1/* THIS IS A SINGLE-FILE DISTRIBUTION CONCATENATED FROM THE OPEN62541 SOURCES
2 * visit http://open62541.org/ for information about this software
3 * Git-Revision: v1.4.13
4 */
5
6/*
7 * Copyright (C) 2014-2021 the contributors as stated in the AUTHORS file
8 *
9 * This file is part of open62541. open62541 is free software: you can
10 * redistribute it and/or modify it under the terms of the Mozilla Public
11 * License v2.0 as stated in the LICENSE file provided with open62541.
12 *
13 * open62541 is distributed in the hope that it will be useful, but WITHOUT ANY
14 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15 * A PARTICULAR PURPOSE.
16 */
17
18#ifndef UA_DYNAMIC_LINKING_EXPORT
19# define UA_DYNAMIC_LINKING_EXPORT
20# define MDNSD_DYNAMIC_LINKING
21#endif
22
23#define UA_INLINABLE_IMPL 1
24
25/* Disable security warnings for BSD sockets on MSVC */
26#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
27# define _CRT_SECURE_NO_WARNINGS
28#endif
29
30#include "open62541.h"
31
32/**** amalgamated original file "/arch/win32/ua_architecture.h" ****/
33
34/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
35 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
36 *
37 * Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB
38 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
39 * Copyright 2021 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati)
40 */
41
42#ifdef UA_ARCHITECTURE_WIN32
43
44#ifndef PLUGINS_ARCH_WIN32_UA_ARCHITECTURE_H_
45#define PLUGINS_ARCH_WIN32_UA_ARCHITECTURE_H_
46
47/* Disable some security warnings on MSVC */
48#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
49# define _CRT_SECURE_NO_WARNINGS
50#endif
51
52
53#include <stdlib.h>
54#include <stdio.h>
55#include <errno.h>
56#include <winsock2.h>
57#include <windows.h>
58#include <ws2tcpip.h>
59#include <basetsd.h>
60
61#ifndef _SSIZE_T_DEFINED
62typedef SSIZE_T ssize_t;
63#endif
64
65#define UA_IPV6 1
66#define UA_SOCKET SOCKET
67#define UA_INVALID_SOCKET INVALID_SOCKET
68#define UA_ERRNO WSAGetLastError()
69#define UA_INTERRUPTED WSAEINTR
70#define UA_AGAIN EAGAIN /* the same as wouldblock on nearly every system */
71#define UA_INPROGRESS WSAEINPROGRESS
72#define UA_WOULDBLOCK WSAEWOULDBLOCK
73#define UA_POLLIN POLLRDNORM
74#define UA_POLLOUT POLLWRNORM
75#define UA_SHUT_RDWR SD_BOTH
76
77#define UA_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) \
78 getnameinfo(sa, (socklen_t)salen, host, (DWORD)hostlen, serv, (DWORD)servlen, flags)
79#define UA_poll(fds,nfds,timeout) WSAPoll((LPWSAPOLLFD)fds, nfds, timeout)
80#define UA_send(sockfd, buf, len, flags) send(sockfd, buf, (int)(len), flags)
81#define UA_recv(sockfd, buf, len, flags) recv(sockfd, buf, (int)(len), flags)
82#define UA_sendto(sockfd, buf, len, flags, dest_addr, addrlen) \
83 sendto(sockfd, (const char*)(buf), (int)(len), flags, dest_addr, (int) (addrlen))
84#define UA_close closesocket
85#define UA_select(nfds, readfds, writefds, exceptfds, timeout) \
86 select((int)(nfds), readfds, writefds, exceptfds, timeout)
87#define UA_connect(sockfd, addr, addrlen) connect(sockfd, addr, (int)(addrlen))
88#define UA_getsockopt(sockfd, level, optname, optval, optlen) \
89 getsockopt(sockfd, level, optname, (char*) (optval), optlen)
90#define UA_setsockopt(sockfd, level, optname, optval, optlen) \
91 setsockopt(sockfd, level, optname, (const char*) (optval), optlen)
92#define UA_inet_pton InetPton
93
94#if UA_IPV6
95# define UA_if_nametoindex if_nametoindex
96
97# include <iphlpapi.h>
98
99#endif
100
101#ifdef maxStringLength //defined in mingw64
102# undef maxStringLength
103#endif
104
105#define UA_LOG_SOCKET_ERRNO_WRAP(LOG) { \
106 char *errno_str = NULL; \
107 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, \
108 NULL, WSAGetLastError(), \
109 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), \
110 (LPSTR)&errno_str, 0, NULL); \
111 LOG; \
112 LocalFree(errno_str); \
113}
114#define UA_LOG_SOCKET_ERRNO_GAI_WRAP UA_LOG_SOCKET_ERRNO_WRAP
115
116/* Fix redefinition of SLIST_ENTRY on mingw winnt.h */
117#if !defined(_SYS_QUEUE_H_) && defined(SLIST_ENTRY)
118# undef SLIST_ENTRY
119#endif
120
121#endif /* PLUGINS_ARCH_WIN32_UA_ARCHITECTURE_H_ */
122
123#endif /* UA_ARCHITECTURE_WIN32 */
124
125/**** amalgamated original file "/arch/posix/ua_architecture.h" ****/
126
127/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
128 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
129 *
130 * Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB
131 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
132 */
133
134#ifdef UA_ARCHITECTURE_POSIX
135
136
137
138#include <errno.h>
139#include <arpa/inet.h>
140#include <netinet/in.h>
141#include <netinet/tcp.h>
142#include <netdb.h>
143#include <sys/ioctl.h>
144#include <sys/select.h>
145#include <net/if.h>
146#include <poll.h>
147#include <fcntl.h>
148#include <unistd.h>
149#include <ifaddrs.h>
150
151#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
152# include <sys/param.h>
153# if defined(BSD)
154# include <sys/socket.h>
155# endif
156#endif
157
158#define UA_IPV6 1
159#define UA_SOCKET int
160#define UA_INVALID_SOCKET -1
161#define UA_ERRNO errno
162#define UA_INTERRUPTED EINTR
163#define UA_AGAIN EAGAIN /* the same as wouldblock on nearly every system */
164#define UA_INPROGRESS EINPROGRESS
165#define UA_WOULDBLOCK EWOULDBLOCK
166#define UA_POLLIN POLLIN
167#define UA_POLLOUT POLLOUT
168#define UA_SHUT_RDWR SHUT_RDWR
169
170#define UA_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) \
171 getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
172#define UA_poll poll
173#define UA_send send
174#define UA_recv recv
175#define UA_sendto sendto
176#define UA_close close
177#define UA_select select
178#define UA_connect connect
179#define UA_getsockopt getsockopt
180#define UA_setsockopt setsockopt
181#define UA_inet_pton inet_pton
182#define UA_if_nametoindex if_nametoindex
183
184#define UA_clean_errno(STR_FUN) (errno == 0 ? (char*) "None" : (STR_FUN)(errno))
185
186#define UA_LOG_SOCKET_ERRNO_WRAP(LOG) { \
187 char *errno_str = UA_clean_errno(strerror); \
188 LOG; \
189 errno = 0; \
190}
191#define UA_LOG_SOCKET_ERRNO_GAI_WRAP(LOG) { \
192 const char *errno_str = UA_clean_errno(gai_strerror); \
193 LOG; \
194 errno = 0; \
195}
196
197#if defined(__APPLE__) && defined(_SYS_QUEUE_H_)
198// in some compilers there's already a _SYS_QUEUE_H_ which is included first and doesn't
199// have all functions
200
201#undef SLIST_HEAD
202#undef SLIST_HEAD_INITIALIZER
203#undef SLIST_ENTRY
204#undef SLIST_FIRST
205#undef SLIST_END
206#undef SLIST_EMPTY
207#undef SLIST_NEXT
208#undef SLIST_FOREACH
209#undef SLIST_FOREACH_SAFE
210#undef SLIST_INIT
211#undef SLIST_INSERT_AFTER
212#undef SLIST_INSERT_HEAD
213#undef SLIST_REMOVE_AFTER
214#undef SLIST_REMOVE_HEAD
215#undef SLIST_REMOVE
216#undef LIST_HEAD
217#undef LIST_HEAD_INITIALIZER
218#undef LIST_ENTRY
219#undef LIST_FIRST
220#undef LIST_END
221#undef LIST_EMPTY
222#undef LIST_NEXT
223#undef LIST_FOREACH
224#undef LIST_FOREACH_SAFE
225#undef LIST_INIT
226#undef LIST_INSERT_AFTER
227#undef LIST_INSERT_BEFORE
228#undef LIST_INSERT_HEAD
229#undef LIST_REMOVE
230#undef LIST_REPLACE
231#undef SIMPLEQ_HEAD
232#undef SIMPLEQ_HEAD_INITIALIZER
233#undef SIMPLEQ_ENTRY
234#undef SIMPLEQ_FIRST
235#undef SIMPLEQ_END
236#undef SIMPLEQ_EMPTY
237#undef SIMPLEQ_NEXT
238#undef SIMPLEQ_FOREACH
239#undef SIMPLEQ_FOREACH_SAFE
240#undef SIMPLEQ_INIT
241#undef SIMPLEQ_INSERT_HEAD
242#undef SIMPLEQ_INSERT_TAIL
243#undef SIMPLEQ_INSERT_AFTER
244#undef SIMPLEQ_REMOVE_HEAD
245#undef SIMPLEQ_REMOVE_AFTER
246#undef XSIMPLEQ_HEAD
247#undef XSIMPLEQ_ENTRY
248#undef XSIMPLEQ_XOR
249#undef XSIMPLEQ_FIRST
250#undef XSIMPLEQ_END
251#undef XSIMPLEQ_EMPTY
252#undef XSIMPLEQ_NEXT
253#undef XSIMPLEQ_FOREACH
254#undef XSIMPLEQ_FOREACH_SAFE
255#undef XSIMPLEQ_INIT
256#undef XSIMPLEQ_INSERT_HEAD
257#undef XSIMPLEQ_INSERT_TAIL
258#undef XSIMPLEQ_INSERT_AFTER
259#undef XSIMPLEQ_REMOVE_HEAD
260#undef XSIMPLEQ_REMOVE_AFTER
261#undef TAILQ_HEAD
262#undef TAILQ_HEAD_INITIALIZER
263#undef TAILQ_ENTRY
264#undef TAILQ_FIRST
265#undef TAILQ_END
266#undef TAILQ_NEXT
267#undef TAILQ_LAST
268#undef TAILQ_PREV
269#undef TAILQ_EMPTY
270#undef TAILQ_FOREACH
271#undef TAILQ_FOREACH_SAFE
272#undef TAILQ_FOREACH_REVERSE
273#undef TAILQ_FOREACH_REVERSE_SAFE
274#undef TAILQ_INIT
275#undef TAILQ_INSERT_HEAD
276#undef TAILQ_INSERT_TAIL
277#undef TAILQ_INSERT_AFTER
278#undef TAILQ_INSERT_BEFORE
279#undef TAILQ_REMOVE
280#undef TAILQ_REPLACE
281#undef CIRCLEQ_HEAD
282#undef CIRCLEQ_HEAD_INITIALIZER
283#undef CIRCLEQ_ENTRY
284#undef CIRCLEQ_FIRST
285#undef CIRCLEQ_LAST
286#undef CIRCLEQ_END
287#undef CIRCLEQ_NEXT
288#undef CIRCLEQ_PREV
289#undef CIRCLEQ_EMPTY
290#undef CIRCLEQ_FOREACH
291#undef CIRCLEQ_FOREACH_SAFE
292#undef CIRCLEQ_FOREACH_REVERSE
293#undef CIRCLEQ_FOREACH_REVERSE_SAFE
294#undef CIRCLEQ_INIT
295#undef CIRCLEQ_INSERT_AFTER
296#undef CIRCLEQ_INSERT_BEFORE
297#undef CIRCLEQ_INSERT_HEAD
298#undef CIRCLEQ_INSERT_TAIL
299#undef CIRCLEQ_REMOVE
300#undef CIRCLEQ_REPLACE
301
302#undef _SYS_QUEUE_H_
303
304#endif /* defined(__APPLE__) && defined(_SYS_QUEUE_H_) */
305
306
307#endif /* UA_ARCHITECTURE_POSIX */
308
309/**** amalgamated original file "/deps/open62541_queue.h" ****/
310
311/* $OpenBSD: queue.h,v 1.38 2013/07/03 15:05:21 fgsch Exp $ */
312/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
313
314/*
315 * Copyright (c) 1991, 1993
316 * The Regents of the University of California. All rights reserved.
317 *
318 * Redistribution and use in source and binary forms, with or without
319 * modification, are permitted provided that the following conditions
320 * are met:
321 * 1. Redistributions of source code must retain the above copyright
322 * notice, this list of conditions and the following disclaimer.
323 * 2. Redistributions in binary form must reproduce the above copyright
324 * notice, this list of conditions and the following disclaimer in the
325 * documentation and/or other materials provided with the distribution.
326 * 3. Neither the name of the University nor the names of its contributors
327 * may be used to endorse or promote products derived from this software
328 * without specific prior written permission.
329 *
330 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
331 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
332 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
333 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
334 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
335 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
336 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
337 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
338 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
339 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
340 * SUCH DAMAGE.
341 *
342 * @(#)queue.h 8.5 (Berkeley) 8/20/94
343 */
344
345
346/*
347 * This file defines five types of data structures: singly-linked lists,
348 * lists, simple queues, tail queues, and circular queues.
349 *
350 *
351 * A singly-linked list is headed by a single forward pointer. The elements
352 * are singly linked for minimum space and pointer manipulation overhead at
353 * the expense of O(n) removal for arbitrary elements. New elements can be
354 * added to the list after an existing element or at the head of the list.
355 * Elements being removed from the head of the list should use the explicit
356 * macro for this purpose for optimum efficiency. A singly-linked list may
357 * only be traversed in the forward direction. Singly-linked lists are ideal
358 * for applications with large datasets and few or no removals or for
359 * implementing a LIFO queue.
360 *
361 * A list is headed by a single forward pointer (or an array of forward
362 * pointers for a hash table header). The elements are doubly linked
363 * so that an arbitrary element can be removed without a need to
364 * traverse the list. New elements can be added to the list before
365 * or after an existing element or at the head of the list. A list
366 * may only be traversed in the forward direction.
367 *
368 * A simple queue is headed by a pair of pointers, one the head of the
369 * list and the other to the tail of the list. The elements are singly
370 * linked to save space, so elements can only be removed from the
371 * head of the list. New elements can be added to the list before or after
372 * an existing element, at the head of the list, or at the end of the
373 * list. A simple queue may only be traversed in the forward direction.
374 *
375 * A tail queue is headed by a pair of pointers, one to the head of the
376 * list and the other to the tail of the list. The elements are doubly
377 * linked so that an arbitrary element can be removed without a need to
378 * traverse the list. New elements can be added to the list before or
379 * after an existing element, at the head of the list, or at the end of
380 * the list. A tail queue may be traversed in either direction.
381 *
382 * A circle queue is headed by a pair of pointers, one to the head of the
383 * list and the other to the tail of the list. The elements are doubly
384 * linked so that an arbitrary element can be removed without a need to
385 * traverse the list. New elements can be added to the list before or after
386 * an existing element, at the head of the list, or at the end of the list.
387 * A circle queue may be traversed in either direction, but has a more
388 * complex end of list detection.
389 *
390 * For details on the use of these macros, see the queue(3) manual page.
391 */
392
393#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
394#define _Q_INVALIDATE(a) (a) = ((void *)-1)
395#else
396#define _Q_INVALIDATE(a)
397#endif
398
399/*
400 * Singly-linked List definitions.
401 */
402#define SLIST_HEAD(name, type) \
403struct name { \
404 struct type *slh_first; /* first element */ \
405}
406
407#define SLIST_HEAD_INITIALIZER(head) \
408 { NULL }
409
410#define SLIST_ENTRY(type) \
411struct { \
412 struct type *sle_next; /* next element */ \
413}
414
415/*
416 * Singly-linked List access methods.
417 */
418#define SLIST_FIRST(head) ((head)->slh_first)
419#define SLIST_END(head) NULL
420#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
421#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
422
423#define SLIST_FOREACH(var, head, field) \
424 for((var) = SLIST_FIRST(head); \
425 (var) != SLIST_END(head); \
426 (var) = SLIST_NEXT(var, field))
427
428#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
429 for ((var) = SLIST_FIRST(head); \
430 (var) && ((tvar) = SLIST_NEXT(var, field), 1); \
431 (var) = (tvar))
432
433/*
434 * Singly-linked List functions.
435 */
436#define SLIST_INIT(head) do { \
437 SLIST_FIRST(head) = SLIST_END(head); \
438} while(0)
439
440#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
441 (elm)->field.sle_next = (slistelm)->field.sle_next; \
442 (slistelm)->field.sle_next = (elm); \
443} while (0)
444
445#define SLIST_INSERT_HEAD(head, elm, field) do { \
446 (elm)->field.sle_next = (head)->slh_first; \
447 (head)->slh_first = (elm); \
448} while (0)
449
450#define SLIST_REMOVE_AFTER(elm, field) do { \
451 (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
452} while (0)
453
454#define SLIST_REMOVE_HEAD(head, field) do { \
455 (head)->slh_first = (head)->slh_first->field.sle_next; \
456} while (0)
457
458#define SLIST_REMOVE(head, elm, type, field) do { \
459 if ((head)->slh_first == (elm)) { \
460 SLIST_REMOVE_HEAD((head), field); \
461 } else { \
462 struct type *curelm = (head)->slh_first; \
463 \
464 while (curelm->field.sle_next != (elm)) \
465 curelm = curelm->field.sle_next; \
466 curelm->field.sle_next = \
467 curelm->field.sle_next->field.sle_next; \
468 _Q_INVALIDATE((elm)->field.sle_next); \
469 } \
470} while (0)
471
472/*
473 * List definitions.
474 */
475#define LIST_HEAD(name, type) \
476struct name { \
477 struct type *lh_first; /* first element */ \
478}
479
480#define LIST_HEAD_INITIALIZER(head) \
481 { NULL }
482
483#define LIST_ENTRY(type) \
484struct { \
485 struct type *le_next; /* next element */ \
486 struct type **le_prev; /* address of previous next element */ \
487}
488
489/*
490 * List access methods
491 */
492#define LIST_FIRST(head) ((head)->lh_first)
493#define LIST_END(head) NULL
494#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
495#define LIST_NEXT(elm, field) ((elm)->field.le_next)
496
497#define LIST_FOREACH(var, head, field) \
498 for((var) = LIST_FIRST(head); \
499 (var)!= LIST_END(head); \
500 (var) = LIST_NEXT(var, field))
501
502#define LIST_FOREACH_SAFE(var, head, field, tvar) \
503 for ((var) = LIST_FIRST(head); \
504 (var) && ((tvar) = LIST_NEXT(var, field), 1); \
505 (var) = (tvar))
506
507/*
508 * List functions.
509 */
510#define LIST_INIT(head) do { \
511 LIST_FIRST(head) = LIST_END(head); \
512} while (0)
513
514#define LIST_INSERT_AFTER(listelm, elm, field) do { \
515 if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
516 (listelm)->field.le_next->field.le_prev = \
517 &(elm)->field.le_next; \
518 (listelm)->field.le_next = (elm); \
519 (elm)->field.le_prev = &(listelm)->field.le_next; \
520} while (0)
521
522#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
523 (elm)->field.le_prev = (listelm)->field.le_prev; \
524 (elm)->field.le_next = (listelm); \
525 *(listelm)->field.le_prev = (elm); \
526 (listelm)->field.le_prev = &(elm)->field.le_next; \
527} while (0)
528
529#define LIST_INSERT_HEAD(head, elm, field) do { \
530 if (((elm)->field.le_next = (head)->lh_first) != NULL) \
531 (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
532 (head)->lh_first = (elm); \
533 (elm)->field.le_prev = &(head)->lh_first; \
534} while (0)
535
536#define LIST_REMOVE(elm, field) do { \
537 if ((elm)->field.le_next != NULL) \
538 (elm)->field.le_next->field.le_prev = \
539 (elm)->field.le_prev; \
540 *(elm)->field.le_prev = (elm)->field.le_next; \
541 _Q_INVALIDATE((elm)->field.le_prev); \
542 _Q_INVALIDATE((elm)->field.le_next); \
543} while (0)
544
545#define LIST_REPLACE(elm, elm2, field) do { \
546 if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
547 (elm2)->field.le_next->field.le_prev = \
548 &(elm2)->field.le_next; \
549 (elm2)->field.le_prev = (elm)->field.le_prev; \
550 *(elm2)->field.le_prev = (elm2); \
551 _Q_INVALIDATE((elm)->field.le_prev); \
552 _Q_INVALIDATE((elm)->field.le_next); \
553} while (0)
554
555/*
556 * Simple queue definitions.
557 */
558#define SIMPLEQ_HEAD(name, type) \
559struct name { \
560 struct type *sqh_first; /* first element */ \
561 struct type **sqh_last; /* addr of last next element */ \
562}
563
564#define SIMPLEQ_HEAD_INITIALIZER(head) \
565 { NULL, &(head).sqh_first }
566
567#define SIMPLEQ_ENTRY(type) \
568struct { \
569 struct type *sqe_next; /* next element */ \
570}
571
572/*
573 * Simple queue access methods.
574 */
575#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
576#define SIMPLEQ_END(head) NULL
577#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
578#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
579
580#define SIMPLEQ_FOREACH(var, head, field) \
581 for((var) = SIMPLEQ_FIRST(head); \
582 (var) != SIMPLEQ_END(head); \
583 (var) = SIMPLEQ_NEXT(var, field))
584
585#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
586 for ((var) = SIMPLEQ_FIRST(head); \
587 (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \
588 (var) = (tvar))
589
590/*
591 * Simple queue functions.
592 */
593#define SIMPLEQ_INIT(head) do { \
594 (head)->sqh_first = NULL; \
595 (head)->sqh_last = &(head)->sqh_first; \
596} while (0)
597
598#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
599 if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
600 (head)->sqh_last = &(elm)->field.sqe_next; \
601 (head)->sqh_first = (elm); \
602} while (0)
603
604#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
605 (elm)->field.sqe_next = NULL; \
606 *(head)->sqh_last = (elm); \
607 (head)->sqh_last = &(elm)->field.sqe_next; \
608} while (0)
609
610#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
611 if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
612 (head)->sqh_last = &(elm)->field.sqe_next; \
613 (listelm)->field.sqe_next = (elm); \
614} while (0)
615
616#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
617 if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
618 (head)->sqh_last = &(head)->sqh_first; \
619} while (0)
620
621#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
622 if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
623 == NULL) \
624 (head)->sqh_last = &(elm)->field.sqe_next; \
625} while (0)
626
627/*
628 * XOR Simple queue definitions.
629 */
630#define XSIMPLEQ_HEAD(name, type) \
631struct name { \
632 struct type *sqx_first; /* first element */ \
633 struct type **sqx_last; /* addr of last next element */ \
634 unsigned long sqx_cookie; \
635}
636
637#define XSIMPLEQ_ENTRY(type) \
638struct { \
639 struct type *sqx_next; /* next element */ \
640}
641
642/*
643 * XOR Simple queue access methods.
644 */
645#define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \
646 (unsigned long)(ptr)))
647#define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first))
648#define XSIMPLEQ_END(head) NULL
649#define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
650#define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
651
652
653#define XSIMPLEQ_FOREACH(var, head, field) \
654 for ((var) = XSIMPLEQ_FIRST(head); \
655 (var) != XSIMPLEQ_END(head); \
656 (var) = XSIMPLEQ_NEXT(head, var, field))
657
658#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
659 for ((var) = XSIMPLEQ_FIRST(head); \
660 (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
661 (var) = (tvar))
662
663/*
664 * XOR Simple queue functions.
665 */
666#define XSIMPLEQ_INIT(head) do { \
667 arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
668 (head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \
669 (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
670} while (0)
671
672#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \
673 if (((elm)->field.sqx_next = (head)->sqx_first) == \
674 XSIMPLEQ_XOR(head, NULL)) \
675 (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
676 (head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \
677} while (0)
678
679#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \
680 (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \
681 *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
682 (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
683} while (0)
684
685#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
686 if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \
687 XSIMPLEQ_XOR(head, NULL)) \
688 (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
689 (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \
690} while (0)
691
692#define XSIMPLEQ_REMOVE_HEAD(head, field) do { \
693 if (((head)->sqx_first = XSIMPLEQ_XOR(head, \
694 (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
695 (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
696} while (0)
697
698#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
699 if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \
700 (elm)->field.sqx_next)->field.sqx_next) \
701 == XSIMPLEQ_XOR(head, NULL)) \
702 (head)->sqx_last = \
703 XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
704} while (0)
705
706
707/*
708 * Tail queue definitions.
709 */
710#define TAILQ_HEAD(name, type) \
711struct name { \
712 struct type *tqh_first; /* first element */ \
713 struct type **tqh_last; /* addr of last next element */ \
714}
715
716#define TAILQ_HEAD_INITIALIZER(head) \
717 { NULL, &(head).tqh_first }
718
719#define TAILQ_ENTRY(type) \
720struct { \
721 struct type *tqe_next; /* next element */ \
722 struct type **tqe_prev; /* address of previous next element */ \
723}
724
725/*
726 * tail queue access methods
727 */
728#define TAILQ_FIRST(head) ((head)->tqh_first)
729#define TAILQ_END(head) NULL
730#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
731#define TAILQ_LAST(head, headname) \
732 (*(((struct headname *)((head)->tqh_last))->tqh_last))
733/* XXX */
734#define TAILQ_PREV(elm, headname, field) \
735 (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
736#define TAILQ_EMPTY(head) \
737 (TAILQ_FIRST(head) == TAILQ_END(head))
738
739#define TAILQ_FOREACH(var, head, field) \
740 for((var) = TAILQ_FIRST(head); \
741 (var) != TAILQ_END(head); \
742 (var) = TAILQ_NEXT(var, field))
743
744#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
745 for ((var) = TAILQ_FIRST(head); \
746 (var) != TAILQ_END(head) && \
747 ((tvar) = TAILQ_NEXT(var, field), 1); \
748 (var) = (tvar))
749
750
751#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
752 for((var) = TAILQ_LAST(head, headname); \
753 (var) != TAILQ_END(head); \
754 (var) = TAILQ_PREV(var, headname, field))
755
756#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
757 for ((var) = TAILQ_LAST(head, headname); \
758 (var) != TAILQ_END(head) && \
759 ((tvar) = TAILQ_PREV(var, headname, field), 1); \
760 (var) = (tvar))
761
762/*
763 * Tail queue functions.
764 */
765#define TAILQ_INIT(head) do { \
766 (head)->tqh_first = NULL; \
767 (head)->tqh_last = &(head)->tqh_first; \
768} while (0)
769
770#define TAILQ_INSERT_HEAD(head, elm, field) do { \
771 if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
772 (head)->tqh_first->field.tqe_prev = \
773 &(elm)->field.tqe_next; \
774 else \
775 (head)->tqh_last = &(elm)->field.tqe_next; \
776 (head)->tqh_first = (elm); \
777 (elm)->field.tqe_prev = &(head)->tqh_first; \
778} while (0)
779
780#define TAILQ_INSERT_TAIL(head, elm, field) do { \
781 (elm)->field.tqe_next = NULL; \
782 (elm)->field.tqe_prev = (head)->tqh_last; \
783 *(head)->tqh_last = (elm); \
784 (head)->tqh_last = &(elm)->field.tqe_next; \
785} while (0)
786
787#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
788 if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
789 (elm)->field.tqe_next->field.tqe_prev = \
790 &(elm)->field.tqe_next; \
791 else \
792 (head)->tqh_last = &(elm)->field.tqe_next; \
793 (listelm)->field.tqe_next = (elm); \
794 (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
795} while (0)
796
797#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
798 (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
799 (elm)->field.tqe_next = (listelm); \
800 *(listelm)->field.tqe_prev = (elm); \
801 (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
802} while (0)
803
804#define TAILQ_REMOVE(head, elm, field) do { \
805 if (((elm)->field.tqe_next) != NULL) \
806 (elm)->field.tqe_next->field.tqe_prev = \
807 (elm)->field.tqe_prev; \
808 else \
809 (head)->tqh_last = (elm)->field.tqe_prev; \
810 *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
811 _Q_INVALIDATE((elm)->field.tqe_prev); \
812 _Q_INVALIDATE((elm)->field.tqe_next); \
813} while (0)
814
815#define TAILQ_REPLACE(head, elm, elm2, field) do { \
816 if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
817 (elm2)->field.tqe_next->field.tqe_prev = \
818 &(elm2)->field.tqe_next; \
819 else \
820 (head)->tqh_last = &(elm2)->field.tqe_next; \
821 (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
822 *(elm2)->field.tqe_prev = (elm2); \
823 _Q_INVALIDATE((elm)->field.tqe_prev); \
824 _Q_INVALIDATE((elm)->field.tqe_next); \
825} while (0)
826
827/*
828 * Circular queue definitions.
829 */
830#define CIRCLEQ_HEAD(name, type) \
831struct name { \
832 struct type *cqh_first; /* first element */ \
833 struct type *cqh_last; /* last element */ \
834}
835
836#define CIRCLEQ_HEAD_INITIALIZER(head) \
837 { CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
838
839#define CIRCLEQ_ENTRY(type) \
840struct { \
841 struct type *cqe_next; /* next element */ \
842 struct type *cqe_prev; /* previous element */ \
843}
844
845/*
846 * Circular queue access methods
847 */
848#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
849#define CIRCLEQ_LAST(head) ((head)->cqh_last)
850#define CIRCLEQ_END(head) ((void *)(head))
851#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
852#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
853#define CIRCLEQ_EMPTY(head) \
854 (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
855
856#define CIRCLEQ_FOREACH(var, head, field) \
857 for((var) = CIRCLEQ_FIRST(head); \
858 (var) != CIRCLEQ_END(head); \
859 (var) = CIRCLEQ_NEXT(var, field))
860
861#define CIRCLEQ_FOREACH_SAFE(var, head, field, tvar) \
862 for ((var) = CIRCLEQ_FIRST(head); \
863 (var) != CIRCLEQ_END(head) && \
864 ((tvar) = CIRCLEQ_NEXT(var, field), 1); \
865 (var) = (tvar))
866
867#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
868 for((var) = CIRCLEQ_LAST(head); \
869 (var) != CIRCLEQ_END(head); \
870 (var) = CIRCLEQ_PREV(var, field))
871
872#define CIRCLEQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
873 for ((var) = CIRCLEQ_LAST(head, headname); \
874 (var) != CIRCLEQ_END(head) && \
875 ((tvar) = CIRCLEQ_PREV(var, headname, field), 1); \
876 (var) = (tvar))
877
878/*
879 * Circular queue functions.
880 */
881#define CIRCLEQ_INIT(head) do { \
882 (head)->cqh_first = CIRCLEQ_END(head); \
883 (head)->cqh_last = CIRCLEQ_END(head); \
884} while (0)
885
886#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
887 (elm)->field.cqe_next = (listelm)->field.cqe_next; \
888 (elm)->field.cqe_prev = (listelm); \
889 if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
890 (head)->cqh_last = (elm); \
891 else \
892 (listelm)->field.cqe_next->field.cqe_prev = (elm); \
893 (listelm)->field.cqe_next = (elm); \
894} while (0)
895
896#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
897 (elm)->field.cqe_next = (listelm); \
898 (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
899 if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
900 (head)->cqh_first = (elm); \
901 else \
902 (listelm)->field.cqe_prev->field.cqe_next = (elm); \
903 (listelm)->field.cqe_prev = (elm); \
904} while (0)
905
906#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
907 (elm)->field.cqe_next = (head)->cqh_first; \
908 (elm)->field.cqe_prev = CIRCLEQ_END(head); \
909 if ((head)->cqh_last == CIRCLEQ_END(head)) \
910 (head)->cqh_last = (elm); \
911 else \
912 (head)->cqh_first->field.cqe_prev = (elm); \
913 (head)->cqh_first = (elm); \
914} while (0)
915
916#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
917 (elm)->field.cqe_next = CIRCLEQ_END(head); \
918 (elm)->field.cqe_prev = (head)->cqh_last; \
919 if ((head)->cqh_first == CIRCLEQ_END(head)) \
920 (head)->cqh_first = (elm); \
921 else \
922 (head)->cqh_last->field.cqe_next = (elm); \
923 (head)->cqh_last = (elm); \
924} while (0)
925
926#define CIRCLEQ_REMOVE(head, elm, field) do { \
927 if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
928 (head)->cqh_last = (elm)->field.cqe_prev; \
929 else \
930 (elm)->field.cqe_next->field.cqe_prev = \
931 (elm)->field.cqe_prev; \
932 if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
933 (head)->cqh_first = (elm)->field.cqe_next; \
934 else \
935 (elm)->field.cqe_prev->field.cqe_next = \
936 (elm)->field.cqe_next; \
937 _Q_INVALIDATE((elm)->field.cqe_prev); \
938 _Q_INVALIDATE((elm)->field.cqe_next); \
939} while (0)
940
941#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
942 if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
943 CIRCLEQ_END(head)) \
944 (head)->cqh_last = (elm2); \
945 else \
946 (elm2)->field.cqe_next->field.cqe_prev = (elm2); \
947 if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
948 CIRCLEQ_END(head)) \
949 (head)->cqh_first = (elm2); \
950 else \
951 (elm2)->field.cqe_prev->field.cqe_next = (elm2); \
952 _Q_INVALIDATE((elm)->field.cqe_prev); \
953 _Q_INVALIDATE((elm)->field.cqe_next); \
954} while (0)
955
956
957/**** amalgamated original file "/deps/pcg_basic.h" ****/
958
959/*
960 * PCG Random Number Generation for C.
961 *
962 * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
963 *
964 * Licensed under the Apache License, Version 2.0 (the "License");
965 * you may not use this file except in compliance with the License.
966 * You may obtain a copy of the License at
967 *
968 * http://www.apache.org/licenses/LICENSE-2.0
969 *
970 * Unless required by applicable law or agreed to in writing, software
971 * distributed under the License is distributed on an "AS IS" BASIS,
972 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
973 * See the License for the specific language governing permissions and
974 * limitations under the License.
975 *
976 * For additional information about the PCG random number generation scheme,
977 * including its license and other licensing options, visit
978 *
979 * http://www.pcg-random.org
980 */
981
982
983#if defined(UNDER_CE) || !defined(_MSC_VER) || _MSC_VER >= 1800
984# include <stdint.h>
985#else
986#endif
987
988#ifdef __cplusplus
989extern "C" {
990#endif
991
992typedef struct pcg_state_setseq_64 {
993 uint64_t state; /* RNG state. All values are possible. */
994 uint64_t inc; /* Controls which RNG sequence (stream) is selected. Must
995 * *always* be odd. */
996} pcg32_random_t;
997
998#define PCG32_INITIALIZER { 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL }
999
1000void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initial_state, uint64_t initseq);
1001uint32_t pcg32_random_r(pcg32_random_t* rng);
1002
1003#ifdef __cplusplus
1004}
1005#endif
1006
1007
1008/**** amalgamated original file "/deps/libc_time.h" ****/
1009
1010
1011struct musl_tm {
1012 int tm_sec;
1013 int tm_min;
1014 int tm_hour;
1015 int tm_mday;
1016 int tm_mon;
1017 int tm_year;
1018 int tm_wday;
1019 int tm_yday;
1020 /* int tm_isdst; */
1021 /* long __tm_gmtoff; */
1022 /* const char *__tm_zone; */
1023};
1024
1025int musl_secs_to_tm(long long t, struct musl_tm *tm);
1026long long musl_tm_to_secs(const struct musl_tm *tm);
1027
1028
1029/**** amalgamated original file "/deps/base64.h" ****/
1030
1031#ifndef UA_BASE64_H_
1032#define UA_BASE64_H_
1033
1034
1035_UA_BEGIN_DECLS
1036
1037#include <stddef.h>
1038
1039/**
1040 * base64_encode - Base64 encode
1041 * @src: Data to be encoded
1042 * @len: Length of the data to be encoded
1043 * @out_len: Pointer to output length variable
1044 * Returns: Allocated buffer of out_len bytes of encoded data,
1045 * or %NULL on failure. The output is NOT Null-terminated. */
1046unsigned char *
1047UA_base64(const unsigned char *src, size_t len, size_t *out_len);
1048
1049/* Requires as input a buffer of length at least 4*((len + 2) / 3).
1050 * Returns the actual size */
1051size_t
1052UA_base64_buf(const unsigned char *src, size_t len, unsigned char *out);
1053
1054/**
1055 * base64_decode - Base64 decode
1056 * @src: Data to be decoded
1057 * @len: Length of the data to be decoded
1058 * @out_len: Pointer to output length variable
1059 * Returns: Allocated buffer of out_len bytes of decoded data,
1060 * or %NULL on failure. */
1061unsigned char *
1062UA_unbase64(const unsigned char *src, size_t len, size_t *out_len);
1063
1064_UA_END_DECLS
1065
1066#endif /* UA_BASE64_H_ */
1067
1068/**** amalgamated original file "/deps/dtoa.h" ****/
1069
1070// Copyright 2013, Andreas Samoljuk
1071// Copyright 2023, Julius Pfrommer
1072//
1073// Boost Software License - Version 1.0 - August 17th, 2003
1074//
1075// Permission is hereby granted, free of charge, to any person or organization
1076// obtaining a copy of the software and accompanying documentation covered by
1077// this license (the "Software") to use, reproduce, display, distribute,
1078// execute, and transmit the Software, and to prepare derivative works of the
1079// Software, and to permit third-parties to whom the Software is furnished to
1080// do so, all subject to the following:
1081//
1082// The copyright notices in the Software and this entire statement, including
1083// the above license grant, this restriction and the following disclaimer,
1084// must be included in all copies of the Software, in whole or in part, and
1085// all derivative works of the Software, unless such copies or derivative
1086// works are solely in the form of machine-executable object code generated by
1087// a source language processor.
1088//
1089// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1090// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1091// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
1092// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
1093// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
1094// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1095// DEALINGS IN THE SOFTWARE.
1096
1097#ifndef DTOA_H
1098#define DTOA_H
1099
1100#ifdef __cplusplus
1101extern "C" {
1102#endif
1103
1104// Prints a double-value as a readable string. The buffer must be at least 24
1105// chars wide. Returns the number of printed characters. Does not
1106// null-terminate.
1107unsigned dtoa(double d, char* buffer);
1108
1109#ifdef __cplusplus
1110}
1111#endif
1112
1113#endif // DTOA_H
1114
1115/**** amalgamated original file "/deps/mp_printf.h" ****/
1116
1117/**
1118 * @author (c) Eyal Rozenberg <eyalroz1@gmx.com>
1119 * 2021-2023, Haifa, Palestine/Israel
1120 * @author (c) Marco Paland (info@paland.com)
1121 * 2014-2019, PALANDesign Hannover, Germany
1122 *
1123 * @note Others have made smaller contributions to this file: see the
1124 * contributors page at https://github.com/eyalroz/printf/graphs/contributors
1125 * or ask one of the authors.
1126 *
1127 * @brief Small stand-alone implementation of the printf family of functions
1128 * (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems with
1129 * a very limited resources.
1130 *
1131 * @note the implementations are thread-safe; re-entrant; use no functions from
1132 * the standard library; and do not dynamically allocate any memory.
1133 *
1134 * @license The MIT License (MIT)
1135 *
1136 * Permission is hereby granted, free of charge, to any person obtaining a copy
1137 * of this software and associated documentation files (the "Software"), to deal
1138 * in the Software without restriction, including without limitation the rights
1139 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1140 * copies of the Software, and to permit persons to whom the Software is
1141 * furnished to do so, subject to the following conditions:
1142 *
1143 * The above copyright notice and this permission notice shall be included in
1144 * all copies or substantial portions of the Software.
1145 *
1146 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1147 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1148 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1149 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1150 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1151 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1152 * THE SOFTWARE.
1153 */
1154
1155#ifndef MP_PRINTF_H
1156#define MP_PRINTF_H
1157
1158#include <stdarg.h>
1159#include <stddef.h>
1160
1161#ifdef __cplusplus
1162extern "C" {
1163#endif
1164
1165#ifdef __GNUC__
1166# if ((__GNUC__ == 4 && __GNUC_MINOR__>= 4) || __GNUC__ > 4)
1167# define ATTR_PRINTF(one_based_format_index, first_arg) \
1168__attribute__((format(gnu_printf, (one_based_format_index), (first_arg))))
1169# else
1170# define ATTR_PRINTF(one_based_format_index, first_arg) \
1171__attribute__((format(printf, (one_based_format_index), (first_arg))))
1172# endif
1173# define ATTR_VPRINTF(one_based_format_index) ATTR_PRINTF((one_based_format_index), 0)
1174#else
1175# define ATTR_PRINTF(one_based_format_index, first_arg)
1176# define ATTR_VPRINTF(one_based_format_index)
1177#endif
1178
1179/**
1180 * An implementation of the C standard's snprintf/vsnprintf
1181 *
1182 * @param s An array in which to store the formatted string. It must be large
1183 * enough to fit either the entire formatted output, or at least @p n
1184 * characters. Alternatively, it can be NULL, in which case nothing will be
1185 * printed, and only the number of characters which _could_ have been printed is
1186 * tallied and returned.
1187 * @param n The maximum number of characters to write to the array, including a
1188 * terminating null character
1189 * @param format A string specifying the format of the output, with %-marked
1190 * specifiers of how to interpret additional arguments.
1191 * @param arg Additional arguments to the function, one for each specifier in @p
1192 * format
1193 * @return The number of characters that COULD have been written into @p s, not
1194 * counting the terminating null character. A value equal or larger than @p n
1195 * indicates truncation. Only when the returned value is non-negative and less
1196 * than @p n, the null-terminated string has been fully and successfully
1197 * printed.
1198 */
1199int mp_snprintf(char* s, size_t count, const char* format, ...) ATTR_PRINTF(3, 4);
1200int mp_vsnprintf(char* s, size_t count, const char* format, va_list arg) ATTR_VPRINTF(3);
1201
1202#ifdef __cplusplus
1203} // extern "C"
1204#endif
1205
1206#endif // MP_PRINTF_H
1207
1208/**** amalgamated original file "/deps/itoa.h" ****/
1209
1210/*
1211 * Copyright 2017 Techie Delight
1212 * Permission is hereby granted, free of charge, to any person obtaining a copy
1213 * of this software and associated documentation files (the "Software"), to deal
1214 * in the Software without restriction, including without limitation the rights
1215 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1216 * copies of the Software, and to permit persons to whom the Software is
1217 * furnished to do so, subject to the following conditions:
1218 *
1219 * The above copyright notice and this permission notice shall be included
1220 * in all copies or substantial portions of the Software.
1221 *
1222 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1223 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1224 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1225 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1226 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
1227 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1228 */
1229
1230#ifndef ITOA_H
1231#define ITOA_H
1232
1233#ifdef __cplusplus
1234extern "C" {
1235#endif
1236
1237
1238UA_UInt16 itoaUnsigned(UA_UInt64 value, char* buffer, UA_Byte base);
1239UA_UInt16 itoaSigned(UA_Int64 value, char* buffer);
1240
1241#ifdef __cplusplus
1242}
1243#endif
1244
1245#endif /* ITOA_H */
1246
1247
1248/**** amalgamated original file "/deps/ziptree.h" ****/
1249
1250/* This Source Code Form is subject to the terms of the Mozilla Public
1251 * License, v. 2.0. If a copy of the MPL was not distributed with this
1252 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
1253 *
1254 * Copyright 2018, 2021-2022 (c) Julius Pfrommer
1255 */
1256
1257
1258#include <stddef.h>
1259
1260#ifdef _MSC_VER
1261# define ZIP_INLINE __inline
1262#else
1263# define ZIP_INLINE inline
1264#endif
1265
1266#if defined(__GNUC__) || defined(__clang__)
1267# define ZIP_UNUSED __attribute__((unused))
1268#else
1269# define ZIP_UNUSED
1270#endif
1271
1272#ifdef __cplusplus
1273extern "C" {
1274#endif
1275
1276/* Reusable zip tree implementation. The style is inspired by the BSD
1277 * sys/queue.h linked list definition.
1278 *
1279 * Zip trees were developed in: Tarjan, R. E., Levy, C. C., and Timmel, S. "Zip
1280 * Trees." arXiv preprint arXiv:1806.06726 (2018). The original definition was
1281 * modified in two ways:
1282 *
1283 * - Multiple elements with the same key can be inserted. These appear adjacent
1284 * in the tree. ZIP_FIND will return the topmost of these elements.
1285 * - The pointer-value of the elements are used as the rank. This simplifies the
1286 * code and is (empirically) faster.
1287 *
1288 * The ZIP_ENTRY definitions are to be contained in the tree entries themselves.
1289 * Use ZIP_FUNCTIONS to define the signature of the zip tree functions. */
1290
1291#define ZIP_HEAD(name, type) \
1292struct name { \
1293 struct type *root; \
1294}
1295
1296#define ZIP_ENTRY(type) \
1297struct { \
1298 struct type *left; \
1299 struct type *right; \
1300}
1301
1302enum ZIP_CMP {
1303 ZIP_CMP_LESS = -1,
1304 ZIP_CMP_EQ = 0,
1305 ZIP_CMP_MORE = 1
1306};
1307
1308/* The comparison method "cmp" for a zip tree has the signature.
1309 * Provide this to the ZIP_FUNCTIONS macro.
1310 *
1311 * enum ZIP_CMP cmpMethod(const keytype *a, const keytype *b);
1312 */
1313typedef enum ZIP_CMP (*zip_cmp_cb)(const void *key1, const void *key2);
1314
1315#define ZIP_INIT(head) do { (head)->root = NULL; } while (0)
1316#define ZIP_ROOT(head) (head)->root
1317#define ZIP_LEFT(elm, field) (elm)->field.left
1318#define ZIP_RIGHT(elm, field) (elm)->field.right
1319#define ZIP_INSERT(name, head, elm) name##_ZIP_INSERT(head, elm)
1320#define ZIP_FIND(name, head, key) name##_ZIP_FIND(head, key)
1321#define ZIP_MIN(name, head) name##_ZIP_MIN(head)
1322#define ZIP_MAX(name, head) name##_ZIP_MAX(head)
1323
1324/* Returns the element if it was found in the tree. Returns NULL otherwise. */
1325#define ZIP_REMOVE(name, head, elm) name##_ZIP_REMOVE(head, elm)
1326
1327/* Split (_UNZIP) and merge (_ZIP) trees. _UNZIP splits at the key and moves
1328 * elements <= into the left output (right otherwise). */
1329#define ZIP_ZIP(name, left, right) name##_ZIP_ZIP(left, right)
1330#define ZIP_UNZIP(name, head, key, left, right) \
1331 name##_ZIP_UNZIP(head, key, left, right)
1332
1333/* ZIP_ITER uses in-order traversal of the tree (in the order of the keys). The
1334 * memory if a node is not accessed by ZIP_ITER after the callback has been
1335 * executed for it. So a tree can be cleaned by calling free on each node from
1336 * within the iteration callback.
1337 *
1338 * ZIP_ITER returns a void pointer. The first callback to return non-NULL aborts
1339 * the iteration. This pointer is then returned. */
1340typedef void * (*zip_iter_cb)(void *context, void *elm);
1341#define ZIP_ITER(name, head, cb, ctx) name##_ZIP_ITER(head, cb, ctx)
1342
1343/* Same as _ITER, but only visits elements with the given key */
1344#define ZIP_ITER_KEY(name, head, key, cb, ctx) name##_ZIP_ITER_KEY(head, key, cb, ctx)
1345
1346/* Macro to generate typed ziptree methods */
1347#define ZIP_FUNCTIONS(name, type, field, keytype, keyfield, cmp) \
1348 \
1349ZIP_UNUSED static ZIP_INLINE void \
1350name##_ZIP_INSERT(struct name *head, struct type *el) { \
1351 __ZIP_INSERT(head, (zip_cmp_cb)cmp, offsetof(struct type, field), \
1352 offsetof(struct type, keyfield), el); \
1353} \
1354 \
1355ZIP_UNUSED static ZIP_INLINE struct type * \
1356name##_ZIP_REMOVE(struct name *head, struct type *elm) { \
1357 return (struct type*) \
1358 __ZIP_REMOVE(head, (zip_cmp_cb)cmp, \
1359 offsetof(struct type, field), \
1360 offsetof(struct type, keyfield), elm); \
1361} \
1362 \
1363ZIP_UNUSED static ZIP_INLINE struct type * \
1364name##_ZIP_FIND(struct name *head, const keytype *key) { \
1365 struct type *cur = ZIP_ROOT(head); \
1366 while(cur) { \
1367 enum ZIP_CMP eq = cmp(key, &cur->keyfield); \
1368 if(eq == ZIP_CMP_EQ) \
1369 break; \
1370 if(eq == ZIP_CMP_LESS) \
1371 cur = ZIP_LEFT(cur, field); \
1372 else \
1373 cur = ZIP_RIGHT(cur, field); \
1374 } \
1375 return cur; \
1376} \
1377 \
1378ZIP_UNUSED static ZIP_INLINE struct type * \
1379name##_ZIP_MIN(struct name *head) { \
1380 struct type *cur = ZIP_ROOT(head); \
1381 if(!cur) \
1382 return NULL; \
1383 while(ZIP_LEFT(cur, field)) { \
1384 cur = ZIP_LEFT(cur, field); \
1385 } \
1386 return cur; \
1387} \
1388 \
1389ZIP_UNUSED static ZIP_INLINE struct type * \
1390name##_ZIP_MAX(struct name *head) { \
1391 struct type *cur = ZIP_ROOT(head); \
1392 if(!cur) \
1393 return NULL; \
1394 while(ZIP_RIGHT(cur, field)) { \
1395 cur = ZIP_RIGHT(cur, field); \
1396 } \
1397 return cur; \
1398} \
1399 \
1400typedef void * (*name##_cb)(void *context, struct type *elm); \
1401 \
1402ZIP_UNUSED static ZIP_INLINE void * \
1403name##_ZIP_ITER(struct name *head, name##_cb cb, void *context) { \
1404 return __ZIP_ITER(offsetof(struct type, field), (zip_iter_cb)cb, \
1405 context, ZIP_ROOT(head)); \
1406} \
1407 \
1408ZIP_UNUSED static ZIP_INLINE void * \
1409name##_ZIP_ITER_KEY(struct name *head, const keytype *key, \
1410 name##_cb cb, void *context) { \
1411 return __ZIP_ITER_KEY((zip_cmp_cb)cmp, offsetof(struct type, field), \
1412 offsetof(struct type, keyfield), key, \
1413 (zip_iter_cb)cb, context, ZIP_ROOT(head)); \
1414} \
1415 \
1416ZIP_UNUSED static ZIP_INLINE struct type * \
1417name##_ZIP_ZIP(struct type *left, struct type *right) { \
1418 return (struct type*) \
1419 __ZIP_ZIP(offsetof(struct type, field), left, right); \
1420} \
1421 \
1422ZIP_UNUSED static ZIP_INLINE void \
1423name##_ZIP_UNZIP(struct name *head, const keytype *key, \
1424 struct name *left, struct name *right) { \
1425 __ZIP_UNZIP((zip_cmp_cb)cmp, offsetof(struct type, field), \
1426 offsetof(struct type, keyfield), key, \
1427 head, left, right); \
1428}
1429
1430/* Internal definitions. Don't use directly. */
1431
1432void
1433__ZIP_INSERT(void *h, zip_cmp_cb cmp, unsigned short fieldoffset,
1434 unsigned short keyoffset, void *elm);
1435
1436void *
1437__ZIP_REMOVE(void *h, zip_cmp_cb cmp, unsigned short fieldoffset,
1438 unsigned short keyoffset, void *elm);
1439
1440void *
1441__ZIP_ITER(unsigned short fieldoffset, zip_iter_cb cb,
1442 void *context, void *elm);
1443
1444void *
1445__ZIP_ITER_KEY(zip_cmp_cb cmp, unsigned short fieldoffset,
1446 unsigned short keyoffset, const void *key,
1447 zip_iter_cb cb, void *context, void *elm);
1448
1449void *
1450__ZIP_ZIP(unsigned short fieldoffset, void *left, void *right);
1451
1452void
1453__ZIP_UNZIP(zip_cmp_cb cmp, unsigned short fieldoffset,
1454 unsigned short keyoffset, const void *key,
1455 void *h, void *l, void *r);
1456
1457#ifdef __cplusplus
1458} /* extern "C" */
1459#endif
1460
1461
1462/**** amalgamated original file "/src/ua_types_encoding_binary.h" ****/
1463
1464/* This Source Code Form is subject to the terms of the Mozilla Public
1465 * License, v. 2.0. If a copy of the MPL was not distributed with this
1466 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
1467 *
1468 * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
1469 * Copyright 2015 (c) Sten Grüner
1470 * Copyright 2014, 2017 (c) Florian Palm
1471 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
1472 * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB
1473 */
1474
1475
1476
1477_UA_BEGIN_DECLS
1478
1479typedef UA_StatusCode (*UA_exchangeEncodeBuffer)(void *handle, UA_Byte **bufPos,
1480 const UA_Byte **bufEnd);
1481
1482/* Encodes the scalar value described by type in the binary encoding. Encoding
1483 * is thread-safe if thread-local variables are enabled. Encoding is also
1484 * reentrant and can be safely called from signal handlers or interrupts.
1485 *
1486 * @param src The value. Must not be NULL.
1487 * @param type The value type. Must not be NULL.
1488 * @param bufPos Points to a pointer to the current position in the encoding
1489 * buffer. Must not be NULL. The pointer is advanced by the number of
1490 * encoded bytes, or, if the buffer is exchanged, to the position in the
1491 * new buffer.
1492 * @param bufEnd Points to a pointer to the end of the encoding buffer (encoding
1493 * always stops before *buf_end). Must not be NULL. The pointer is
1494 * changed when the buffer is exchanged.
1495 * @param exchangeCallback Called when the end of the buffer is reached. This is
1496 used to send out a message chunk before continuing with the encoding.
1497 Is ignored if NULL.
1498 * @param exchangeHandle Custom data passed into the exchangeCallback.
1499 * @return Returns a statuscode whether encoding succeeded. */
1500UA_StatusCode
1501UA_encodeBinaryInternal(const void *src, const UA_DataType *type,
1502 UA_Byte **bufPos, const UA_Byte **bufEnd,
1503 UA_exchangeEncodeBuffer exchangeCallback,
1504 void *exchangeHandle)
1505 UA_FUNC_ATTR_WARN_UNUSED_RESULT;
1506
1507/* Decodes a scalar value described by type from binary encoding. Decoding
1508 * is thread-safe if thread-local variables are enabled. Decoding is also
1509 * reentrant and can be safely called from signal handlers or interrupts.
1510 *
1511 * @param src The buffer with the binary encoded value. Must not be NULL.
1512 * @param offset The current position in the buffer. Must not be NULL. The value
1513 * is advanced as decoding progresses.
1514 * @param dst The target value. Must not be NULL. The target is assumed to have
1515 * size type->memSize. The value is reset to zero before decoding. If
1516 * decoding fails, members are deleted and the value is reset (zeroed)
1517 * again.
1518 * @param type The value type. Must not be NULL.
1519 * @param customTypesSize The number of non-standard datatypes contained in the
1520 * customTypes array.
1521 * @param customTypes An array of non-standard datatypes (not included in
1522 * UA_TYPES). Can be NULL if customTypesSize is zero.
1523 * @return Returns a statuscode whether decoding succeeded. */
1524UA_StatusCode
1525UA_decodeBinaryInternal(const UA_ByteString *src, size_t *offset,
1526 void *dst, const UA_DataType *type,
1527 const UA_DataTypeArray *customTypes)
1528 UA_FUNC_ATTR_WARN_UNUSED_RESULT;
1529
1530const UA_DataType *
1531UA_findDataTypeByBinary(const UA_NodeId *typeId);
1532
1533_UA_END_DECLS
1534
1535
1536/**** amalgamated original file "/src/ua_util_internal.h" ****/
1537
1538/* This Source Code Form is subject to the terms of the Mozilla Public
1539 * License, v. 2.0. If a copy of the MPL was not distributed with this
1540 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
1541 *
1542 * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
1543 * Copyright 2014, 2017 (c) Florian Palm
1544 * Copyright 2015 (c) LEvertz
1545 * Copyright 2015-2016 (c) Sten Grüner
1546 * Copyright 2015 (c) Chris Iatrou
1547 * Copyright 2015-2016 (c) Oleksiy Vasylyev
1548 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
1549 * Copyright 2021 (c) Fraunhofer IOSB (Author: Jan Hermes)
1550 */
1551
1552
1553#define UA_INTERNAL
1554
1555
1556_UA_BEGIN_DECLS
1557
1558/* Macro-Expand for MSVC workarounds */
1559#define UA_MACRO_EXPAND(x) x
1560
1561/* Try if the type of the value can be adjusted "in situ" to the target type.
1562 * That can be done, for example, to map between int32 and an enum.
1563 *
1564 * This can also "unwrap" a type. For example: string -> array of bytes
1565 *
1566 * If value->data is changed during adjustType, free the pointer afterwards (if
1567 * you did not keep the original variant for _clear). */
1568void
1569adjustType(UA_Variant *value, const UA_DataType *targetType);
1570
1571/* Print a NodeId in logs */
1572#define UA_LOG_NODEID_INTERNAL(NODEID, LEVEL, LOG) \
1573 if(UA_LOGLEVEL <= UA_LOGLEVEL_##LEVEL) { \
1574 UA_String nodeIdStr = UA_STRING_NULL; \
1575 UA_NodeId_print(NODEID, &nodeIdStr); \
1576 LOG; \
1577 UA_String_clear(&nodeIdStr); \
1578 }
1579
1580#define UA_LOG_NODEID_TRACE(NODEID, LOG) UA_LOG_NODEID_INTERNAL(NODEID, TRACE, LOG)
1581#define UA_LOG_NODEID_DEBUG(NODEID, LOG) UA_LOG_NODEID_INTERNAL(NODEID, DEBUG, LOG)
1582#define UA_LOG_NODEID_INFO(NODEID, LOG) UA_LOG_NODEID_INTERNAL(NODEID, INFO, LOG)
1583#define UA_LOG_NODEID_WARNING(NODEID, LOG) UA_LOG_NODEID_INTERNAL(NODEID, WARNING, LOG)
1584#define UA_LOG_NODEID_ERROR(NODEID, LOG) UA_LOG_NODEID_INTERNAL(NODEID, ERROR, LOG)
1585#define UA_LOG_NODEID_FATAL(NODEID, LOG) UA_LOG_NODEID_INTERNAL(NODEID, FATAL, LOG)
1586
1587/* Short names for integer. These are not exposed on the public API, since many
1588 * user-applications make the same definitions in their headers. */
1589typedef UA_Byte u8;
1590typedef UA_SByte i8;
1591typedef UA_UInt16 u16;
1592typedef UA_Int16 i16;
1593typedef UA_UInt32 u32;
1594typedef UA_Int32 i32;
1595typedef UA_UInt64 u64;
1596typedef UA_Int64 i64;
1597typedef UA_StatusCode status;
1598
1599/**
1600 * Error checking macros
1601 */
1602
1603static UA_INLINE UA_Boolean
1604isGood(UA_StatusCode code) {
1605 return code == UA_STATUSCODE_GOOD;
1606}
1607
1608static UA_INLINE UA_Boolean
1609isNonNull(const void *ptr) {
1610 return ptr != NULL;
1611}
1612
1613static UA_INLINE UA_Boolean
1614isTrue(uint8_t expr) {
1615 return expr;
1616}
1617
1618#define UA_CHECK(A, EVAL_ON_ERROR) \
1619 do { \
1620 if(UA_UNLIKELY(!isTrue(A))) { \
1621 EVAL_ON_ERROR; \
1622 } \
1623 } while(0)
1624
1625#define UA_CHECK_STATUS(STATUSCODE, EVAL_ON_ERROR) \
1626 UA_CHECK(isGood(STATUSCODE), EVAL_ON_ERROR)
1627
1628#define UA_CHECK_MEM(STATUSCODE, EVAL_ON_ERROR) \
1629 UA_CHECK(isNonNull(STATUSCODE), EVAL_ON_ERROR)
1630
1631#ifdef UA_DEBUG_FILE_LINE_INFO
1632#define UA_CHECK_LOG_INTERNAL(A, STATUSCODE, EVAL, LOG, LOGGER, CAT, MSG, ...) \
1633 UA_MACRO_EXPAND( \
1634 UA_CHECK(A, LOG(LOGGER, CAT, "" MSG "%s (%s:%d: StatusCode: %s)", __VA_ARGS__, \
1635 __FILE__, __LINE__, UA_StatusCode_name(STATUSCODE)); \
1636 EVAL))
1637#else
1638#define UA_CHECK_LOG_INTERNAL(A, STATUSCODE, EVAL, LOG, LOGGER, CAT, MSG, ...) \
1639 UA_MACRO_EXPAND( \
1640 UA_CHECK(A, LOG(LOGGER, CAT, "" MSG "%s (StatusCode: %s)", __VA_ARGS__, \
1641 UA_StatusCode_name(STATUSCODE)); \
1642 EVAL))
1643#endif
1644
1645#define UA_CHECK_LOG(A, EVAL, LEVEL, LOGGER, CAT, ...) \
1646 UA_MACRO_EXPAND(UA_CHECK_LOG_INTERNAL(A, UA_STATUSCODE_BAD, EVAL, UA_LOG_##LEVEL, \
1647 LOGGER, CAT, __VA_ARGS__, ""))
1648
1649#define UA_CHECK_STATUS_LOG(STATUSCODE, EVAL, LEVEL, LOGGER, CAT, ...) \
1650 UA_MACRO_EXPAND(UA_CHECK_LOG_INTERNAL(isGood(STATUSCODE), STATUSCODE, \
1651 EVAL, UA_LOG_##LEVEL, LOGGER, CAT, \
1652 __VA_ARGS__, ""))
1653
1654#define UA_CHECK_MEM_LOG(PTR, EVAL, LEVEL, LOGGER, CAT, ...) \
1655 UA_MACRO_EXPAND(UA_CHECK_LOG_INTERNAL(isNonNull(PTR), UA_STATUSCODE_BADOUTOFMEMORY, \
1656 EVAL, UA_LOG_##LEVEL, LOGGER, CAT, \
1657 __VA_ARGS__, ""))
1658
1659/**
1660 * Check Macros
1661 * Usage examples:
1662 *
1663 * void *data = malloc(...);
1664 * UA_CHECK(data, return error);
1665 *
1666 * UA_StatusCode rv = some_func(...);
1667 * UA_CHECK_STATUS(rv, return rv);
1668 *
1669 * UA_Logger *logger = &server->config.logger;
1670 * rv = bar_func(...);
1671 * UA_CHECK_STATUS_WARN(rv, return rv, logger, UA_LOGCATEGORY_SERVER, "msg & args %s", "arg");
1672 */
1673#define UA_CHECK_FATAL(A, EVAL, LOGGER, CAT, ...) \
1674 UA_MACRO_EXPAND(UA_CHECK_LOG(A, EVAL, FATAL, LOGGER, CAT, __VA_ARGS__))
1675#define UA_CHECK_ERROR(A, EVAL, LOGGER, CAT, ...) \
1676 UA_MACRO_EXPAND(UA_CHECK_LOG(A, EVAL, ERROR, LOGGER, CAT, __VA_ARGS__))
1677#define UA_CHECK_WARN(A, EVAL, LOGGER, CAT, ...) \
1678 UA_MACRO_EXPAND(UA_CHECK_LOG(A, EVAL, WARNING, LOGGER, CAT, __VA_ARGS__))
1679#define UA_CHECK_INFO(A, EVAL, LOGGER, CAT, ...) \
1680 UA_MACRO_EXPAND(UA_CHECK_LOG(A, EVAL, INFO, LOGGER, CAT, __VA_ARGS__))
1681
1682#define UA_CHECK_STATUS_FATAL(STATUSCODE, EVAL, LOGGER, CAT, ...) \
1683 UA_MACRO_EXPAND( \
1684 UA_CHECK_STATUS_LOG(STATUSCODE, EVAL, FATAL, LOGGER, CAT, __VA_ARGS__))
1685#define UA_CHECK_STATUS_ERROR(STATUSCODE, EVAL, LOGGER, CAT, ...) \
1686 UA_MACRO_EXPAND( \
1687 UA_CHECK_STATUS_LOG(STATUSCODE, EVAL, ERROR, LOGGER, CAT, __VA_ARGS__))
1688#define UA_CHECK_STATUS_WARN(STATUSCODE, EVAL, LOGGER, CAT, ...) \
1689 UA_MACRO_EXPAND( \
1690 UA_CHECK_STATUS_LOG(STATUSCODE, EVAL, WARNING, LOGGER, CAT, __VA_ARGS__))
1691#define UA_CHECK_STATUS_INFO(STATUSCODE, EVAL, LOGGER, CAT, ...) \
1692 UA_MACRO_EXPAND( \
1693 UA_CHECK_STATUS_LOG(STATUSCODE, EVAL, INFO, LOGGER, CAT, __VA_ARGS__))
1694#define UA_CHECK_STATUS_DEBUG(STATUSCODE, EVAL, LOGGER, CAT, ...) \
1695 UA_MACRO_EXPAND( \
1696 UA_CHECK_STATUS_LOG(STATUSCODE, EVAL, DEBUG, LOGGER, CAT, __VA_ARGS__))
1697
1698#define UA_CHECK_MEM_FATAL(PTR, EVAL, LOGGER, CAT, ...) \
1699 UA_MACRO_EXPAND( \
1700 UA_CHECK_MEM_LOG(PTR, EVAL, FATAL, LOGGER, CAT, __VA_ARGS__))
1701#define UA_CHECK_MEM_ERROR(PTR, EVAL, LOGGER, CAT, ...) \
1702 UA_MACRO_EXPAND( \
1703 UA_CHECK_MEM_LOG(PTR, EVAL, ERROR, LOGGER, CAT, __VA_ARGS__))
1704#define UA_CHECK_MEM_WARN(PTR, EVAL, LOGGER, CAT, ...) \
1705 UA_MACRO_EXPAND( \
1706 UA_CHECK_MEM_LOG(PTR, EVAL, WARNING, LOGGER, CAT, __VA_ARGS__))
1707#define UA_CHECK_MEM_INFO(PTR, EVAL, LOGGER, CAT, ...) \
1708 UA_MACRO_EXPAND( \
1709 UA_CHECK_MEM_LOG(PTR, EVAL, INFO, LOGGER, CAT, __VA_ARGS__))
1710
1711/**
1712 * Utility Functions
1713 * ----------------- */
1714
1715#ifdef UA_ENABLE_DISCOVERY_SEMAPHORE
1716# ifdef UA_ARCHITECTURE_WIN32
1717# include <io.h>
1718# define UA_fileExists(X) ( _access(X, 0) == 0)
1719# else
1720# include <unistd.h>
1721# define UA_fileExists(X) ( access(X, 0) == 0)
1722# endif
1723#endif
1724
1725void
1726UA_cleanupDataTypeWithCustom(const UA_DataTypeArray *customTypes);
1727
1728/* Get the number of optional fields contained in an structure type */
1729size_t UA_EXPORT
1730getCountOfOptionalFields(const UA_DataType *type);
1731
1732/* Dump packet for debugging / fuzzing */
1733#ifdef UA_DEBUG_DUMP_PKGS
1734void UA_EXPORT
1735UA_dump_hex_pkg(UA_Byte* buffer, size_t bufferLen);
1736#endif
1737
1738/* Get pointer to leaf certificate of a specified valid chain of DER encoded
1739 * certificates */
1740UA_ByteString getLeafCertificate(UA_ByteString chain);
1741
1742/* Unions that represent any of the supported request or response message */
1743typedef union {
1744 UA_RequestHeader requestHeader;
1745 UA_FindServersRequest findServersRequest;
1746 UA_GetEndpointsRequest getEndpointsRequest;
1747#ifdef UA_ENABLE_DISCOVERY
1748# ifdef UA_ENABLE_DISCOVERY_MULTICAST
1749 UA_FindServersOnNetworkRequest findServersOnNetworkRequest;
1750# endif
1751 UA_RegisterServerRequest registerServerRequest;
1752 UA_RegisterServer2Request registerServer2Request;
1753#endif
1754 UA_OpenSecureChannelRequest openSecureChannelRequest;
1755 UA_CreateSessionRequest createSessionRequest;
1756 UA_ActivateSessionRequest activateSessionRequest;
1757 UA_CloseSessionRequest closeSessionRequest;
1758 UA_AddNodesRequest addNodesRequest;
1759 UA_AddReferencesRequest addReferencesRequest;
1760 UA_DeleteNodesRequest deleteNodesRequest;
1761 UA_DeleteReferencesRequest deleteReferencesRequest;
1762 UA_BrowseRequest browseRequest;
1763 UA_BrowseNextRequest browseNextRequest;
1764 UA_TranslateBrowsePathsToNodeIdsRequest translateBrowsePathsToNodeIdsRequest;
1765 UA_RegisterNodesRequest registerNodesRequest;
1766 UA_UnregisterNodesRequest unregisterNodesRequest;
1767 UA_ReadRequest readRequest;
1768 UA_WriteRequest writeRequest;
1769#ifdef UA_ENABLE_HISTORIZING
1770 UA_HistoryReadRequest historyReadRequest;
1771 UA_HistoryUpdateRequest historyUpdateRequest;
1772#endif
1773#ifdef UA_ENABLE_METHODCALLS
1774 UA_CallRequest callRequest;
1775#endif
1776#ifdef UA_ENABLE_SUBSCRIPTIONS
1777 UA_CreateMonitoredItemsRequest createMonitoredItemsRequest;
1778 UA_DeleteMonitoredItemsRequest deleteMonitoredItemsRequest;
1779 UA_ModifyMonitoredItemsRequest modifyMonitoredItemsRequest;
1780 UA_SetMonitoringModeRequest setMonitoringModeRequest;
1781 UA_CreateSubscriptionRequest createSubscriptionRequest;
1782 UA_ModifySubscriptionRequest modifySubscriptionRequest;
1783 UA_SetPublishingModeRequest setPublishingModeRequest;
1784 UA_PublishRequest publishRequest;
1785 UA_RepublishRequest republishRequest;
1786 UA_DeleteSubscriptionsRequest deleteSubscriptionsRequest;
1787#endif
1788} UA_Request;
1789
1790typedef union {
1791 UA_ResponseHeader responseHeader;
1792 UA_FindServersResponse findServersResponse;
1793 UA_GetEndpointsResponse getEndpointsResponse;
1794#ifdef UA_ENABLE_DISCOVERY
1795# ifdef UA_ENABLE_DISCOVERY_MULTICAST
1796 UA_FindServersOnNetworkResponse findServersOnNetworkResponse;
1797# endif
1798 UA_RegisterServerResponse registerServerResponse;
1799 UA_RegisterServer2Response registerServer2Response;
1800#endif
1801 UA_OpenSecureChannelResponse openSecureChannelResponse;
1802 UA_CreateSessionResponse createSessionResponse;
1803 UA_ActivateSessionResponse activateSessionResponse;
1804 UA_CloseSessionResponse closeSessionResponse;
1805 UA_AddNodesResponse addNodesResponse;
1806 UA_AddReferencesResponse addReferencesResponse;
1807 UA_DeleteNodesResponse deleteNodesResponse;
1808 UA_DeleteReferencesResponse deleteReferencesResponse;
1809 UA_BrowseResponse browseResponse;
1810 UA_BrowseNextResponse browseNextResponse;
1811 UA_TranslateBrowsePathsToNodeIdsResponse translateBrowsePathsToNodeIdsResponse;
1812 UA_RegisterNodesResponse registerNodesResponse;
1813 UA_UnregisterNodesResponse unregisterNodesResponse;
1814 UA_ReadResponse readResponse;
1815 UA_WriteResponse writeResponse;
1816#ifdef UA_ENABLE_HISTORIZING
1817 UA_HistoryReadResponse historyReadResponse;
1818 UA_HistoryUpdateResponse historyUpdateResponse;
1819#endif
1820#ifdef UA_ENABLE_METHODCALLS
1821 UA_CallResponse callResponse;
1822#endif
1823#ifdef UA_ENABLE_SUBSCRIPTIONS
1824 UA_CreateMonitoredItemsResponse createMonitoredItemsResponse;
1825 UA_DeleteMonitoredItemsResponse deleteMonitoredItemsResponse;
1826 UA_ModifyMonitoredItemsResponse modifyMonitoredItemsResponse;
1827 UA_SetMonitoringModeResponse setMonitoringModeResponse;
1828 UA_CreateSubscriptionResponse createSubscriptionResponse;
1829 UA_ModifySubscriptionResponse modifySubscriptionResponse;
1830 UA_SetPublishingModeResponse setPublishingModeResponse;
1831 UA_PublishResponse publishResponse;
1832 UA_RepublishResponse republishResponse;
1833 UA_DeleteSubscriptionsResponse deleteSubscriptionsResponse;
1834#endif
1835} UA_Response;
1836
1837/* Do not expose UA_String_equal_ignorecase to public API as it currently only handles
1838 * ASCII strings, and not UTF8! */
1839UA_Boolean UA_EXPORT
1840UA_String_equal_ignorecase(const UA_String *s1, const UA_String *s2);
1841
1842/********************/
1843/* Encoding Helpers */
1844/********************/
1845
1846/* out must be a buffer with at least 36 elements, the length of every guid */
1847void UA_Guid_to_hex(const UA_Guid *guid, u8* out, UA_Boolean lower);
1848
1849#define UA_ENCODING_HELPERS(TYPE, UPCASE_TYPE) \
1850 static UA_INLINE size_t \
1851 UA_##TYPE##_calcSizeBinary(const UA_##TYPE *src) { \
1852 return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_##UPCASE_TYPE]); \
1853 } \
1854 static UA_INLINE UA_StatusCode \
1855 UA_##TYPE##_encodeBinary(const UA_##TYPE *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { \
1856 return UA_encodeBinaryInternal(src, &UA_TYPES[UA_TYPES_##UPCASE_TYPE], \
1857 bufPos, &bufEnd, NULL, NULL); \
1858 } \
1859 static UA_INLINE UA_StatusCode \
1860 UA_##TYPE##_decodeBinary(const UA_ByteString *src, size_t *offset, UA_##TYPE *dst) { \
1861 return UA_decodeBinaryInternal(src, offset, dst, \
1862 &UA_TYPES[UA_TYPES_##UPCASE_TYPE], NULL); \
1863 }
1864
1865UA_ENCODING_HELPERS(Boolean, BOOLEAN)
1866UA_ENCODING_HELPERS(SByte, SBYTE)
1867UA_ENCODING_HELPERS(Byte, BYTE)
1868UA_ENCODING_HELPERS(Int16, INT16)
1869UA_ENCODING_HELPERS(UInt16, UINT16)
1870UA_ENCODING_HELPERS(Int32, INT32)
1871UA_ENCODING_HELPERS(UInt32, UINT32)
1872UA_ENCODING_HELPERS(Int64, INT64)
1873UA_ENCODING_HELPERS(UInt64, UINT64)
1874UA_ENCODING_HELPERS(Float, FLOAT)
1875UA_ENCODING_HELPERS(Double, DOUBLE)
1876UA_ENCODING_HELPERS(String, STRING)
1877UA_ENCODING_HELPERS(DateTime, DATETIME)
1878UA_ENCODING_HELPERS(Guid, GUID)
1879UA_ENCODING_HELPERS(ByteString, BYTESTRING)
1880UA_ENCODING_HELPERS(XmlElement, XMLELEMENT)
1881UA_ENCODING_HELPERS(NodeId, NODEID)
1882UA_ENCODING_HELPERS(ExpandedNodeId, EXPANDEDNODEID)
1883UA_ENCODING_HELPERS(StatusCode, STATUSCODE)
1884UA_ENCODING_HELPERS(QualifiedName, QUALIFIEDNAME)
1885UA_ENCODING_HELPERS(LocalizedText, LOCALIZEDTEXT)
1886UA_ENCODING_HELPERS(ExtensionObject, EXTENSIONOBJECT)
1887UA_ENCODING_HELPERS(DataValue, DATAVALUE)
1888UA_ENCODING_HELPERS(Variant, VARIANT)
1889UA_ENCODING_HELPERS(DiagnosticInfo, DIAGNOSTICINFO)
1890
1891_UA_END_DECLS
1892
1893
1894/**** amalgamated original file "/build/src_generated/open62541/transport_generated.h" ****/
1895
1896/**********************************
1897 * Autogenerated -- do not modify *
1898 **********************************/
1899
1900/* Must be before the include guards */
1901#ifdef UA_ENABLE_AMALGAMATION
1902#else
1903#endif
1904
1905
1906
1907_UA_BEGIN_DECLS
1908
1909/**
1910 * Every type is assigned an index in an array containing the type descriptions.
1911 * These descriptions are used during type handling (copying, deletion,
1912 * binary encoding, ...). */
1913#define UA_TRANSPORT_COUNT 9
1914extern UA_EXPORT UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT];
1915
1916/* MessageType: Message Type and whether the message contains an intermediate chunk */
1917typedef enum {
1918 UA_MESSAGETYPE_ACK = 0x4B4341,
1919 UA_MESSAGETYPE_HEL = 0x4C4548,
1920 UA_MESSAGETYPE_MSG = 0x47534D,
1921 UA_MESSAGETYPE_OPN = 0x4E504F,
1922 UA_MESSAGETYPE_CLO = 0x4F4C43,
1923 UA_MESSAGETYPE_ERR = 0x525245,
1924 UA_MESSAGETYPE_RHE = 0x454852,
1925 UA_MESSAGETYPE_INVALID = 0x0,
1926 __UA_MESSAGETYPE_FORCE32BIT = 0x7fffffff
1927} UA_MessageType;
1928
1929UA_STATIC_ASSERT(sizeof(UA_MessageType) == sizeof(UA_Int32), enum_must_be_32bit);
1930
1931#define UA_TRANSPORT_MESSAGETYPE 0
1932
1933/* ChunkType: Type of the chunk */
1934typedef enum {
1935 UA_CHUNKTYPE_FINAL = 0x46000000,
1936 UA_CHUNKTYPE_INTERMEDIATE = 0x43000000,
1937 UA_CHUNKTYPE_ABORT = 0x41000000,
1938 __UA_CHUNKTYPE_FORCE32BIT = 0x7fffffff
1939} UA_ChunkType;
1940
1941UA_STATIC_ASSERT(sizeof(UA_ChunkType) == sizeof(UA_Int32), enum_must_be_32bit);
1942
1943#define UA_TRANSPORT_CHUNKTYPE 1
1944
1945/* TcpMessageHeader: TCP Header */
1946typedef struct {
1947 UA_UInt32 messageTypeAndChunkType;
1948 UA_UInt32 messageSize;
1949} UA_TcpMessageHeader;
1950
1951#define UA_TRANSPORT_TCPMESSAGEHEADER 2
1952
1953/* TcpHelloMessage: Hello Message */
1954typedef struct {
1955 UA_UInt32 protocolVersion;
1956 UA_UInt32 receiveBufferSize;
1957 UA_UInt32 sendBufferSize;
1958 UA_UInt32 maxMessageSize;
1959 UA_UInt32 maxChunkCount;
1960 UA_String endpointUrl;
1961} UA_TcpHelloMessage;
1962
1963#define UA_TRANSPORT_TCPHELLOMESSAGE 3
1964
1965/* TcpReverseHelloMessage */
1966typedef struct {
1967 UA_String serverUri;
1968 UA_String endpointUrl;
1969} UA_TcpReverseHelloMessage;
1970
1971#define UA_TRANSPORT_TCPREVERSEHELLOMESSAGE 4
1972
1973/* TcpAcknowledgeMessage: Acknowledge Message */
1974typedef struct {
1975 UA_UInt32 protocolVersion;
1976 UA_UInt32 receiveBufferSize;
1977 UA_UInt32 sendBufferSize;
1978 UA_UInt32 maxMessageSize;
1979 UA_UInt32 maxChunkCount;
1980} UA_TcpAcknowledgeMessage;
1981
1982#define UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE 5
1983
1984/* TcpErrorMessage: Error Message */
1985typedef struct {
1986 UA_UInt32 error;
1987 UA_String reason;
1988} UA_TcpErrorMessage;
1989
1990#define UA_TRANSPORT_TCPERRORMESSAGE 6
1991
1992/* AsymmetricAlgorithmSecurityHeader: Asymmetric Security Header */
1993typedef struct {
1994 UA_ByteString securityPolicyUri;
1995 UA_ByteString senderCertificate;
1996 UA_ByteString receiverCertificateThumbprint;
1997} UA_AsymmetricAlgorithmSecurityHeader;
1998
1999#define UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER 7
2000
2001/* SequenceHeader: Secure Layer Sequence Header */
2002typedef struct {
2003 UA_UInt32 sequenceNumber;
2004 UA_UInt32 requestId;
2005} UA_SequenceHeader;
2006
2007#define UA_TRANSPORT_SEQUENCEHEADER 8
2008
2009
2010_UA_END_DECLS
2011
2012
2013/**** amalgamated original file "/build/src_generated/open62541/transport_generated_handling.h" ****/
2014
2015/**********************************
2016 * Autogenerated -- do not modify *
2017 **********************************/
2018
2019
2020
2021_UA_BEGIN_DECLS
2022
2023#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6
2024# pragma GCC diagnostic push
2025# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
2026# pragma GCC diagnostic ignored "-Wmissing-braces"
2027#endif
2028
2029
2030/* MessageType */
2031static UA_INLINE void
2032UA_MessageType_init(UA_MessageType *p) {
2033 memset(s: p, c: 0, n: sizeof(UA_MessageType));
2034}
2035
2036static UA_INLINE UA_MessageType *
2037UA_MessageType_new(void) {
2038 return (UA_MessageType*)UA_new(type: &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE]);
2039}
2040
2041static UA_INLINE UA_StatusCode
2042UA_MessageType_copy(const UA_MessageType *src, UA_MessageType *dst) {
2043 return UA_copy(src, dst, type: &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE]);
2044}
2045
2046UA_DEPRECATED static UA_INLINE void
2047UA_MessageType_deleteMembers(UA_MessageType *p) {
2048 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE]);
2049}
2050
2051static UA_INLINE void
2052UA_MessageType_clear(UA_MessageType *p) {
2053 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE]);
2054}
2055
2056static UA_INLINE void
2057UA_MessageType_delete(UA_MessageType *p) {
2058 UA_delete(p, type: &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE]);
2059}static UA_INLINE UA_Boolean
2060UA_MessageType_equal(const UA_MessageType *p1, const UA_MessageType *p2) {
2061 return (UA_order(p1, p2, type: &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE]) == UA_ORDER_EQ);
2062}
2063
2064
2065
2066/* ChunkType */
2067static UA_INLINE void
2068UA_ChunkType_init(UA_ChunkType *p) {
2069 memset(s: p, c: 0, n: sizeof(UA_ChunkType));
2070}
2071
2072static UA_INLINE UA_ChunkType *
2073UA_ChunkType_new(void) {
2074 return (UA_ChunkType*)UA_new(type: &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE]);
2075}
2076
2077static UA_INLINE UA_StatusCode
2078UA_ChunkType_copy(const UA_ChunkType *src, UA_ChunkType *dst) {
2079 return UA_copy(src, dst, type: &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE]);
2080}
2081
2082UA_DEPRECATED static UA_INLINE void
2083UA_ChunkType_deleteMembers(UA_ChunkType *p) {
2084 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE]);
2085}
2086
2087static UA_INLINE void
2088UA_ChunkType_clear(UA_ChunkType *p) {
2089 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE]);
2090}
2091
2092static UA_INLINE void
2093UA_ChunkType_delete(UA_ChunkType *p) {
2094 UA_delete(p, type: &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE]);
2095}static UA_INLINE UA_Boolean
2096UA_ChunkType_equal(const UA_ChunkType *p1, const UA_ChunkType *p2) {
2097 return (UA_order(p1, p2, type: &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE]) == UA_ORDER_EQ);
2098}
2099
2100
2101
2102/* TcpMessageHeader */
2103static UA_INLINE void
2104UA_TcpMessageHeader_init(UA_TcpMessageHeader *p) {
2105 memset(s: p, c: 0, n: sizeof(UA_TcpMessageHeader));
2106}
2107
2108static UA_INLINE UA_TcpMessageHeader *
2109UA_TcpMessageHeader_new(void) {
2110 return (UA_TcpMessageHeader*)UA_new(type: &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER]);
2111}
2112
2113static UA_INLINE UA_StatusCode
2114UA_TcpMessageHeader_copy(const UA_TcpMessageHeader *src, UA_TcpMessageHeader *dst) {
2115 return UA_copy(src, dst, type: &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER]);
2116}
2117
2118UA_DEPRECATED static UA_INLINE void
2119UA_TcpMessageHeader_deleteMembers(UA_TcpMessageHeader *p) {
2120 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER]);
2121}
2122
2123static UA_INLINE void
2124UA_TcpMessageHeader_clear(UA_TcpMessageHeader *p) {
2125 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER]);
2126}
2127
2128static UA_INLINE void
2129UA_TcpMessageHeader_delete(UA_TcpMessageHeader *p) {
2130 UA_delete(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER]);
2131}static UA_INLINE UA_Boolean
2132UA_TcpMessageHeader_equal(const UA_TcpMessageHeader *p1, const UA_TcpMessageHeader *p2) {
2133 return (UA_order(p1, p2, type: &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER]) == UA_ORDER_EQ);
2134}
2135
2136
2137
2138/* TcpHelloMessage */
2139static UA_INLINE void
2140UA_TcpHelloMessage_init(UA_TcpHelloMessage *p) {
2141 memset(s: p, c: 0, n: sizeof(UA_TcpHelloMessage));
2142}
2143
2144static UA_INLINE UA_TcpHelloMessage *
2145UA_TcpHelloMessage_new(void) {
2146 return (UA_TcpHelloMessage*)UA_new(type: &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]);
2147}
2148
2149static UA_INLINE UA_StatusCode
2150UA_TcpHelloMessage_copy(const UA_TcpHelloMessage *src, UA_TcpHelloMessage *dst) {
2151 return UA_copy(src, dst, type: &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]);
2152}
2153
2154UA_DEPRECATED static UA_INLINE void
2155UA_TcpHelloMessage_deleteMembers(UA_TcpHelloMessage *p) {
2156 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]);
2157}
2158
2159static UA_INLINE void
2160UA_TcpHelloMessage_clear(UA_TcpHelloMessage *p) {
2161 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]);
2162}
2163
2164static UA_INLINE void
2165UA_TcpHelloMessage_delete(UA_TcpHelloMessage *p) {
2166 UA_delete(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]);
2167}static UA_INLINE UA_Boolean
2168UA_TcpHelloMessage_equal(const UA_TcpHelloMessage *p1, const UA_TcpHelloMessage *p2) {
2169 return (UA_order(p1, p2, type: &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]) == UA_ORDER_EQ);
2170}
2171
2172
2173
2174/* TcpReverseHelloMessage */
2175static UA_INLINE void
2176UA_TcpReverseHelloMessage_init(UA_TcpReverseHelloMessage *p) {
2177 memset(s: p, c: 0, n: sizeof(UA_TcpReverseHelloMessage));
2178}
2179
2180static UA_INLINE UA_TcpReverseHelloMessage *
2181UA_TcpReverseHelloMessage_new(void) {
2182 return (UA_TcpReverseHelloMessage*)UA_new(type: &UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE]);
2183}
2184
2185static UA_INLINE UA_StatusCode
2186UA_TcpReverseHelloMessage_copy(const UA_TcpReverseHelloMessage *src, UA_TcpReverseHelloMessage *dst) {
2187 return UA_copy(src, dst, type: &UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE]);
2188}
2189
2190UA_DEPRECATED static UA_INLINE void
2191UA_TcpReverseHelloMessage_deleteMembers(UA_TcpReverseHelloMessage *p) {
2192 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE]);
2193}
2194
2195static UA_INLINE void
2196UA_TcpReverseHelloMessage_clear(UA_TcpReverseHelloMessage *p) {
2197 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE]);
2198}
2199
2200static UA_INLINE void
2201UA_TcpReverseHelloMessage_delete(UA_TcpReverseHelloMessage *p) {
2202 UA_delete(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE]);
2203}static UA_INLINE UA_Boolean
2204UA_TcpReverseHelloMessage_equal(const UA_TcpReverseHelloMessage *p1, const UA_TcpReverseHelloMessage *p2) {
2205 return (UA_order(p1, p2, type: &UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE]) == UA_ORDER_EQ);
2206}
2207
2208
2209
2210/* TcpAcknowledgeMessage */
2211static UA_INLINE void
2212UA_TcpAcknowledgeMessage_init(UA_TcpAcknowledgeMessage *p) {
2213 memset(s: p, c: 0, n: sizeof(UA_TcpAcknowledgeMessage));
2214}
2215
2216static UA_INLINE UA_TcpAcknowledgeMessage *
2217UA_TcpAcknowledgeMessage_new(void) {
2218 return (UA_TcpAcknowledgeMessage*)UA_new(type: &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE]);
2219}
2220
2221static UA_INLINE UA_StatusCode
2222UA_TcpAcknowledgeMessage_copy(const UA_TcpAcknowledgeMessage *src, UA_TcpAcknowledgeMessage *dst) {
2223 return UA_copy(src, dst, type: &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE]);
2224}
2225
2226UA_DEPRECATED static UA_INLINE void
2227UA_TcpAcknowledgeMessage_deleteMembers(UA_TcpAcknowledgeMessage *p) {
2228 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE]);
2229}
2230
2231static UA_INLINE void
2232UA_TcpAcknowledgeMessage_clear(UA_TcpAcknowledgeMessage *p) {
2233 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE]);
2234}
2235
2236static UA_INLINE void
2237UA_TcpAcknowledgeMessage_delete(UA_TcpAcknowledgeMessage *p) {
2238 UA_delete(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE]);
2239}static UA_INLINE UA_Boolean
2240UA_TcpAcknowledgeMessage_equal(const UA_TcpAcknowledgeMessage *p1, const UA_TcpAcknowledgeMessage *p2) {
2241 return (UA_order(p1, p2, type: &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE]) == UA_ORDER_EQ);
2242}
2243
2244
2245
2246/* TcpErrorMessage */
2247static UA_INLINE void
2248UA_TcpErrorMessage_init(UA_TcpErrorMessage *p) {
2249 memset(s: p, c: 0, n: sizeof(UA_TcpErrorMessage));
2250}
2251
2252static UA_INLINE UA_TcpErrorMessage *
2253UA_TcpErrorMessage_new(void) {
2254 return (UA_TcpErrorMessage*)UA_new(type: &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]);
2255}
2256
2257static UA_INLINE UA_StatusCode
2258UA_TcpErrorMessage_copy(const UA_TcpErrorMessage *src, UA_TcpErrorMessage *dst) {
2259 return UA_copy(src, dst, type: &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]);
2260}
2261
2262UA_DEPRECATED static UA_INLINE void
2263UA_TcpErrorMessage_deleteMembers(UA_TcpErrorMessage *p) {
2264 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]);
2265}
2266
2267static UA_INLINE void
2268UA_TcpErrorMessage_clear(UA_TcpErrorMessage *p) {
2269 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]);
2270}
2271
2272static UA_INLINE void
2273UA_TcpErrorMessage_delete(UA_TcpErrorMessage *p) {
2274 UA_delete(p, type: &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]);
2275}static UA_INLINE UA_Boolean
2276UA_TcpErrorMessage_equal(const UA_TcpErrorMessage *p1, const UA_TcpErrorMessage *p2) {
2277 return (UA_order(p1, p2, type: &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]) == UA_ORDER_EQ);
2278}
2279
2280
2281
2282/* AsymmetricAlgorithmSecurityHeader */
2283static UA_INLINE void
2284UA_AsymmetricAlgorithmSecurityHeader_init(UA_AsymmetricAlgorithmSecurityHeader *p) {
2285 memset(s: p, c: 0, n: sizeof(UA_AsymmetricAlgorithmSecurityHeader));
2286}
2287
2288static UA_INLINE UA_AsymmetricAlgorithmSecurityHeader *
2289UA_AsymmetricAlgorithmSecurityHeader_new(void) {
2290 return (UA_AsymmetricAlgorithmSecurityHeader*)UA_new(type: &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]);
2291}
2292
2293static UA_INLINE UA_StatusCode
2294UA_AsymmetricAlgorithmSecurityHeader_copy(const UA_AsymmetricAlgorithmSecurityHeader *src, UA_AsymmetricAlgorithmSecurityHeader *dst) {
2295 return UA_copy(src, dst, type: &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]);
2296}
2297
2298UA_DEPRECATED static UA_INLINE void
2299UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(UA_AsymmetricAlgorithmSecurityHeader *p) {
2300 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]);
2301}
2302
2303static UA_INLINE void
2304UA_AsymmetricAlgorithmSecurityHeader_clear(UA_AsymmetricAlgorithmSecurityHeader *p) {
2305 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]);
2306}
2307
2308static UA_INLINE void
2309UA_AsymmetricAlgorithmSecurityHeader_delete(UA_AsymmetricAlgorithmSecurityHeader *p) {
2310 UA_delete(p, type: &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]);
2311}static UA_INLINE UA_Boolean
2312UA_AsymmetricAlgorithmSecurityHeader_equal(const UA_AsymmetricAlgorithmSecurityHeader *p1, const UA_AsymmetricAlgorithmSecurityHeader *p2) {
2313 return (UA_order(p1, p2, type: &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]) == UA_ORDER_EQ);
2314}
2315
2316
2317
2318/* SequenceHeader */
2319static UA_INLINE void
2320UA_SequenceHeader_init(UA_SequenceHeader *p) {
2321 memset(s: p, c: 0, n: sizeof(UA_SequenceHeader));
2322}
2323
2324static UA_INLINE UA_SequenceHeader *
2325UA_SequenceHeader_new(void) {
2326 return (UA_SequenceHeader*)UA_new(type: &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER]);
2327}
2328
2329static UA_INLINE UA_StatusCode
2330UA_SequenceHeader_copy(const UA_SequenceHeader *src, UA_SequenceHeader *dst) {
2331 return UA_copy(src, dst, type: &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER]);
2332}
2333
2334UA_DEPRECATED static UA_INLINE void
2335UA_SequenceHeader_deleteMembers(UA_SequenceHeader *p) {
2336 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER]);
2337}
2338
2339static UA_INLINE void
2340UA_SequenceHeader_clear(UA_SequenceHeader *p) {
2341 UA_clear(p, type: &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER]);
2342}
2343
2344static UA_INLINE void
2345UA_SequenceHeader_delete(UA_SequenceHeader *p) {
2346 UA_delete(p, type: &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER]);
2347}static UA_INLINE UA_Boolean
2348UA_SequenceHeader_equal(const UA_SequenceHeader *p1, const UA_SequenceHeader *p2) {
2349 return (UA_order(p1, p2, type: &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER]) == UA_ORDER_EQ);
2350}
2351
2352
2353
2354#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6
2355# pragma GCC diagnostic pop
2356#endif
2357
2358_UA_END_DECLS
2359
2360
2361/**** amalgamated original file "/src/ua_securechannel.h" ****/
2362
2363/* This Source Code Form is subject to the terms of the Mozilla Public
2364 * License, v. 2.0. If a copy of the MPL was not distributed with this
2365 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
2366 *
2367 * Copyright 2014-2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
2368 * Copyright 2017 (c) Florian Palm
2369 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
2370 * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB
2371 */
2372
2373
2374
2375
2376_UA_BEGIN_DECLS
2377
2378struct UA_SecureChannel;
2379typedef struct UA_SecureChannel UA_SecureChannel;
2380
2381/* The message header of the OPC UA binary protocol is structured as follows:
2382 *
2383 * - MessageType (3 Byte)
2384 * - IsFinal (1 Byte)
2385 * - MessageSize (4 Byte)
2386 * *** UA_SECURECHANNEL_MESSAGEHEADER_LENGTH ***
2387 * - SecureChannelId (4 Byte)
2388 * *** UA_SECURECHANNEL_CHANNELHEADER_LENGTH ***
2389 * - SecurityHeader (4 Byte TokenId for symmetric, otherwise dynamic length)
2390 * - SequenceHeader (8 Byte)
2391 * - SequenceNumber
2392 * - RequestId
2393 */
2394
2395#define UA_SECURECHANNEL_MESSAGEHEADER_LENGTH 8
2396#define UA_SECURECHANNEL_CHANNELHEADER_LENGTH 12
2397#define UA_SECURECHANNEL_SYMMETRIC_SECURITYHEADER_LENGTH 4
2398#define UA_SECURECHANNEL_SEQUENCEHEADER_LENGTH 8
2399#define UA_SECURECHANNEL_SYMMETRIC_HEADER_UNENCRYPTEDLENGTH \
2400 (UA_SECURECHANNEL_CHANNELHEADER_LENGTH + \
2401 UA_SECURECHANNEL_SYMMETRIC_SECURITYHEADER_LENGTH)
2402#define UA_SECURECHANNEL_SYMMETRIC_HEADER_TOTALLENGTH \
2403 (UA_SECURECHANNEL_CHANNELHEADER_LENGTH + \
2404 UA_SECURECHANNEL_SYMMETRIC_SECURITYHEADER_LENGTH + \
2405 UA_SECURECHANNEL_SEQUENCEHEADER_LENGTH)
2406
2407/* Minimum length of a valid message (ERR message with an empty reason) */
2408#define UA_SECURECHANNEL_MESSAGE_MIN_LENGTH 16
2409
2410/* The Session implementation differs between client and server. Still, it is
2411 * expected that the Session structure begins with the SessionHeader. This is
2412 * the interface that will be used by the SecureChannel. The lifecycle of
2413 * Sessions is independent of the underlying SecureChannel. But every Session
2414 * can be attached to only one SecureChannel. */
2415typedef struct UA_SessionHeader {
2416 SLIST_ENTRY(UA_SessionHeader) next;
2417 UA_NodeId authenticationToken;
2418 UA_Boolean serverSession; /* Disambiguate client and server session */
2419 UA_SecureChannel *channel; /* The pointer back to the SecureChannel in the session. */
2420} UA_SessionHeader;
2421
2422/* For chunked requests */
2423typedef struct UA_Chunk {
2424 TAILQ_ENTRY(UA_Chunk) pointers;
2425 UA_ByteString bytes;
2426 UA_MessageType messageType;
2427 UA_ChunkType chunkType;
2428 UA_UInt32 requestId;
2429 UA_Boolean copied; /* Do the bytes point to a buffer from the network or was
2430 * memory allocated for the chunk separately */
2431} UA_Chunk;
2432
2433typedef TAILQ_HEAD(UA_ChunkQueue, UA_Chunk) UA_ChunkQueue;
2434
2435typedef enum {
2436 UA_SECURECHANNELRENEWSTATE_NORMAL,
2437
2438 /* Client has sent an OPN, but not received a response so far. */
2439 UA_SECURECHANNELRENEWSTATE_SENT,
2440
2441 /* The server waits for the first request with the new token for the rollover.
2442 * The new token is stored in the altSecurityToken. The configured local and
2443 * remote symmetric encryption keys are the old ones. */
2444 UA_SECURECHANNELRENEWSTATE_NEWTOKEN_SERVER,
2445
2446 /* The client already uses the new token. But he waits for the server to respond
2447 * with the new token to complete the rollover. The old token is stored in
2448 * altSecurityToken. The local symmetric encryption key is new. The remote
2449 * encryption key is the old one. */
2450 UA_SECURECHANNELRENEWSTATE_NEWTOKEN_CLIENT
2451} UA_SecureChannelRenewState;
2452
2453struct UA_SecureChannel {
2454 UA_SecureChannelState state;
2455 UA_SecureChannelRenewState renewState;
2456 UA_MessageSecurityMode securityMode;
2457 UA_ShutdownReason shutdownReason;
2458 UA_ConnectionConfig config;
2459
2460 UA_String endpointUrl;
2461
2462 /* Connection handling in the EventLoop */
2463 UA_ConnectionManager *connectionManager;
2464 uintptr_t connectionId;
2465
2466 /* Rules for revolving the token with a renew OPN request: The client is
2467 * allowed to accept messages with the old token until the OPN response has
2468 * arrived. The server accepts the old token until one message secured with
2469 * the new token has arrived.
2470 *
2471 * We recognize whether nextSecurityToken contains a valid next token if the
2472 * ChannelId is not 0. */
2473 UA_ChannelSecurityToken securityToken; /* Also contains the channelId */
2474 UA_ChannelSecurityToken altSecurityToken; /* Alternative token for the rollover.
2475 * See the renewState. */
2476
2477 /* The endpoint and context of the channel */
2478 UA_SecurityPolicy *securityPolicy;
2479 void *channelContext; /* For interaction with the security policy */
2480
2481 /* Asymmetric encryption info */
2482 UA_ByteString remoteCertificate;
2483 UA_Byte remoteCertificateThumbprint[20]; /* The thumbprint of the remote certificate */
2484
2485 /* Symmetric encryption nonces. These are used to generate the key material
2486 * and must not be reused once the keys are in place.
2487 *
2488 * Nonces are also used during the CreateSession / ActivateSession
2489 * handshake. These are not handled here, as the Session handling can
2490 * overlap with a RenewSecureChannel. */
2491 UA_ByteString remoteNonce;
2492 UA_ByteString localNonce;
2493
2494 UA_UInt32 receiveSequenceNumber;
2495 UA_UInt32 sendSequenceNumber;
2496
2497 /* Sessions that are bound to the SecureChannel */
2498 SLIST_HEAD(, UA_SessionHeader) sessions;
2499
2500 /* (Decrypted) chunks waiting to be processed */
2501 UA_ChunkQueue chunks;
2502 size_t chunksCount;
2503 size_t chunksLength;
2504
2505 /* Received buffer from which no chunks have been extracted so far */
2506 UA_ByteString unprocessed;
2507 size_t unprocessedOffset;
2508 UA_Boolean unprocessedCopied;
2509 UA_DelayedCallback unprocessedDelayed;
2510
2511 UA_CertificateVerification *certificateVerification;
2512 void *processOPNHeaderApplication;
2513 UA_StatusCode (*processOPNHeader)(void *application, UA_SecureChannel *channel,
2514 const UA_AsymmetricAlgorithmSecurityHeader *asymHeader);
2515};
2516
2517void UA_SecureChannel_init(UA_SecureChannel *channel);
2518
2519/* Trigger the shutdown */
2520void UA_SecureChannel_shutdown(UA_SecureChannel *channel,
2521 UA_ShutdownReason shutdownReason);
2522
2523/* Eventual cleanup after the channel has closed. It is possible to call _init
2524 * on the channel afterwards to reset it to the fresh status. */
2525void UA_SecureChannel_clear(UA_SecureChannel *channel);
2526
2527/* Process the remote configuration in the HEL/ACK handshake. The connection
2528 * config is initialized with the local settings. */
2529UA_StatusCode
2530UA_SecureChannel_processHELACK(UA_SecureChannel *channel,
2531 const UA_TcpAcknowledgeMessage *remoteConfig);
2532
2533UA_StatusCode
2534UA_SecureChannel_setSecurityPolicy(UA_SecureChannel *channel,
2535 UA_SecurityPolicy *securityPolicy,
2536 const UA_ByteString *remoteCertificate);
2537
2538UA_Boolean
2539UA_SecureChannel_isConnected(UA_SecureChannel *channel);
2540
2541/* When a fatal error occurs the Server shall send an Error Message to the
2542 * Client and close the socket. When a Client encounters one of these errors, it
2543 * shall also close the socket but does not send an Error Message. After the
2544 * socket is closed a Client shall try to reconnect automatically using the
2545 * mechanisms described in [...]. */
2546void
2547UA_SecureChannel_sendError(UA_SecureChannel *channel, UA_TcpErrorMessage *error);
2548
2549/* Remove (partially) received unprocessed chunks */
2550void
2551UA_SecureChannel_deleteBuffered(UA_SecureChannel *channel);
2552
2553/* Wrapper function for generating a local nonce for the supplied channel. Uses
2554 * the random generator of the channels security policy to allocate and generate
2555 * a nonce with the specified length. */
2556UA_StatusCode
2557UA_SecureChannel_generateLocalNonce(UA_SecureChannel *channel);
2558
2559UA_StatusCode
2560UA_SecureChannel_generateLocalKeys(const UA_SecureChannel *channel);
2561
2562UA_StatusCode
2563generateRemoteKeys(const UA_SecureChannel *channel);
2564
2565/**
2566 * Sending Messages
2567 * ---------------- */
2568
2569UA_StatusCode
2570UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel, UA_UInt32 requestId,
2571 const void *content, const UA_DataType *contentType);
2572
2573UA_StatusCode
2574UA_SecureChannel_sendSymmetricMessage(UA_SecureChannel *channel, UA_UInt32 requestId,
2575 UA_MessageType messageType, void *payload,
2576 const UA_DataType *payloadType);
2577
2578/* The MessageContext is forwarded into the encoding layer so that we can send
2579 * chunks before continuing to encode. This lets us reuse a fixed chunk-sized
2580 * messages buffer. */
2581typedef struct {
2582 UA_SecureChannel *channel;
2583 UA_UInt32 requestId;
2584 UA_UInt32 messageType;
2585
2586 UA_UInt16 chunksSoFar;
2587 size_t messageSizeSoFar;
2588
2589 UA_ByteString messageBuffer;
2590 UA_Byte *buf_pos;
2591 const UA_Byte *buf_end;
2592
2593 UA_Boolean final;
2594} UA_MessageContext;
2595
2596/* Start the context of a new symmetric message. */
2597UA_StatusCode
2598UA_MessageContext_begin(UA_MessageContext *mc, UA_SecureChannel *channel,
2599 UA_UInt32 requestId, UA_MessageType messageType);
2600
2601/* Encode the content and send out full chunks. If the return code is good, then
2602 * the ChunkInfo contains encoded content that has not been sent. If the return
2603 * code is bad, then the ChunkInfo has been cleaned up internally. */
2604UA_StatusCode
2605UA_MessageContext_encode(UA_MessageContext *mc, const void *content,
2606 const UA_DataType *contentType);
2607
2608/* Sends a symmetric message already encoded in the context. The context is
2609 * cleaned up, also in case of errors. */
2610UA_StatusCode
2611UA_MessageContext_finish(UA_MessageContext *mc);
2612
2613/* To be used when a failure occures when a MessageContext is open. Note that
2614 * the _encode and _finish methods will clean up internally. _abort can be run
2615 * on a MessageContext that has already been cleaned up before. */
2616void
2617UA_MessageContext_abort(UA_MessageContext *mc);
2618
2619/**
2620 * Receive Message
2621 * --------------- */
2622
2623/* Process a received buffer. This always has these three steps:
2624 *
2625 * 1. loadBuffer: The chunks in the SecureChannel are cut into chunks.
2626 * The chunks can still point to the buffer.
2627 * 2. getCompleteMessage: Assemble chunks into a complete message. This is
2628 * repeated until an error occours or an empty message is returned.
2629 * 3. persistBuffer: Make a copy of the remaining unpprocessed bytestring. So
2630 * that the NetworkManager can reuse or free the packet memory.
2631 *
2632 * Note that only MSG and CLO messages are decrypted. HEL/ACK/OPN/... are
2633 * forwarded verbatim to the application. */
2634UA_StatusCode
2635UA_SecureChannel_loadBuffer(UA_SecureChannel *channel, const UA_ByteString buffer);
2636
2637UA_StatusCode
2638UA_SecureChannel_getCompleteMessage(UA_SecureChannel *channel,
2639 UA_MessageType *messageType, UA_UInt32 *requestId,
2640 UA_ByteString *payload, UA_Boolean *copied);
2641
2642UA_StatusCode
2643UA_SecureChannel_persistBuffer(UA_SecureChannel *channel);
2644
2645/* Internal methods in ua_securechannel_crypto.h */
2646
2647void
2648hideBytesAsym(const UA_SecureChannel *channel, UA_Byte **buf_start,
2649 const UA_Byte **buf_end);
2650
2651/* Decrypt and verify via the signature. The chunk buffer is reused to hold the
2652 * decrypted data after the MessageHeader and SecurityHeader. The chunk length
2653 * is reduced by the signature, padding and encryption overhead.
2654 *
2655 * The offset argument points to the start of the encrypted content (beginning
2656 * with the SequenceHeader).*/
2657UA_StatusCode
2658decryptAndVerifyChunk(const UA_SecureChannel *channel,
2659 const UA_SecurityPolicyCryptoModule *cryptoModule,
2660 UA_MessageType messageType, UA_ByteString *chunk,
2661 size_t offset);
2662
2663size_t
2664calculateAsymAlgSecurityHeaderLength(const UA_SecureChannel *channel);
2665
2666UA_StatusCode
2667prependHeadersAsym(UA_SecureChannel *const channel, UA_Byte *header_pos,
2668 const UA_Byte *buf_end, size_t totalLength,
2669 size_t securityHeaderLength, UA_UInt32 requestId,
2670 size_t *const finalLength);
2671
2672void
2673setBufPos(UA_MessageContext *mc);
2674
2675UA_StatusCode
2676checkSymHeader(UA_SecureChannel *channel, const UA_UInt32 tokenId);
2677
2678UA_StatusCode
2679checkAsymHeader(UA_SecureChannel *channel,
2680 const UA_AsymmetricAlgorithmSecurityHeader *asymHeader);
2681
2682void
2683padChunk(UA_SecureChannel *channel, const UA_SecurityPolicyCryptoModule *cm,
2684 const UA_Byte *start, UA_Byte **pos);
2685
2686UA_StatusCode
2687signAndEncryptAsym(UA_SecureChannel *channel, size_t preSignLength,
2688 UA_ByteString *buf, size_t securityHeaderLength,
2689 size_t totalLength);
2690
2691UA_StatusCode
2692signAndEncryptSym(UA_MessageContext *messageContext,
2693 size_t preSigLength, size_t totalLength);
2694
2695/**
2696 * Log Helper
2697 * ----------
2698 * C99 requires at least one element for the variadic argument. If the log
2699 * statement has no variable arguments, supply an additional NULL. It will be
2700 * ignored by printf.
2701 *
2702 * We have to jump through some hoops to enable the use of format strings
2703 * without arguments since (pedantic) C99 does not allow variadic macros with
2704 * zero arguments. So we add a dummy argument that is not printed (%.0s is
2705 * string of length zero). */
2706
2707#define UA_LOG_CHANNEL_INTERNAL(LOGGER, LEVEL, CHANNEL, MSG, ...) \
2708 if(UA_LOGLEVEL <= UA_LOGLEVEL_##LEVEL) { \
2709 UA_LOG_##LEVEL(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, \
2710 "TCP %lu\t| SC %" PRIu32 "\t| " MSG "%.0s", \
2711 (long unsigned)(CHANNEL)->connectionId, \
2712 (CHANNEL)->securityToken.channelId, __VA_ARGS__); \
2713 }
2714
2715#define UA_LOG_TRACE_CHANNEL(LOGGER, CHANNEL, ...) \
2716 UA_MACRO_EXPAND(UA_LOG_CHANNEL_INTERNAL(LOGGER, TRACE, CHANNEL, __VA_ARGS__, ""))
2717#define UA_LOG_DEBUG_CHANNEL(LOGGER, CHANNEL, ...) \
2718 UA_MACRO_EXPAND(UA_LOG_CHANNEL_INTERNAL(LOGGER, DEBUG, CHANNEL, __VA_ARGS__, ""))
2719#define UA_LOG_INFO_CHANNEL(LOGGER, CHANNEL, ...) \
2720 UA_MACRO_EXPAND(UA_LOG_CHANNEL_INTERNAL(LOGGER, INFO, CHANNEL, __VA_ARGS__, ""))
2721#define UA_LOG_WARNING_CHANNEL(LOGGER, CHANNEL, ...) \
2722 UA_MACRO_EXPAND(UA_LOG_CHANNEL_INTERNAL(LOGGER, WARNING, CHANNEL, __VA_ARGS__, ""))
2723#define UA_LOG_ERROR_CHANNEL(LOGGER, CHANNEL, ...) \
2724 UA_MACRO_EXPAND(UA_LOG_CHANNEL_INTERNAL(LOGGER, ERROR, CHANNEL, __VA_ARGS__, ""))
2725#define UA_LOG_FATAL_CHANNEL(LOGGER, CHANNEL, ...) \
2726 UA_MACRO_EXPAND(UA_LOG_CHANNEL_INTERNAL(LOGGER, FATAL, CHANNEL, __VA_ARGS__, ""))
2727
2728_UA_END_DECLS
2729
2730
2731/**** amalgamated original file "/src/server/ua_session.h" ****/
2732
2733/* This Source Code Form is subject to the terms of the Mozilla Public
2734 * License, v. 2.0. If a copy of the MPL was not distributed with this
2735 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
2736 *
2737 * Copyright 2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
2738 * Copyright 2019 (c) HMS Industrial Networks AB (Author: Jonas Green)
2739 */
2740
2741
2742
2743
2744_UA_BEGIN_DECLS
2745
2746#define UA_MAXCONTINUATIONPOINTS 5
2747
2748struct ContinuationPoint;
2749typedef struct ContinuationPoint ContinuationPoint;
2750
2751/* Returns the next entry in the linked list */
2752ContinuationPoint *
2753ContinuationPoint_clear(ContinuationPoint *cp);
2754
2755struct UA_Subscription;
2756typedef struct UA_Subscription UA_Subscription;
2757
2758#ifdef UA_ENABLE_SUBSCRIPTIONS
2759typedef struct UA_PublishResponseEntry {
2760 SIMPLEQ_ENTRY(UA_PublishResponseEntry) listEntry;
2761 UA_UInt32 requestId;
2762 UA_DateTime maxTime; /* Based on the TimeoutHint of the request */
2763 UA_PublishResponse response;
2764} UA_PublishResponseEntry;
2765#endif
2766
2767typedef struct {
2768 UA_SessionHeader header;
2769 UA_ApplicationDescription clientDescription;
2770 UA_String sessionName;
2771 UA_Boolean activated;
2772 void *sessionHandle; /* pointer assigned in userland-callback */
2773 UA_NodeId sessionId;
2774 UA_String clientUserIdOfSession;
2775 UA_UInt32 maxRequestMessageSize;
2776 UA_UInt32 maxResponseMessageSize;
2777 UA_Double timeout; /* in ms */
2778 UA_DateTime validTill;
2779 UA_ByteString serverNonce;
2780
2781 UA_UInt16 availableContinuationPoints;
2782 ContinuationPoint *continuationPoints;
2783
2784 UA_KeyValueMap *attributes;
2785
2786 /* Localization information */
2787 size_t localeIdsSize;
2788 UA_String *localeIds;
2789
2790#ifdef UA_ENABLE_SUBSCRIPTIONS
2791 /* The queue is ordered according to the priority byte (higher bytes come
2792 * first). When a late subscription finally publishes, then it is pushed to
2793 * the back within the sub-set of subscriptions that has the same priority
2794 * (round-robin scheduling). */
2795 size_t subscriptionsSize;
2796 TAILQ_HEAD(, UA_Subscription) subscriptions;
2797
2798 size_t responseQueueSize;
2799 SIMPLEQ_HEAD(, UA_PublishResponseEntry) responseQueue;
2800
2801 size_t totalRetransmissionQueueSize; /* Retransmissions of all subscriptions */
2802#endif
2803
2804#ifdef UA_ENABLE_DIAGNOSTICS
2805 UA_SessionSecurityDiagnosticsDataType securityDiagnostics;
2806 UA_SessionDiagnosticsDataType diagnostics;
2807#endif
2808} UA_Session;
2809
2810/**
2811 * Session Lifecycle
2812 * ----------------- */
2813
2814void UA_Session_init(UA_Session *session);
2815void UA_Session_clear(UA_Session *session, UA_Server *server);
2816void UA_Session_attachToSecureChannel(UA_Session *session, UA_SecureChannel *channel);
2817void UA_Session_detachFromSecureChannel(UA_Session *session);
2818UA_StatusCode UA_Session_generateNonce(UA_Session *session);
2819
2820/* If any activity on a session happens, the timeout is extended */
2821void UA_Session_updateLifetime(UA_Session *session);
2822
2823/**
2824 * Subscription handling
2825 * --------------------- */
2826
2827#ifdef UA_ENABLE_SUBSCRIPTIONS
2828
2829void
2830UA_Session_attachSubscription(UA_Session *session, UA_Subscription *sub);
2831
2832/* If releasePublishResponses is true and the last subscription is removed, all
2833 * outstanding PublishResponse are sent with a StatusCode. But we don't do that
2834 * if a Subscription is only detached for modification. */
2835void
2836UA_Session_detachSubscription(UA_Server *server, UA_Session *session,
2837 UA_Subscription *sub, UA_Boolean releasePublishResponses);
2838
2839UA_Subscription *
2840UA_Session_getSubscriptionById(UA_Session *session,
2841 UA_UInt32 subscriptionId);
2842
2843
2844void
2845UA_Session_queuePublishReq(UA_Session *session,
2846 UA_PublishResponseEntry* entry,
2847 UA_Boolean head);
2848
2849UA_PublishResponseEntry *
2850UA_Session_dequeuePublishReq(UA_Session *session);
2851
2852#endif
2853
2854/**
2855 * Log Helper
2856 * ----------
2857 * We have to jump through some hoops to enable the use of format strings
2858 * without arguments since (pedantic) C99 does not allow variadic macros with
2859 * zero arguments. So we add a dummy argument that is not printed (%.0s is
2860 * string of length zero). */
2861
2862#define UA_LOG_SESSION_INTERNAL(LOGGER, LEVEL, SESSION, MSG, ...) \
2863 if(UA_LOGLEVEL <= UA_LOGLEVEL_##LEVEL) { \
2864 int nameLen = (SESSION) ? (int)(SESSION)->sessionName.length : 0; \
2865 const char *nameStr = (SESSION) ? \
2866 (const char*)(SESSION)->sessionName.data : ""; \
2867 unsigned long sockId = ((SESSION) && (SESSION)->header.channel) ? \
2868 (unsigned long)(SESSION)->header.channel->connectionId : 0; \
2869 UA_UInt32 chanId = ((SESSION) && (SESSION)->header.channel) ? \
2870 (SESSION)->header.channel->securityToken.channelId : 0; \
2871 UA_LOG_##LEVEL(LOGGER, UA_LOGCATEGORY_SESSION, \
2872 "TCP %lu\t| SC %" PRIu32 "\t| Session \"%.*s\"\t| " MSG "%.0s", \
2873 sockId, chanId, nameLen, nameStr, __VA_ARGS__); \
2874 }
2875
2876#define UA_LOG_TRACE_SESSION(LOGGER, SESSION, ...) \
2877 UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, TRACE, SESSION, __VA_ARGS__, ""))
2878#define UA_LOG_DEBUG_SESSION(LOGGER, SESSION, ...) \
2879 UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, DEBUG, SESSION, __VA_ARGS__, ""))
2880#define UA_LOG_INFO_SESSION(LOGGER, SESSION, ...) \
2881 UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, INFO, SESSION, __VA_ARGS__, ""))
2882#define UA_LOG_WARNING_SESSION(LOGGER, SESSION, ...) \
2883 UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, WARNING, SESSION, __VA_ARGS__, ""))
2884#define UA_LOG_ERROR_SESSION(LOGGER, SESSION, ...) \
2885 UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, ERROR, SESSION, __VA_ARGS__, ""))
2886#define UA_LOG_FATAL_SESSION(LOGGER, SESSION, ...) \
2887 UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, FATAL, SESSION, __VA_ARGS__, ""))
2888
2889_UA_END_DECLS
2890
2891
2892/**** amalgamated original file "/src/server/ua_subscription.h" ****/
2893
2894/* This Source Code Form is subject to the terms of the Mozilla Public
2895 * License, v. 2.0. If a copy of the MPL was not distributed with this
2896 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
2897 *
2898 * Copyright 2015-2018, 2021-2022 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
2899 * Copyright 2015 (c) Chris Iatrou
2900 * Copyright 2015-2016 (c) Sten Grüner
2901 * Copyright 2015 (c) Oleksiy Vasylyev
2902 * Copyright 2017 (c) Florian Palm
2903 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
2904 * Copyright 2017 (c) Mattias Bornhager
2905 * Copyright 2019 (c) HMS Industrial Networks AB (Author: Jonas Green)
2906 * Copyright 2020 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati)
2907 * Copyright 2021 (c) Fraunhofer IOSB (Author: Andreas Ebner)
2908 * Copyright 2021 (c) Fraunhofer IOSB (Author: Jan Hermes)
2909 */
2910
2911
2912
2913
2914_UA_BEGIN_DECLS
2915
2916#ifdef UA_ENABLE_SUBSCRIPTIONS
2917
2918/* MonitoredItems create Notifications. Subscriptions collect Notifications from
2919 * (several) MonitoredItems and publish them to the client.
2920 *
2921 * Notifications are put into two queues at the same time. One for the
2922 * MonitoredItem that generated the notification. Here we can remove it if the
2923 * space reserved for the MonitoredItem runs full. The second queue is the
2924 * "global" queue for all Notifications generated in a Subscription. For
2925 * publication, the notifications are taken out of the "global" queue in the
2926 * order of their creation. */
2927
2928/*****************/
2929/* Notifications */
2930/*****************/
2931
2932/* Set to the TAILQ_NEXT pointer of a notification, the sentinel that the
2933 * notification was not added to the global queue */
2934#define UA_SUBSCRIPTION_QUEUE_SENTINEL ((UA_Notification*)0x01)
2935
2936typedef struct UA_Notification {
2937 TAILQ_ENTRY(UA_Notification) localEntry; /* Notification list for the MonitoredItem */
2938 TAILQ_ENTRY(UA_Notification) globalEntry; /* Notification list for the Subscription */
2939 UA_MonitoredItem *mon; /* Always set */
2940
2941 /* The event field is used if mon->attributeId is the EventNotifier */
2942 union {
2943 UA_MonitoredItemNotification dataChange;
2944#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
2945 UA_EventFieldList event;
2946#endif
2947 } data;
2948
2949#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
2950 UA_Boolean isOverflowEvent; /* Counted manually */
2951#endif
2952} UA_Notification;
2953
2954/* Initializes and sets the sentinel pointers */
2955UA_Notification * UA_Notification_new(void);
2956
2957/* Notifications are always added to the queue of the MonitoredItem. That queue
2958 * can overflow. If Notifications are reported, they are also added to the
2959 * global queue of the Subscription. There they are picked up by the publishing
2960 * callback.
2961 *
2962 * There are two ways Notifications can be put into the global queue of the
2963 * Subscription: They are added because the MonitoringMode of the MonitoredItem
2964 * is "reporting". Or the MonitoringMode is "sampling" and a link is trigered
2965 * that puts the last Notification into the global queue. */
2966void UA_Notification_enqueueAndTrigger(UA_Server *server,
2967 UA_Notification *n);
2968
2969/* Dequeue and delete the notification */
2970void UA_Notification_delete(UA_Notification *n);
2971
2972/* A NotificationMessage contains an array of notifications.
2973 * Sent NotificationMessages are stored for the republish service. */
2974typedef struct UA_NotificationMessageEntry {
2975 TAILQ_ENTRY(UA_NotificationMessageEntry) listEntry;
2976 UA_NotificationMessage message;
2977} UA_NotificationMessageEntry;
2978
2979/* Queue Definitions */
2980typedef TAILQ_HEAD(NotificationQueue, UA_Notification) NotificationQueue;
2981typedef TAILQ_HEAD(NotificationMessageQueue, UA_NotificationMessageEntry)
2982 NotificationMessageQueue;
2983
2984/*****************/
2985/* MonitoredItem */
2986/*****************/
2987
2988/* The type of sampling for MonitoredItems depends on the sampling interval.
2989 *
2990 * >0: Cyclic callback
2991 * =0: Attached to the node. Sampling is triggered after every "write".
2992 * <0: Attached to the subscription. Triggered just before every "publish". */
2993typedef enum {
2994 UA_MONITOREDITEMSAMPLINGTYPE_NONE = 0,
2995 UA_MONITOREDITEMSAMPLINGTYPE_CYCLIC, /* Cyclic callback */
2996 UA_MONITOREDITEMSAMPLINGTYPE_EVENT, /* Attached to the node. Can be a "write
2997 * event" for DataChange MonitoredItems
2998 * with a zero sampling interval .*/
2999 UA_MONITOREDITEMSAMPLINGTYPE_PUBLISH /* Attached to the subscription */
3000} UA_MonitoredItemSamplingType;
3001
3002struct UA_MonitoredItem {
3003 UA_DelayedCallback delayedFreePointers;
3004 LIST_ENTRY(UA_MonitoredItem) listEntry; /* Linked list in the Subscription */
3005 UA_Subscription *subscription; /* If NULL, then this is a Local MonitoredItem */
3006 UA_UInt32 monitoredItemId;
3007
3008 /* Status and Settings */
3009 UA_ReadValueId itemToMonitor;
3010 UA_MonitoringMode monitoringMode;
3011 UA_TimestampsToReturn timestampsToReturn;
3012 UA_Boolean registered; /* Registered in the server / Subscription */
3013 UA_DateTime triggeredUntil; /* If the MonitoringMode is SAMPLING,
3014 * triggering the MonitoredItem puts the latest
3015 * Notification into the publishing queue (of
3016 * the Subscription). In addition, the first
3017 * new sample is also published (and not just
3018 * sampled) if it occurs within the duration of
3019 * one publishing cycle after the triggering. */
3020
3021 /* If the filter is a UA_DataChangeFilter: The DataChangeFilter always
3022 * contains an absolute deadband definition. Part 8, §6.2 gives the
3023 * following formula to test for percentage deadbands:
3024 *
3025 * DataChange if (absolute value of (last cached value - current value)
3026 * > (deadbandValue/100.0) * ((high–low) of EURange)))
3027 *
3028 * So we can convert from a percentage to an absolute deadband and keep
3029 * the hot code path simple.
3030 *
3031 * TODO: Store the percentage deadband to recompute when the UARange is
3032 * changed at runtime of the MonitoredItem */
3033 UA_MonitoringParameters parameters;
3034
3035 /* Sampling */
3036 UA_MonitoredItemSamplingType samplingType;
3037 union {
3038 UA_UInt64 callbackId;
3039 UA_MonitoredItem *nodeListNext; /* Event-Based: Attached to Node */
3040 LIST_ENTRY(UA_MonitoredItem) subscriptionSampling; /* Linked to publish
3041 * interval */
3042 } sampling;
3043 UA_DataValue lastValue;
3044
3045 /* Triggering Links */
3046 size_t triggeringLinksSize;
3047 UA_UInt32 *triggeringLinks;
3048
3049 /* Notification Queue */
3050 NotificationQueue queue;
3051 size_t queueSize; /* This is the current size. See also the configured
3052 * (maximum) queueSize in the parameters. */
3053 size_t eventOverflows; /* Separate counter for the queue. Can at most double
3054 * the queue size */
3055};
3056
3057void UA_MonitoredItem_init(UA_MonitoredItem *mon);
3058void UA_MonitoredItem_delete(UA_Server *server, UA_MonitoredItem *mon);
3059void UA_MonitoredItem_removeOverflowInfoBits(UA_MonitoredItem *mon);
3060void UA_MonitoredItem_sampleCallback(UA_Server *server, UA_MonitoredItem *mon);
3061void UA_Server_registerMonitoredItem(UA_Server *server, UA_MonitoredItem *mon);
3062
3063/* Register sampling. Either by adding a repeated callback or by adding the
3064 * MonitoredItem to a linked list in the node. */
3065UA_StatusCode
3066UA_MonitoredItem_registerSampling(UA_Server *server, UA_MonitoredItem *mon);
3067
3068void
3069UA_MonitoredItem_unregisterSampling(UA_Server *server, UA_MonitoredItem *mon);
3070
3071UA_StatusCode
3072UA_MonitoredItem_setMonitoringMode(UA_Server *server, UA_MonitoredItem *mon,
3073 UA_MonitoringMode monitoringMode);
3074
3075
3076/* Do not use the value after calling this. It will be moved to mon or freed. */
3077void
3078UA_MonitoredItem_processSampledValue(UA_Server *server, UA_MonitoredItem *mon,
3079 UA_DataValue *value);
3080
3081UA_StatusCode
3082UA_MonitoredItem_removeLink(UA_Subscription *sub, UA_MonitoredItem *mon,
3083 UA_UInt32 linkId);
3084
3085UA_StatusCode
3086UA_MonitoredItem_addLink(UA_Subscription *sub, UA_MonitoredItem *mon,
3087 UA_UInt32 linkId);
3088
3089UA_StatusCode
3090UA_MonitoredItem_createDataChangeNotification(UA_Server *server, UA_MonitoredItem *mon,
3091 const UA_DataValue *value);
3092
3093/* Remove entries until mon->maxQueueSize is reached. Sets infobits for lost
3094 * data if required. */
3095void UA_MonitoredItem_ensureQueueSpace(UA_Server *server, UA_MonitoredItem *mon);
3096
3097/****************/
3098/* Subscription */
3099/****************/
3100
3101/* We use only a subset of the states defined in the standard */
3102typedef enum {
3103 UA_SUBSCRIPTIONSTATE_STOPPED = 0,
3104 UA_SUBSCRIPTIONSTATE_REMOVING,
3105 UA_SUBSCRIPTIONSTATE_ENABLED_NOPUBLISH, /* only keepalive */
3106 UA_SUBSCRIPTIONSTATE_ENABLED
3107} UA_SubscriptionState;
3108
3109/* Subscriptions are managed in a server-wide linked list. If they are attached
3110 * to a Session, then they are additionaly in the per-Session linked-list. A
3111 * subscription is always generated for a Session. But the CloseSession Service
3112 * may keep Subscriptions intact beyond the Session lifetime. They can then be
3113 * re-bound to a new Session with the TransferSubscription Service. */
3114struct UA_Subscription {
3115 UA_DelayedCallback delayedFreePointers;
3116 LIST_ENTRY(UA_Subscription) serverListEntry;
3117 /* Ordered according to the priority byte and round-robin scheduling for
3118 * late subscriptions. See ua_session.h. Only set if session != NULL. */
3119 TAILQ_ENTRY(UA_Subscription) sessionListEntry;
3120 UA_Session *session; /* May be NULL if no session is attached. */
3121 UA_UInt32 subscriptionId;
3122
3123 /* Settings */
3124 UA_UInt32 lifeTimeCount;
3125 UA_UInt32 maxKeepAliveCount;
3126 UA_Double publishingInterval; /* in ms */
3127 UA_UInt32 notificationsPerPublish;
3128 UA_Byte priority;
3129
3130 /* Runtime information */
3131 UA_SubscriptionState state;
3132 UA_Boolean late;
3133 UA_StatusCode statusChange; /* If set, a notification is generated and the
3134 * Subscription is deleted within
3135 * UA_Subscription_publish. */
3136 UA_UInt32 nextSequenceNumber;
3137 UA_UInt32 currentKeepAliveCount;
3138 UA_UInt32 currentLifetimeCount;
3139
3140 /* Publish Callback. Registered if id > 0. */
3141 UA_UInt64 publishCallbackId;
3142
3143 /* Delayed callback to schedule publication of more notifications */
3144 UA_Boolean delayedCallbackRegistered;
3145 UA_DelayedCallback delayedMoreNotifications;
3146
3147 /* MonitoredItems */
3148 UA_UInt32 lastMonitoredItemId; /* increase the identifiers */
3149 LIST_HEAD(, UA_MonitoredItem) monitoredItems;
3150 UA_UInt32 monitoredItemsSize;
3151
3152 /* MonitoredItems that are sampled in every publish callback (with the
3153 * publish interval of the subscription) */
3154 LIST_HEAD(, UA_MonitoredItem) samplingMonitoredItems;
3155
3156 /* Global list of notifications from the MonitoredItems */
3157 TAILQ_HEAD(, UA_Notification) notificationQueue;
3158 UA_UInt32 notificationQueueSize; /* Total queue size */
3159 UA_UInt32 dataChangeNotifications;
3160 UA_UInt32 eventNotifications;
3161
3162 /* Retransmission Queue */
3163 NotificationMessageQueue retransmissionQueue;
3164 size_t retransmissionQueueSize;
3165
3166 /* Statistics for the server diagnostics. The fields are defined according
3167 * to the SubscriptionDiagnosticsDataType (Part 5, §12.15). */
3168#ifdef UA_ENABLE_DIAGNOSTICS
3169 UA_NodeId ns0Id; /* Representation in the Session object */
3170
3171 UA_UInt32 modifyCount;
3172 UA_UInt32 enableCount;
3173 UA_UInt32 disableCount;
3174 UA_UInt32 republishRequestCount;
3175 UA_UInt32 republishMessageCount;
3176 UA_UInt32 transferRequestCount;
3177 UA_UInt32 transferredToAltClientCount;
3178 UA_UInt32 transferredToSameClientCount;
3179 UA_UInt32 publishRequestCount;
3180 UA_UInt32 dataChangeNotificationsCount;
3181 UA_UInt32 eventNotificationsCount;
3182 UA_UInt32 notificationsCount;
3183 UA_UInt32 latePublishRequestCount;
3184 UA_UInt32 discardedMessageCount;
3185 UA_UInt32 monitoringQueueOverflowCount;
3186 UA_UInt32 eventQueueOverFlowCount;
3187#endif
3188};
3189
3190UA_Subscription * UA_Subscription_new(void);
3191
3192void
3193UA_Subscription_delete(UA_Server *server, UA_Subscription *sub);
3194
3195UA_StatusCode
3196Subscription_setState(UA_Server *server, UA_Subscription *sub,
3197 UA_SubscriptionState state);
3198
3199void
3200Subscription_resetLifetime(UA_Subscription *sub);
3201
3202UA_MonitoredItem *
3203UA_Subscription_getMonitoredItem(UA_Subscription *sub,
3204 UA_UInt32 monitoredItemId);
3205
3206void
3207UA_Subscription_publish(UA_Server *server, UA_Subscription *sub);
3208
3209void
3210UA_Subscription_resendData(UA_Server *server, UA_Subscription *sub);
3211
3212UA_StatusCode
3213UA_Subscription_removeRetransmissionMessage(UA_Subscription *sub,
3214 UA_UInt32 sequenceNumber);
3215
3216void
3217UA_Session_ensurePublishQueueSpace(UA_Server *server, UA_Session *session);
3218
3219/* Forward declaration for A&C used in ua_server_internal.h" */
3220struct UA_ConditionSource;
3221typedef struct UA_ConditionSource UA_ConditionSource;
3222
3223/* Event Handling */
3224#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
3225
3226#define UA_EVENTFILTER_MAXELEMENTS 64 /* Max operator elements */
3227#define UA_EVENTFILTER_MAXOPERANDS 64 /* Max operands per operator */
3228#define UA_EVENTFILTER_MAXSELECT 64 /* Max select clauses */
3229
3230UA_StatusCode
3231UA_MonitoredItem_addEvent(UA_Server *server, UA_MonitoredItem *mon,
3232 const UA_NodeId *event);
3233
3234UA_StatusCode
3235generateEventId(UA_ByteString *generatedId);
3236
3237/* Static validation when the filter is registered */
3238UA_StatusCode
3239UA_SimpleAttributeOperandValidation(UA_Server *server,
3240 const UA_SimpleAttributeOperand *sao);
3241
3242/* Static validation when the filter is registered */
3243UA_ContentFilterElementResult
3244UA_ContentFilterElementValidation(UA_Server *server, size_t operatorIndex,
3245 size_t operatorsCount,
3246 const UA_ContentFilterElement *ef);
3247
3248/* Evaluate content filter, exported only for unit testing */
3249UA_StatusCode
3250evaluateWhereClause(UA_Server *server, UA_Session *session, const UA_NodeId *eventNode,
3251 const UA_ContentFilter *contentFilter,
3252 UA_ContentFilterResult *contentFilterResult);
3253
3254#endif
3255
3256/***********/
3257/* Helpers */
3258/***********/
3259
3260/* Setting an integer value within bounds */
3261#define UA_BOUNDEDVALUE_SETWBOUNDS(BOUNDS, SRC, DST) { \
3262 if(SRC > BOUNDS.max) DST = BOUNDS.max; \
3263 else if(SRC < BOUNDS.min) DST = BOUNDS.min; \
3264 else DST = SRC; \
3265 }
3266
3267/* Logging
3268 * See a description of the tricks used in ua_session.h */
3269#define UA_LOG_SUBSCRIPTION_INTERNAL(LOGGER, LEVEL, SUB, MSG, ...) \
3270 do { \
3271 if((SUB) && (SUB)->session) { \
3272 UA_LOG_##LEVEL##_SESSION(LOGGER, (SUB)->session, \
3273 "Subscription %" PRIu32 " | " MSG "%.0s", \
3274 (SUB)->subscriptionId, __VA_ARGS__); \
3275 } else { \
3276 UA_LOG_##LEVEL(LOGGER, UA_LOGCATEGORY_SERVER, \
3277 "Subscription %" PRIu32 " | " MSG "%.0s", \
3278 (SUB) ? (SUB)->subscriptionId : 0, __VA_ARGS__); \
3279 } \
3280 } while(0)
3281
3282#if UA_LOGLEVEL <= 100
3283# define UA_LOG_TRACE_SUBSCRIPTION(LOGGER, SUB, ...) \
3284 UA_MACRO_EXPAND(UA_LOG_SUBSCRIPTION_INTERNAL(LOGGER, TRACE, SUB, __VA_ARGS__, ""))
3285#else
3286# define UA_LOG_TRACE_SUBSCRIPTION(LOGGER, SUB, ...) do {} while(0)
3287#endif
3288
3289#if UA_LOGLEVEL <= 200
3290# define UA_LOG_DEBUG_SUBSCRIPTION(LOGGER, SUB, ...) \
3291 UA_MACRO_EXPAND(UA_LOG_SUBSCRIPTION_INTERNAL(LOGGER, DEBUG, SUB, __VA_ARGS__, ""))
3292#else
3293# define UA_LOG_DEBUG_SUBSCRIPTION(LOGGER, SUB, ...) do {} while(0)
3294#endif
3295
3296#if UA_LOGLEVEL <= 300
3297# define UA_LOG_INFO_SUBSCRIPTION(LOGGER, SUB, ...) \
3298 UA_MACRO_EXPAND(UA_LOG_SUBSCRIPTION_INTERNAL(LOGGER, INFO, SUB, __VA_ARGS__, ""))
3299#else
3300# define UA_LOG_INFO_SUBSCRIPTION(LOGGER, SUB, ...) do {} while(0)
3301#endif
3302
3303#if UA_LOGLEVEL <= 400
3304# define UA_LOG_WARNING_SUBSCRIPTION(LOGGER, SUB, ...) \
3305 UA_MACRO_EXPAND(UA_LOG_SUBSCRIPTION_INTERNAL(LOGGER, WARNING, SUB, __VA_ARGS__, ""))
3306#else
3307# define UA_LOG_WARNING_SUBSCRIPTION(LOGGER, SUB, ...) do {} while(0)
3308#endif
3309
3310#if UA_LOGLEVEL <= 500
3311# define UA_LOG_ERROR_SUBSCRIPTION(LOGGER, SUB, ...) \
3312 UA_MACRO_EXPAND(UA_LOG_SUBSCRIPTION_INTERNAL(LOGGER, ERROR, SUB, __VA_ARGS__, ""))
3313#else
3314# define UA_LOG_ERROR_SUBSCRIPTION(LOGGER, SUB, ...) do {} while(0)
3315#endif
3316
3317#if UA_LOGLEVEL <= 600
3318# define UA_LOG_FATAL_SUBSCRIPTION(LOGGER, SUB, ...) \
3319 UA_MACRO_EXPAND(UA_LOG_SUBSCRIPTION_INTERNAL(LOGGER, FATAL, SUB, __VA_ARGS__, ""))
3320#else
3321# define UA_LOG_FATAL_SUBSCRIPTION(LOGGER, SUB, ...) do {} while(0)
3322#endif
3323
3324#endif /* UA_ENABLE_SUBSCRIPTIONS */
3325
3326_UA_END_DECLS
3327
3328
3329/**** amalgamated original file "/src/pubsub/ua_pubsub_networkmessage.h" ****/
3330
3331/* This Source Code Form is subject to the terms of the Mozilla Public
3332 * License, v. 2.0. If a copy of the MPL was not distributed with this
3333 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
3334 *
3335 * Copyright (c) 2017 - 2018 Fraunhofer IOSB (Author: Tino Bischoff)
3336 * Copyright (c) 2017-2019 Fraunhofer IOSB (Author: Andreas Ebner)
3337 */
3338
3339
3340
3341#ifdef UA_ENABLE_PUBSUB
3342
3343_UA_BEGIN_DECLS
3344
3345#define UA_NETWORKMESSAGE_MAX_NONCE_LENGTH 16
3346
3347/* DataSet Payload Header */
3348typedef struct {
3349 UA_Byte count;
3350 UA_UInt16* dataSetWriterIds;
3351} UA_DataSetPayloadHeader;
3352
3353/* FieldEncoding Enum */
3354typedef enum {
3355 UA_FIELDENCODING_VARIANT = 0,
3356 UA_FIELDENCODING_RAWDATA = 1,
3357 UA_FIELDENCODING_DATAVALUE = 2,
3358 UA_FIELDENCODING_UNKNOWN = 3
3359} UA_FieldEncoding;
3360
3361/* DataSetMessage Type */
3362typedef enum {
3363 UA_DATASETMESSAGE_DATAKEYFRAME = 0,
3364 UA_DATASETMESSAGE_DATADELTAFRAME = 1,
3365 UA_DATASETMESSAGE_EVENT = 2,
3366 UA_DATASETMESSAGE_KEEPALIVE = 3
3367} UA_DataSetMessageType;
3368
3369/* DataSetMessage Header */
3370typedef struct {
3371 UA_Boolean dataSetMessageValid;
3372 UA_FieldEncoding fieldEncoding;
3373 UA_Boolean dataSetMessageSequenceNrEnabled;
3374 UA_Boolean timestampEnabled;
3375 UA_Boolean statusEnabled;
3376 UA_Boolean configVersionMajorVersionEnabled;
3377 UA_Boolean configVersionMinorVersionEnabled;
3378 UA_DataSetMessageType dataSetMessageType;
3379 UA_Boolean picoSecondsIncluded;
3380 UA_UInt16 dataSetMessageSequenceNr;
3381 UA_UtcTime timestamp;
3382 UA_UInt16 picoSeconds;
3383 UA_UInt16 status;
3384 UA_UInt32 configVersionMajorVersion;
3385 UA_UInt32 configVersionMinorVersion;
3386} UA_DataSetMessageHeader;
3387
3388/**
3389 * DataSetMessage
3390 * ^^^^^^^^^^^^^^ */
3391
3392typedef struct {
3393 UA_UInt16 fieldCount;
3394 UA_DataValue* dataSetFields;
3395 UA_ByteString rawFields;
3396 /* Json keys for the dataSetFields: TODO: own dataSetMessageType for json? */
3397 UA_String* fieldNames;
3398 /* This information is for proper en- and decoding needed */
3399 UA_DataSetMetaDataType *dataSetMetaDataType;
3400} UA_DataSetMessage_DataKeyFrameData;
3401
3402typedef struct {
3403 UA_UInt16 fieldIndex;
3404 UA_DataValue fieldValue;
3405} UA_DataSetMessage_DeltaFrameField;
3406
3407typedef struct {
3408 UA_UInt16 fieldCount;
3409 UA_DataSetMessage_DeltaFrameField* deltaFrameFields;
3410} UA_DataSetMessage_DataDeltaFrameData;
3411
3412typedef struct {
3413 UA_DataSetMessageHeader header;
3414 union {
3415 UA_DataSetMessage_DataKeyFrameData keyFrameData;
3416 UA_DataSetMessage_DataDeltaFrameData deltaFrameData;
3417 } data;
3418 size_t configuredSize;
3419} UA_DataSetMessage;
3420
3421typedef struct {
3422 UA_UInt16* sizes;
3423 UA_DataSetMessage* dataSetMessages;
3424} UA_DataSetPayload;
3425
3426typedef enum {
3427 UA_NETWORKMESSAGE_DATASET = 0,
3428 UA_NETWORKMESSAGE_DISCOVERY_REQUEST = 1,
3429 UA_NETWORKMESSAGE_DISCOVERY_RESPONSE = 2
3430} UA_NetworkMessageType;
3431
3432/**
3433 * UA_NetworkMessageGroupHeader
3434 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
3435typedef struct {
3436 UA_Boolean writerGroupIdEnabled;
3437 UA_Boolean groupVersionEnabled;
3438 UA_Boolean networkMessageNumberEnabled;
3439 UA_Boolean sequenceNumberEnabled;
3440 UA_UInt16 writerGroupId;
3441 UA_UInt32 groupVersion; // spec: type "VersionTime"
3442 UA_UInt16 networkMessageNumber;
3443 UA_UInt16 sequenceNumber;
3444} UA_NetworkMessageGroupHeader;
3445
3446/**
3447 * UA_NetworkMessageSecurityHeader
3448 * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
3449typedef struct {
3450 UA_Boolean networkMessageSigned;
3451 UA_Boolean networkMessageEncrypted;
3452 UA_Boolean securityFooterEnabled;
3453 UA_Boolean forceKeyReset;
3454 UA_UInt32 securityTokenId; // spec: IntegerId
3455 UA_Byte messageNonce[UA_NETWORKMESSAGE_MAX_NONCE_LENGTH];
3456 UA_UInt16 messageNonceSize;
3457 UA_UInt16 securityFooterSize;
3458} UA_NetworkMessageSecurityHeader;
3459
3460/**
3461 * UA_NetworkMessage
3462 * ^^^^^^^^^^^^^^^^^ */
3463typedef struct {
3464 UA_Byte version;
3465 UA_Boolean messageIdEnabled;
3466 UA_String messageId; /* For Json NetworkMessage */
3467 UA_Boolean publisherIdEnabled;
3468 UA_Boolean groupHeaderEnabled;
3469 UA_Boolean payloadHeaderEnabled;
3470 UA_Boolean dataSetClassIdEnabled;
3471 UA_Boolean securityEnabled;
3472 UA_Boolean timestampEnabled;
3473 UA_Boolean picosecondsEnabled;
3474 UA_Boolean chunkMessage;
3475 UA_Boolean promotedFieldsEnabled;
3476 UA_NetworkMessageType networkMessageType;
3477 UA_PublisherIdType publisherIdType;
3478 UA_PublisherId publisherId;
3479 UA_Guid dataSetClassId;
3480
3481 UA_NetworkMessageGroupHeader groupHeader;
3482
3483 union {
3484 UA_DataSetPayloadHeader dataSetPayloadHeader;
3485 } payloadHeader;
3486
3487 UA_DateTime timestamp;
3488 UA_UInt16 picoseconds;
3489 UA_UInt16 promotedFieldsSize;
3490 UA_Variant* promotedFields; /* BaseDataType */
3491
3492 UA_NetworkMessageSecurityHeader securityHeader;
3493
3494 union {
3495 UA_DataSetPayload dataSetPayload;
3496 } payload;
3497
3498 UA_ByteString securityFooter;
3499} UA_NetworkMessage;
3500
3501/**********************************************/
3502/* Network Message Offsets */
3503/**********************************************/
3504
3505/* Offsets for buffered messages in the PubSub fast path. */
3506typedef enum {
3507 UA_PUBSUB_OFFSETTYPE_DATASETMESSAGE_SEQUENCENUMBER,
3508 UA_PUBSUB_OFFSETTYPE_NETWORKMESSAGE_SEQUENCENUMBER,
3509 UA_PUBSUB_OFFSETTYPE_NETWORKMESSAGE_FIELDENCDODING,
3510 UA_PUBSUB_OFFSETTYPE_TIMESTAMP_PICOSECONDS,
3511 UA_PUBSUB_OFFSETTYPE_TIMESTAMP, /* source pointer */
3512 UA_PUBSUB_OFFSETTYPE_TIMESTAMP_NOW, /* no source */
3513 UA_PUBSUB_OFFSETTYPE_PAYLOAD_DATAVALUE,
3514 UA_PUBSUB_OFFSETTYPE_PAYLOAD_DATAVALUE_EXTERNAL,
3515 UA_PUBSUB_OFFSETTYPE_PAYLOAD_VARIANT,
3516 UA_PUBSUB_OFFSETTYPE_PAYLOAD_VARIANT_EXTERNAL,
3517 UA_PUBSUB_OFFSETTYPE_PAYLOAD_RAW,
3518 UA_PUBSUB_OFFSETTYPE_PAYLOAD_RAW_EXTERNAL,
3519 /* For subscriber RT */
3520 UA_PUBSUB_OFFSETTYPE_PUBLISHERID,
3521 UA_PUBSUB_OFFSETTYPE_WRITERGROUPID,
3522 UA_PUBSUB_OFFSETTYPE_DATASETWRITERID
3523 /* Add more offset types as needed */
3524} UA_NetworkMessageOffsetType;
3525
3526typedef struct {
3527 UA_NetworkMessageOffsetType contentType;
3528 union {
3529 UA_UInt16 sequenceNumber;
3530 UA_DataValue **externalValue;
3531 UA_DataValue value;
3532 } content;
3533 size_t offset;
3534} UA_NetworkMessageOffset;
3535
3536typedef struct {
3537 UA_ByteString buffer; /* The precomputed message buffer */
3538 UA_NetworkMessageOffset *offsets; /* Offsets for changes in the message buffer */
3539 size_t offsetsSize;
3540 UA_NetworkMessage *nm; /* The precomputed NetworkMessage for subscriber */
3541 size_t rawMessageLength;
3542#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
3543 UA_ByteString encryptBuffer; /* The precomputed message buffer is copied
3544 * into the encrypt buffer for encryption and
3545 * signing*/
3546 UA_Byte *payloadPosition; /* Payload Position of the message to encrypt*/
3547#endif
3548} UA_NetworkMessageOffsetBuffer;
3549
3550void
3551UA_NetworkMessageOffsetBuffer_clear(UA_NetworkMessageOffsetBuffer *nmob);
3552
3553UA_StatusCode
3554UA_NetworkMessage_updateBufferedMessage(UA_NetworkMessageOffsetBuffer *buffer);
3555
3556UA_StatusCode
3557UA_NetworkMessage_updateBufferedNwMessage(UA_NetworkMessageOffsetBuffer *buffer,
3558 const UA_ByteString *src, size_t *bufferPosition);
3559
3560/**
3561 * DataSetMessage
3562 * ^^^^^^^^^^^^^^ */
3563
3564UA_StatusCode
3565UA_DataSetMessageHeader_encodeBinary(const UA_DataSetMessageHeader* src,
3566 UA_Byte **bufPos, const UA_Byte *bufEnd);
3567
3568UA_StatusCode
3569UA_DataSetMessageHeader_decodeBinary(const UA_ByteString *src, size_t *offset,
3570 UA_DataSetMessageHeader* dst);
3571
3572UA_StatusCode
3573UA_DataSetMessage_encodeBinary(const UA_DataSetMessage* src, UA_Byte **bufPos,
3574 const UA_Byte *bufEnd);
3575
3576UA_StatusCode
3577UA_DataSetMessage_decodeBinary(const UA_ByteString *src, size_t *offset,
3578 UA_DataSetMessage* dst, UA_UInt16 dsmSize,
3579 const UA_DataTypeArray *customTypes,
3580 UA_DataSetMetaDataType *dsm);
3581
3582size_t
3583UA_DataSetMessage_calcSizeBinary(UA_DataSetMessage *p,
3584 UA_NetworkMessageOffsetBuffer *offsetBuffer,
3585 size_t currentOffset);
3586
3587void UA_DataSetMessage_clear(UA_DataSetMessage* p);
3588
3589/**
3590 * NetworkMessage Encoding
3591 * ^^^^^^^^^^^^^^^^^^^^^^^ */
3592
3593/* If dataToEncryptStart not-NULL, then it will be set to the start-position of
3594 * the payload in the buffer. */
3595UA_StatusCode
3596UA_NetworkMessage_encodeBinary(const UA_NetworkMessage* src,
3597 UA_Byte **bufPos, const UA_Byte *bufEnd,
3598 UA_Byte **dataToEncryptStart);
3599
3600UA_StatusCode
3601UA_NetworkMessage_encodeHeaders(const UA_NetworkMessage* src,
3602 UA_Byte **bufPos, const UA_Byte *bufEnd);
3603
3604UA_StatusCode
3605UA_NetworkMessage_encodePayload(const UA_NetworkMessage* src,
3606 UA_Byte **bufPos, const UA_Byte *bufEnd);
3607
3608UA_StatusCode
3609UA_NetworkMessage_encodeFooters(const UA_NetworkMessage* src,
3610 UA_Byte **bufPos, const UA_Byte *bufEnd);
3611
3612/**
3613 * NetworkMessage Decoding
3614 * ^^^^^^^^^^^^^^^^^^^^^^^ */
3615
3616UA_StatusCode
3617UA_NetworkMessage_decodeHeaders(const UA_ByteString *src, size_t *offset,
3618 UA_NetworkMessage *dst);
3619
3620UA_StatusCode
3621UA_NetworkMessage_decodePayload(const UA_ByteString *src, size_t *offset,
3622 UA_NetworkMessage *dst, const UA_DataTypeArray *customTypes,
3623 UA_DataSetMetaDataType *dsm);
3624
3625UA_StatusCode
3626UA_NetworkMessage_decodeFooters(const UA_ByteString *src, size_t *offset,
3627 UA_NetworkMessage *dst);
3628
3629UA_StatusCode
3630UA_NetworkMessage_decodeBinary(const UA_ByteString *src, size_t *offset,
3631 UA_NetworkMessage* dst, const UA_DataTypeArray *customTypes);
3632
3633UA_StatusCode
3634UA_NetworkMessageHeader_decodeBinary(const UA_ByteString *src, size_t *offset,
3635 UA_NetworkMessage *dst);
3636
3637/* Also stores the offset if offsetBuffer != NULL */
3638size_t
3639UA_NetworkMessage_calcSizeBinary(UA_NetworkMessage *p,
3640 UA_NetworkMessageOffsetBuffer *offsetBuffer);
3641
3642#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
3643
3644UA_StatusCode
3645UA_NetworkMessage_signEncrypt(UA_NetworkMessage *nm, UA_MessageSecurityMode securityMode,
3646 UA_PubSubSecurityPolicy *policy, void *policyContext,
3647 UA_Byte *messageStart, UA_Byte *encryptStart,
3648 UA_Byte *sigStart);
3649#endif
3650
3651void
3652UA_NetworkMessage_clear(UA_NetworkMessage* p);
3653
3654#ifdef UA_ENABLE_JSON_ENCODING
3655UA_StatusCode
3656UA_NetworkMessage_encodeJson(const UA_NetworkMessage *src,
3657 UA_Byte **bufPos, const UA_Byte **bufEnd, UA_String *namespaces,
3658 size_t namespaceSize, UA_String *serverUris,
3659 size_t serverUriSize, UA_Boolean useReversible);
3660
3661size_t
3662UA_NetworkMessage_calcSizeJson(const UA_NetworkMessage *src,
3663 UA_String *namespaces, size_t namespaceSize,
3664 UA_String *serverUris, size_t serverUriSize,
3665 UA_Boolean useReversible);
3666
3667UA_StatusCode UA_NetworkMessage_decodeJson(UA_NetworkMessage *dst, const UA_ByteString *src);
3668#endif
3669
3670_UA_END_DECLS
3671
3672#endif /* UA_ENABLE_PUBSUB */
3673
3674
3675/**** amalgamated original file "/src/pubsub/ua_pubsub.h" ****/
3676
3677/* This Source Code Form is subject to the terms of the Mozilla Public
3678 * License, v. 2.0. If a copy of the MPL was not distributed with this
3679 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
3680 *
3681 * Copyright (c) 2017-2019 Fraunhofer IOSB (Author: Andreas Ebner)
3682 * Copyright (c) 2019 Kalycito Infotech Private Limited
3683 * Copyright (c) 2020 Yannick Wallerer, Siemens AG
3684 * Copyright (c) 2020, 2022 Thomas Fischer, Siemens AG
3685 * Copyright (c) 2021 Fraunhofer IOSB (Author: Jan Hermes)
3686 * Copyright (c) 2022 Siemens AG (Author: Thomas Fischer)
3687 * Copyright (c) 2022 Fraunhofer IOSB (Author: Noel Graf)
3688 * Copyright (c) 2022 Linutronix GmbH (Author: Muddasir Shakil)
3689 */
3690
3691
3692#define UA_INTERNAL
3693
3694
3695#ifdef UA_ENABLE_PUBSUB_SKS
3696#endif
3697
3698_UA_BEGIN_DECLS
3699
3700#ifdef UA_ENABLE_PUBSUB
3701
3702/* Max number of underlying for sending and receiving */
3703#define UA_PUBSUB_MAXCHANNELS 8
3704
3705struct UA_WriterGroup;
3706typedef struct UA_WriterGroup UA_WriterGroup;
3707
3708struct UA_ReaderGroup;
3709typedef struct UA_ReaderGroup UA_ReaderGroup;
3710
3711struct UA_SecurityGroup;
3712typedef struct UA_SecurityGroup UA_SecurityGroup;
3713
3714/**********************************************/
3715/* PublishedDataSet */
3716/**********************************************/
3717
3718typedef struct UA_PublishedDataSet {
3719 UA_PublishedDataSetConfig config;
3720 UA_DataSetMetaDataType dataSetMetaData;
3721 TAILQ_HEAD(, UA_DataSetField) fields;
3722 UA_UInt16 fieldSize;
3723 UA_NodeId identifier;
3724 UA_UInt16 promotedFieldsCount;
3725 UA_UInt16 configurationFreezeCounter;
3726 TAILQ_ENTRY(UA_PublishedDataSet) listEntry;
3727} UA_PublishedDataSet;
3728
3729UA_StatusCode
3730UA_PublishedDataSetConfig_copy(const UA_PublishedDataSetConfig *src,
3731 UA_PublishedDataSetConfig *dst);
3732
3733UA_PublishedDataSet *
3734UA_PublishedDataSet_findPDSbyId(UA_Server *server, UA_NodeId identifier);
3735
3736UA_PublishedDataSet *
3737UA_PublishedDataSet_findPDSbyName(UA_Server *server, UA_String name);
3738
3739UA_AddPublishedDataSetResult
3740UA_PublishedDataSet_create(UA_Server *server,
3741 const UA_PublishedDataSetConfig *publishedDataSetConfig,
3742 UA_NodeId *pdsIdentifier);
3743
3744void
3745UA_PublishedDataSet_clear(UA_Server *server,
3746 UA_PublishedDataSet *publishedDataSet);
3747
3748UA_StatusCode
3749UA_PublishedDataSet_remove(UA_Server *server, UA_PublishedDataSet *publishedDataSet);
3750
3751UA_StatusCode
3752getPublishedDataSetConfig(UA_Server *server, const UA_NodeId pds,
3753 UA_PublishedDataSetConfig *config);
3754
3755typedef struct UA_StandaloneSubscribedDataSet{
3756 UA_StandaloneSubscribedDataSetConfig config;
3757 UA_NodeId identifier;
3758 TAILQ_ENTRY(UA_StandaloneSubscribedDataSet) listEntry;
3759 UA_NodeId connectedReader;
3760} UA_StandaloneSubscribedDataSet;
3761
3762UA_StatusCode
3763UA_StandaloneSubscribedDataSetConfig_copy(const UA_StandaloneSubscribedDataSetConfig *src,
3764 UA_StandaloneSubscribedDataSetConfig *dst);
3765UA_StandaloneSubscribedDataSet *
3766UA_StandaloneSubscribedDataSet_findSDSbyId(UA_Server *server, UA_NodeId identifier);
3767UA_StandaloneSubscribedDataSet *
3768UA_StandaloneSubscribedDataSet_findSDSbyName(UA_Server *server, UA_String identifier);
3769void
3770UA_StandaloneSubscribedDataSet_clear(UA_Server *server,
3771 UA_StandaloneSubscribedDataSet *subscribedDataSet);
3772
3773#define UA_LOG_PDS_INTERNAL(LOGGER, LEVEL, PDS, MSG, ...) \
3774 if(UA_LOGLEVEL <= UA_LOGLEVEL_##LEVEL) { \
3775 UA_String idStr = UA_STRING_NULL; \
3776 if(PDS) \
3777 UA_NodeId_print(&(PDS)->identifier, &idStr); \
3778 UA_LOG_##LEVEL(LOGGER, UA_LOGCATEGORY_PUBSUB, \
3779 "DataSet %.*s\t| " MSG "%.0s", (int)idStr.length, \
3780 (char*)idStr.data, __VA_ARGS__); \
3781 UA_String_clear(&idStr); \
3782 }
3783
3784#define UA_LOG_TRACE_DATASET(LOGGER, PDS, ...) \
3785 UA_MACRO_EXPAND(UA_LOG_PDS_INTERNAL(LOGGER, TRACE, PDS, __VA_ARGS__, ""))
3786#define UA_LOG_DEBUG_DATASET(LOGGER, PDS, ...) \
3787 UA_MACRO_EXPAND(UA_LOG_PDS_INTERNAL(LOGGER, DEBUG, PDS, __VA_ARGS__, ""))
3788#define UA_LOG_INFO_DATASET(LOGGER, PDS, ...) \
3789 UA_MACRO_EXPAND(UA_LOG_PDS_INTERNAL(LOGGER, INFO, PDS, __VA_ARGS__, ""))
3790#define UA_LOG_WARNING_DATASET(LOGGER, PDS, ...) \
3791 UA_MACRO_EXPAND(UA_LOG_PDS_INTERNAL(LOGGER, WARNING, PDS, __VA_ARGS__, ""))
3792#define UA_LOG_ERROR_DATASET(LOGGER, PDS, ...) \
3793 UA_MACRO_EXPAND(UA_LOG_PDS_INTERNAL(LOGGER, ERROR, PDS, __VA_ARGS__, ""))
3794#define UA_LOG_FATAL_DATASET(LOGGER, PDS, ...) \
3795 UA_MACRO_EXPAND(UA_LOG_PDS_INTERNAL(LOGGER, FATAL, PDS, __VA_ARGS__, ""))
3796
3797/**********************************************/
3798/* Connection */
3799/**********************************************/
3800
3801typedef struct UA_PubSubConnection {
3802 UA_PubSubComponentEnumType componentType;
3803
3804 TAILQ_ENTRY(UA_PubSubConnection) listEntry;
3805 UA_NodeId identifier;
3806
3807 /* The send/recv connections are only opened if the state is operational */
3808 UA_PubSubState state;
3809 UA_PubSubConnectionConfig config;
3810 UA_Boolean json; /* Extracted from the TransportProfileUrl */
3811
3812 /* Channels belonging to the PubSubConnection. Send channels belong to
3813 * WriterGroups, recv channels belong to ReaderGroups. We only open channels
3814 * if there is at least one WriterGroup/ReaderGroup respectively.
3815 *
3816 * Some channels belong exclusively to just one WriterGroup/ReaderGroup that
3817 * defines additional connection properties. For example an MQTT topic name
3818 * or QoS parameters. In that case a dedicated NetworkCallback is used that
3819 * takes this ReaderGroup/WriterGroup directly as context. */
3820 UA_ConnectionManager *cm;
3821 uintptr_t recvChannels[UA_PUBSUB_MAXCHANNELS];
3822 size_t recvChannelsSize;
3823 uintptr_t sendChannel;
3824
3825 size_t writerGroupsSize;
3826 LIST_HEAD(, UA_WriterGroup) writerGroups;
3827
3828 size_t readerGroupsSize;
3829 LIST_HEAD(, UA_ReaderGroup) readerGroups;
3830
3831 UA_UInt16 configurationFreezeCounter;
3832
3833 UA_DateTime silenceErrorUntil; /* Avoid generating too many logs */
3834
3835 UA_Boolean deleteFlag; /* To be deleted - in addition to the PubSubState */
3836 UA_DelayedCallback dc; /* For delayed freeing */
3837} UA_PubSubConnection;
3838
3839UA_StatusCode
3840UA_PubSubConnectionConfig_copy(const UA_PubSubConnectionConfig *src,
3841 UA_PubSubConnectionConfig *dst);
3842
3843UA_PubSubConnection *
3844UA_PubSubConnection_findConnectionbyId(UA_Server *server,
3845 UA_NodeId connectionIdentifier);
3846
3847UA_StatusCode
3848UA_PubSubConnection_create(UA_Server *server,
3849 const UA_PubSubConnectionConfig *connectionConfig,
3850 UA_NodeId *connectionIdentifier);
3851
3852void
3853UA_PubSubConnectionConfig_clear(UA_PubSubConnectionConfig *connectionConfig);
3854
3855void
3856UA_PubSubConnection_delete(UA_Server *server, UA_PubSubConnection *c);
3857
3858UA_StatusCode
3859UA_PubSubConnection_connect(UA_Server *server, UA_PubSubConnection *c,
3860 UA_Boolean validate);
3861
3862void
3863UA_PubSubConnection_disconnect(UA_PubSubConnection *c);
3864
3865/* Returns either the eventloop configured in the connection or, in its absence,
3866 * for the server */
3867UA_EventLoop *
3868UA_PubSubConnection_getEL(UA_Server *server, UA_PubSubConnection *c);
3869
3870UA_StatusCode
3871UA_PubSubConnection_setPubSubState(UA_Server *server,
3872 UA_PubSubConnection *connection,
3873 UA_PubSubState state,
3874 UA_StatusCode cause);
3875
3876#define UA_LOG_CONNECTION_INTERNAL(LOGGER, LEVEL, CONNECTION, MSG, ...) \
3877 if(UA_LOGLEVEL <= UA_LOGLEVEL_##LEVEL) { \
3878 UA_String idStr = UA_STRING_NULL; \
3879 if(CONNECTION) \
3880 UA_NodeId_print(&(CONNECTION)->identifier, &idStr); \
3881 UA_LOG_##LEVEL(LOGGER, UA_LOGCATEGORY_PUBSUB, \
3882 "Connection %.*s\t| " MSG "%.0s", (int)idStr.length, \
3883 (char*)idStr.data, __VA_ARGS__); \
3884 UA_String_clear(&idStr); \
3885 }
3886
3887#define UA_LOG_TRACE_CONNECTION(LOGGER, CONNECTION, ...) \
3888 UA_MACRO_EXPAND(UA_LOG_CONNECTION_INTERNAL(LOGGER, TRACE, CONNECTION, __VA_ARGS__, ""))
3889#define UA_LOG_DEBUG_CONNECTION(LOGGER, CONNECTION, ...) \
3890 UA_MACRO_EXPAND(UA_LOG_CONNECTION_INTERNAL(LOGGER, DEBUG, CONNECTION, __VA_ARGS__, ""))
3891#define UA_LOG_INFO_CONNECTION(LOGGER, CONNECTION, ...) \
3892 UA_MACRO_EXPAND(UA_LOG_CONNECTION_INTERNAL(LOGGER, INFO, CONNECTION, __VA_ARGS__, ""))
3893#define UA_LOG_WARNING_CONNECTION(LOGGER, CONNECTION, ...) \
3894 UA_MACRO_EXPAND(UA_LOG_CONNECTION_INTERNAL(LOGGER, WARNING, CONNECTION, __VA_ARGS__, ""))
3895#define UA_LOG_ERROR_CONNECTION(LOGGER, CONNECTION, ...) \
3896 UA_MACRO_EXPAND(UA_LOG_CONNECTION_INTERNAL(LOGGER, ERROR, CONNECTION, __VA_ARGS__, ""))
3897#define UA_LOG_FATAL_CONNECTION(LOGGER, CONNECTION, ...) \
3898 UA_MACRO_EXPAND(UA_LOG_CONNECTION_INTERNAL(LOGGER, FATAL, CONNECTION, __VA_ARGS__, ""))
3899
3900/**********************************************/
3901/* DataSetWriter */
3902/**********************************************/
3903
3904typedef struct UA_DataSetWriterSample {
3905 UA_Boolean valueChanged;
3906 UA_DataValue value;
3907} UA_DataSetWriterSample;
3908
3909typedef struct UA_DataSetWriter {
3910 UA_PubSubComponentEnumType componentType;
3911 UA_DataSetWriterConfig config;
3912 LIST_ENTRY(UA_DataSetWriter) listEntry;
3913 UA_NodeId identifier;
3914 UA_NodeId linkedWriterGroup;
3915 UA_NodeId connectedDataSet;
3916 UA_ConfigurationVersionDataType connectedDataSetVersion;
3917 UA_PubSubState state;
3918
3919 /* Deltaframes */
3920 UA_UInt16 deltaFrameCounter; /* count of sent deltaFrames */
3921 size_t lastSamplesCount;
3922 UA_DataSetWriterSample *lastSamples;
3923
3924 UA_UInt16 actualDataSetMessageSequenceCount;
3925 UA_Boolean configurationFrozen;
3926} UA_DataSetWriter;
3927
3928UA_StatusCode
3929UA_DataSetWriterConfig_copy(const UA_DataSetWriterConfig *src,
3930 UA_DataSetWriterConfig *dst);
3931
3932UA_DataSetWriter *
3933UA_DataSetWriter_findDSWbyId(UA_Server *server, UA_NodeId identifier);
3934
3935UA_StatusCode
3936UA_DataSetWriter_setPubSubState(UA_Server *server,
3937 UA_DataSetWriter *dataSetWriter,
3938 UA_PubSubState state,
3939 UA_StatusCode cause);
3940
3941UA_StatusCode
3942UA_DataSetWriter_generateDataSetMessage(UA_Server *server,
3943 UA_DataSetMessage *dataSetMessage,
3944 UA_DataSetWriter *dataSetWriter);
3945
3946UA_StatusCode
3947UA_DataSetWriter_prepareDataSet(UA_Server *server, UA_DataSetWriter *dsw,
3948 UA_DataSetMessage *dsm);
3949
3950void
3951UA_DataSetWriter_freezeConfiguration(UA_Server *server, UA_DataSetWriter *dsw);
3952
3953void
3954UA_DataSetWriter_unfreezeConfiguration(UA_Server *server, UA_DataSetWriter *dsw);
3955
3956UA_StatusCode
3957UA_DataSetWriter_create(UA_Server *server,
3958 const UA_NodeId writerGroup, const UA_NodeId dataSet,
3959 const UA_DataSetWriterConfig *dataSetWriterConfig,
3960 UA_NodeId *writerIdentifier);
3961
3962
3963UA_StatusCode
3964UA_DataSetWriter_remove(UA_Server *server, UA_DataSetWriter *dataSetWriter);
3965
3966#define UA_LOG_WRITER_INTERNAL(LOGGER, LEVEL, WRITER, MSG, ...) \
3967 if(UA_LOGLEVEL <= UA_LOGLEVEL_##LEVEL) { \
3968 UA_String idStr = UA_STRING_NULL; \
3969 UA_String groupIdStr = UA_STRING_NULL; \
3970 if(WRITER) { \
3971 UA_NodeId_print(&(WRITER)->identifier, &idStr); \
3972 UA_NodeId_print(&(WRITER)->linkedWriterGroup, &groupIdStr); \
3973 } \
3974 UA_LOG_##LEVEL(LOGGER, UA_LOGCATEGORY_PUBSUB, \
3975 "WriterGroup %.*s\t| Writer %.*s\t| " MSG "%.0s", \
3976 (int)groupIdStr.length, (char*)groupIdStr.data, \
3977 (int)idStr.length, (char*)idStr.data, \
3978 __VA_ARGS__); \
3979 UA_String_clear(&idStr); \
3980 UA_String_clear(&groupIdStr); \
3981 }
3982
3983#define UA_LOG_TRACE_WRITER(LOGGER, WRITER, ...) \
3984 UA_MACRO_EXPAND(UA_LOG_WRITER_INTERNAL(LOGGER, TRACE, WRITER, __VA_ARGS__, ""))
3985#define UA_LOG_DEBUG_WRITER(LOGGER, WRITER, ...) \
3986 UA_MACRO_EXPAND(UA_LOG_WRITER_INTERNAL(LOGGER, DEBUG, WRITER, __VA_ARGS__, ""))
3987#define UA_LOG_INFO_WRITER(LOGGER, WRITER, ...) \
3988 UA_MACRO_EXPAND(UA_LOG_WRITER_INTERNAL(LOGGER, INFO, WRITER, __VA_ARGS__, ""))
3989#define UA_LOG_WARNING_WRITER(LOGGER, WRITER, ...) \
3990 UA_MACRO_EXPAND(UA_LOG_WRITER_INTERNAL(LOGGER, WARNING, WRITER, __VA_ARGS__, ""))
3991#define UA_LOG_ERROR_WRITER(LOGGER, WRITER, ...) \
3992 UA_MACRO_EXPAND(UA_LOG_WRITER_INTERNAL(LOGGER, ERROR, WRITER, __VA_ARGS__, ""))
3993#define UA_LOG_FATAL_WRITER(LOGGER, WRITER, ...) \
3994 UA_MACRO_EXPAND(UA_LOG_WRITER_INTERNAL(LOGGER, FATAL, WRITER, __VA_ARGS__, ""))
3995
3996/**********************************************/
3997/* WriterGroup */
3998/**********************************************/
3999
4000struct UA_WriterGroup {
4001 UA_PubSubComponentEnumType componentType;
4002 UA_WriterGroupConfig config;
4003 LIST_ENTRY(UA_WriterGroup) listEntry;
4004 UA_NodeId identifier;
4005
4006 LIST_HEAD(, UA_DataSetWriter) writers;
4007 UA_UInt32 writersCount;
4008
4009 UA_UInt64 publishCallbackId; /* registered if != 0 */
4010 UA_PubSubState state;
4011 UA_NetworkMessageOffsetBuffer bufferedMessage;
4012 UA_UInt16 sequenceNumber; /* Increased after every succressuly sent message */
4013 UA_Boolean configurationFrozen;
4014 UA_DateTime lastPublishTimeStamp;
4015
4016 /* The ConnectionManager pointer is stored in the Connection. The channels
4017 * are either stored here or in the Connection, but never both. */
4018 UA_PubSubConnection *linkedConnection;
4019 uintptr_t sendChannel;
4020 UA_Boolean deleteFlag;
4021
4022#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
4023 UA_UInt32 securityTokenId;
4024 UA_UInt32 nonceSequenceNumber; /* To be part of the MessageNonce */
4025 void *securityPolicyContext;
4026#ifdef UA_ENABLE_PUBSUB_SKS
4027 UA_PubSubKeyStorage *keyStorage; /* non-owning pointer to keyStorage*/
4028#endif
4029#endif
4030};
4031
4032UA_StatusCode
4033UA_WriterGroup_create(UA_Server *server, const UA_NodeId connection,
4034 const UA_WriterGroupConfig *writerGroupConfig,
4035 UA_NodeId *writerGroupIdentifier);
4036
4037UA_StatusCode
4038UA_WriterGroup_remove(UA_Server *server, UA_WriterGroup *wg);
4039
4040void
4041UA_WriterGroup_disconnect(UA_WriterGroup *wg);
4042
4043UA_StatusCode
4044UA_WriterGroup_connect(UA_Server *server, UA_WriterGroup *wg,
4045 UA_Boolean validate);
4046
4047UA_StatusCode
4048setWriterGroupEncryptionKeys(UA_Server *server, const UA_NodeId writerGroup,
4049 UA_UInt32 securityTokenId,
4050 const UA_ByteString signingKey,
4051 const UA_ByteString encryptingKey,
4052 const UA_ByteString keyNonce);
4053
4054UA_StatusCode
4055UA_WriterGroupConfig_copy(const UA_WriterGroupConfig *src,
4056 UA_WriterGroupConfig *dst);
4057
4058UA_WriterGroup *
4059UA_WriterGroup_findWGbyId(UA_Server *server, UA_NodeId identifier);
4060
4061UA_StatusCode
4062UA_WriterGroup_freezeConfiguration(UA_Server *server, UA_WriterGroup *wg);
4063
4064UA_StatusCode
4065UA_WriterGroup_unfreezeConfiguration(UA_Server *server, UA_WriterGroup *wg);
4066
4067UA_StatusCode
4068UA_WriterGroup_setPubSubState(UA_Server *server,
4069 UA_WriterGroup *writerGroup,
4070 UA_PubSubState state,
4071 UA_StatusCode cause);
4072
4073UA_StatusCode
4074UA_WriterGroup_addPublishCallback(UA_Server *server, UA_WriterGroup *writerGroup);
4075
4076void
4077UA_WriterGroup_publishCallback(UA_Server *server,
4078 UA_WriterGroup *writerGroup);
4079
4080UA_StatusCode
4081UA_WriterGroup_updateConfig(UA_Server *server, UA_WriterGroup *wg,
4082 const UA_WriterGroupConfig *config);
4083
4084#define UA_LOG_WRITERGROUP_INTERNAL(LOGGER, LEVEL, WRITERGROUP, MSG, ...) \
4085 if(UA_LOGLEVEL <= UA_LOGLEVEL_##LEVEL) { \
4086 UA_String idStr = UA_STRING_NULL; \
4087 if(WRITERGROUP) \
4088 UA_NodeId_print(&(WRITERGROUP)->identifier, &idStr); \
4089 UA_LOG_##LEVEL(LOGGER, UA_LOGCATEGORY_PUBSUB, \
4090 "WriterGroup %.*s\t| " MSG "%.0s", \
4091 (int)idStr.length, (char*)idStr.data, \
4092 __VA_ARGS__); \
4093 UA_String_clear(&idStr); \
4094 }
4095
4096#define UA_LOG_TRACE_WRITERGROUP(LOGGER, WRITERGROUP, ...) \
4097 UA_MACRO_EXPAND(UA_LOG_WRITERGROUP_INTERNAL(LOGGER, TRACE, WRITERGROUP, __VA_ARGS__, ""))
4098#define UA_LOG_DEBUG_WRITERGROUP(LOGGER, WRITERGROUP, ...) \
4099 UA_MACRO_EXPAND(UA_LOG_WRITERGROUP_INTERNAL(LOGGER, DEBUG, WRITERGROUP, __VA_ARGS__, ""))
4100#define UA_LOG_INFO_WRITERGROUP(LOGGER, WRITERGROUP, ...) \
4101 UA_MACRO_EXPAND(UA_LOG_WRITERGROUP_INTERNAL(LOGGER, INFO, WRITERGROUP, __VA_ARGS__, ""))
4102#define UA_LOG_WARNING_WRITERGROUP(LOGGER, WRITERGROUP, ...) \
4103 UA_MACRO_EXPAND(UA_LOG_WRITERGROUP_INTERNAL(LOGGER, WARNING, WRITERGROUP, __VA_ARGS__, ""))
4104#define UA_LOG_ERROR_WRITERGROUP(LOGGER, WRITERGROUP, ...) \
4105 UA_MACRO_EXPAND(UA_LOG_WRITERGROUP_INTERNAL(LOGGER, ERROR, WRITERGROUP, __VA_ARGS__, ""))
4106#define UA_LOG_FATAL_WRITERGROUP(LOGGER, WRITERGROUP, ...) \
4107 UA_MACRO_EXPAND(UA_LOG_WRITERGROUP_INTERNAL(LOGGER, FATAL, WRITERGROUP, __VA_ARGS__, ""))
4108
4109/**********************************************/
4110/* DataSetField */
4111/**********************************************/
4112
4113typedef struct UA_DataSetField {
4114 UA_DataSetFieldConfig config;
4115 TAILQ_ENTRY(UA_DataSetField) listEntry;
4116 UA_NodeId identifier;
4117 UA_NodeId publishedDataSet; /* parent pds */
4118 UA_FieldMetaData fieldMetaData; /* contains the dataSetFieldId */
4119 UA_UInt64 sampleCallbackId;
4120 UA_Boolean sampleCallbackIsRegistered;
4121 UA_Boolean configurationFrozen;
4122} UA_DataSetField;
4123
4124UA_StatusCode
4125UA_DataSetFieldConfig_copy(const UA_DataSetFieldConfig *src,
4126 UA_DataSetFieldConfig *dst);
4127
4128UA_DataSetField *
4129UA_DataSetField_findDSFbyId(UA_Server *server, UA_NodeId identifier);
4130
4131UA_DataSetFieldResult
4132UA_DataSetField_remove(UA_Server *server, UA_DataSetField *currentField);
4133
4134UA_DataSetFieldResult
4135UA_DataSetField_create(UA_Server *server, const UA_NodeId publishedDataSet,
4136 const UA_DataSetFieldConfig *fieldConfig,
4137 UA_NodeId *fieldIdentifier);
4138
4139void
4140UA_PubSubDataSetField_sampleValue(UA_Server *server, UA_DataSetField *field,
4141 UA_DataValue *value);
4142
4143/**********************************************/
4144/* DataSetReader */
4145/**********************************************/
4146
4147/* DataSetReader Type definition */
4148typedef struct UA_DataSetReader {
4149 UA_PubSubComponentEnumType componentType;
4150 UA_DataSetReaderConfig config;
4151 UA_NodeId identifier;
4152 UA_NodeId linkedReaderGroup;
4153 LIST_ENTRY(UA_DataSetReader) listEntry;
4154
4155 UA_PubSubState state; /* non std */
4156 UA_Boolean configurationFrozen;
4157 UA_NetworkMessageOffsetBuffer bufferedMessage;
4158
4159#ifdef UA_ENABLE_PUBSUB_MONITORING
4160 /* MessageReceiveTimeout handling */
4161 UA_ServerCallback msgRcvTimeoutTimerCallback;
4162 UA_UInt64 msgRcvTimeoutTimerId;
4163 UA_Boolean msgRcvTimeoutTimerRunning;
4164#endif
4165 UA_DateTime lastHeartbeatReceived;
4166} UA_DataSetReader;
4167
4168/* Process Network Message using DataSetReader */
4169void
4170UA_DataSetReader_process(UA_Server *server,
4171 UA_ReaderGroup *readerGroup,
4172 UA_DataSetReader *dataSetReader,
4173 UA_DataSetMessage *dataSetMsg);
4174
4175UA_StatusCode
4176UA_DataSetReader_checkIdentifier(UA_Server *server, UA_NetworkMessage *msg,
4177 UA_DataSetReader *reader,
4178 UA_ReaderGroupConfig readerGroupConfig);
4179
4180UA_StatusCode
4181UA_DataSetReader_create(UA_Server *server, UA_NodeId readerGroupIdentifier,
4182 const UA_DataSetReaderConfig *dataSetReaderConfig,
4183 UA_NodeId *readerIdentifier);
4184
4185UA_StatusCode
4186UA_DataSetReader_remove(UA_Server *server, UA_DataSetReader *dsr);
4187
4188/* Copy the configuration of Target Variables */
4189UA_StatusCode UA_TargetVariables_copy(const UA_TargetVariables *src,
4190 UA_TargetVariables *dst);
4191
4192/* Clear the Target Variables configuration */
4193void UA_TargetVariables_clear(UA_TargetVariables *subscribedDataSetTarget);
4194
4195/* Copy the configuration of Field Target Variables */
4196UA_StatusCode UA_FieldTargetVariable_copy(const UA_FieldTargetVariable *src,
4197 UA_FieldTargetVariable *dst);
4198
4199UA_StatusCode
4200DataSetReader_createTargetVariables(UA_Server *server, UA_DataSetReader *dsr,
4201 size_t targetVariablesSize,
4202 const UA_FieldTargetVariable *targetVariables);
4203
4204UA_StatusCode
4205UA_DataSetReader_setPubSubState(UA_Server *server,
4206 UA_DataSetReader *dataSetReader,
4207 UA_PubSubState state,
4208 UA_StatusCode cause);
4209
4210#define UA_LOG_READER_INTERNAL(LOGGER, LEVEL, READER, MSG, ...) \
4211 if(UA_LOGLEVEL <= UA_LOGLEVEL_##LEVEL) { \
4212 UA_String idStr = UA_STRING_NULL; \
4213 UA_String groupIdStr = UA_STRING_NULL; \
4214 if(READER) { \
4215 UA_NodeId_print(&(READER)->identifier, &idStr); \
4216 UA_NodeId_print(&(READER)->linkedReaderGroup, &groupIdStr); \
4217 } \
4218 UA_LOG_##LEVEL(LOGGER, UA_LOGCATEGORY_PUBSUB, \
4219 "ReaderGroup %.*s\t| Reader %.*s\t| " MSG "%.0s", \
4220 (int)groupIdStr.length, (char*)groupIdStr.data, \
4221 (int)idStr.length, (char*)idStr.data, \
4222 __VA_ARGS__); \
4223 UA_String_clear(&idStr); \
4224 UA_String_clear(&groupIdStr); \
4225 }
4226
4227#define UA_LOG_TRACE_READER(LOGGER, READER, ...) \
4228 UA_MACRO_EXPAND(UA_LOG_READER_INTERNAL(LOGGER, TRACE, READER, __VA_ARGS__, ""))
4229#define UA_LOG_DEBUG_READER(LOGGER, READER, ...) \
4230 UA_MACRO_EXPAND(UA_LOG_READER_INTERNAL(LOGGER, DEBUG, READER, __VA_ARGS__, ""))
4231#define UA_LOG_INFO_READER(LOGGER, READER, ...) \
4232 UA_MACRO_EXPAND(UA_LOG_READER_INTERNAL(LOGGER, INFO, READER, __VA_ARGS__, ""))
4233#define UA_LOG_WARNING_READER(LOGGER, READER, ...) \
4234 UA_MACRO_EXPAND(UA_LOG_READER_INTERNAL(LOGGER, WARNING, READER, __VA_ARGS__, ""))
4235#define UA_LOG_ERROR_READER(LOGGER, READER, ...) \
4236 UA_MACRO_EXPAND(UA_LOG_READER_INTERNAL(LOGGER, ERROR, READER, __VA_ARGS__, ""))
4237#define UA_LOG_FATAL_READER(LOGGER, READER, ...) \
4238 UA_MACRO_EXPAND(UA_LOG_READER_INTERNAL(LOGGER, FATAL, READER, __VA_ARGS__, ""))
4239
4240/**********************************************/
4241/* ReaderGroup */
4242/**********************************************/
4243
4244struct UA_ReaderGroup {
4245 UA_PubSubComponentEnumType componentType;
4246 UA_ReaderGroupConfig config;
4247 UA_NodeId identifier;
4248 LIST_ENTRY(UA_ReaderGroup) listEntry;
4249
4250 LIST_HEAD(, UA_DataSetReader) readers;
4251 UA_UInt32 readersCount;
4252
4253 UA_PubSubState state;
4254 UA_Boolean configurationFrozen;
4255
4256 /* The ConnectionManager pointer is stored in the Connection. The channels
4257 * are either stored here or in the Connection, but never both. */
4258 UA_PubSubConnection *linkedConnection;
4259 uintptr_t recvChannels[UA_PUBSUB_MAXCHANNELS];
4260 size_t recvChannelsSize;
4261 UA_Boolean deleteFlag;
4262
4263#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
4264 UA_UInt32 securityTokenId;
4265 UA_UInt32 nonceSequenceNumber; /* To be part of the MessageNonce */
4266 void *securityPolicyContext;
4267#ifdef UA_ENABLE_PUBSUB_SKS
4268 UA_PubSubKeyStorage *keyStorage;
4269#endif
4270#endif
4271};
4272
4273UA_StatusCode
4274UA_ReaderGroup_create(UA_Server *server, UA_NodeId connectionId,
4275 const UA_ReaderGroupConfig *rgc,
4276 UA_NodeId *readerGroupId);
4277
4278UA_StatusCode
4279UA_ReaderGroup_remove(UA_Server *server, UA_ReaderGroup *rg);
4280
4281UA_StatusCode
4282UA_ReaderGroup_connect(UA_Server *server, UA_ReaderGroup *rg, UA_Boolean validate);
4283
4284void
4285UA_ReaderGroup_disconnect(UA_ReaderGroup *rg);
4286
4287UA_StatusCode
4288setReaderGroupEncryptionKeys(UA_Server *server, const UA_NodeId readerGroup,
4289 UA_UInt32 securityTokenId,
4290 const UA_ByteString signingKey,
4291 const UA_ByteString encryptingKey,
4292 const UA_ByteString keyNonce);
4293
4294UA_StatusCode
4295UA_ReaderGroupConfig_copy(const UA_ReaderGroupConfig *src,
4296 UA_ReaderGroupConfig *dst);
4297
4298/* Prototypes for internal util functions - some functions maybe removed later
4299 * (currently moved from public to internal) */
4300UA_ReaderGroup *
4301UA_ReaderGroup_findRGbyId(UA_Server *server, UA_NodeId identifier);
4302
4303UA_DataSetReader *
4304UA_ReaderGroup_findDSRbyId(UA_Server *server, UA_NodeId identifier);
4305
4306UA_StatusCode
4307UA_ReaderGroup_freezeConfiguration(UA_Server *server, UA_ReaderGroup *rg);
4308
4309UA_StatusCode
4310UA_ReaderGroup_unfreezeConfiguration(UA_Server *server, UA_ReaderGroup *rg);
4311
4312UA_StatusCode
4313UA_ReaderGroup_setPubSubState(UA_Server *server,
4314 UA_ReaderGroup *readerGroup,
4315 UA_PubSubState state,
4316 UA_StatusCode cause);
4317
4318UA_Boolean
4319UA_ReaderGroup_decodeAndProcessRT(UA_Server *server, UA_ReaderGroup *readerGroup,
4320 UA_ByteString *buf);
4321
4322UA_Boolean
4323UA_ReaderGroup_process(UA_Server *server, UA_ReaderGroup *readerGroup,
4324 UA_NetworkMessage *nm);
4325
4326#define UA_LOG_READERGROUP_INTERNAL(LOGGER, LEVEL, RG, MSG, ...) \
4327 if(UA_LOGLEVEL <= UA_LOGLEVEL_##LEVEL) { \
4328 UA_String idStr = UA_STRING_NULL; \
4329 if(RG) \
4330 UA_NodeId_print(&(RG)->identifier, &idStr); \
4331 UA_LOG_##LEVEL(LOGGER, UA_LOGCATEGORY_PUBSUB, \
4332 "ReaderGroup %.*s\t| " MSG "%.0s", (int)idStr.length, \
4333 (char*)idStr.data, __VA_ARGS__); \
4334 UA_String_clear(&idStr); \
4335 }
4336
4337#define UA_LOG_TRACE_READERGROUP(LOGGER, READERGROUP, ...) \
4338 UA_MACRO_EXPAND(UA_LOG_READERGROUP_INTERNAL(LOGGER, TRACE, READERGROUP, __VA_ARGS__, ""))
4339#define UA_LOG_DEBUG_READERGROUP(LOGGER, READERGROUP, ...) \
4340 UA_MACRO_EXPAND(UA_LOG_READERGROUP_INTERNAL(LOGGER, DEBUG, READERGROUP, __VA_ARGS__, ""))
4341#define UA_LOG_INFO_READERGROUP(LOGGER, READERGROUP, ...) \
4342 UA_MACRO_EXPAND(UA_LOG_READERGROUP_INTERNAL(LOGGER, INFO, READERGROUP, __VA_ARGS__, ""))
4343#define UA_LOG_WARNING_READERGROUP(LOGGER, READERGROUP, ...) \
4344 UA_MACRO_EXPAND(UA_LOG_READERGROUP_INTERNAL(LOGGER, WARNING, READERGROUP, __VA_ARGS__, ""))
4345#define UA_LOG_ERROR_READERGROUP(LOGGER, READERGROUP, ...) \
4346 UA_MACRO_EXPAND(UA_LOG_READERGROUP_INTERNAL(LOGGER, ERROR, READERGROUP, __VA_ARGS__, ""))
4347#define UA_LOG_FATAL_READERGROUP(LOGGER, READERGROUP, ...) \
4348 UA_MACRO_EXPAND(UA_LOG_READERGROUP_INTERNAL(LOGGER, FATAL, READERGROUP, __VA_ARGS__, ""))
4349
4350/*********************************************************/
4351/* Reading Message handling */
4352/*********************************************************/
4353
4354#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
4355UA_StatusCode
4356verifyAndDecrypt(const UA_Logger *logger, UA_ByteString *buffer,
4357 const size_t *currentPosition, const UA_NetworkMessage *nm,
4358 UA_Boolean doValidate, UA_Boolean doDecrypt,
4359 void *channelContext, UA_PubSubSecurityPolicy *securityPolicy);
4360
4361UA_StatusCode
4362verifyAndDecryptNetworkMessage(const UA_Logger *logger, UA_ByteString *buffer,
4363 size_t *currentPosition, UA_NetworkMessage *nm,
4364 UA_ReaderGroup *readerGroup);
4365#endif
4366
4367/* Takes a value (and not a pointer) to the buffer. The original buffer is
4368 const. Internally we may adjust the length during decryption. */
4369UA_StatusCode
4370decodeNetworkMessage(UA_Server *server, UA_ByteString *buffer, size_t *pos,
4371 UA_NetworkMessage *nm, UA_PubSubConnection *connection);
4372
4373#ifdef UA_ENABLE_PUBSUB_SKS
4374/*********************************************************/
4375/* SecurityGroup */
4376/*********************************************************/
4377struct UA_SecurityGroup {
4378 UA_String securityGroupId;
4379 UA_SecurityGroupConfig config;
4380 UA_PubSubKeyStorage *keyStorage;
4381 UA_NodeId securityGroupNodeId;
4382 UA_UInt64 callbackId;
4383 UA_DateTime baseTime;
4384#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
4385 UA_NodeId securityGroupFolderId;
4386#endif
4387 TAILQ_ENTRY(UA_SecurityGroup) listEntry;
4388};
4389
4390UA_StatusCode
4391UA_SecurityGroupConfig_copy(const UA_SecurityGroupConfig *src,
4392 UA_SecurityGroupConfig *dst);
4393
4394/* finds the SecurityGroup within the server by SecurityGroup Name/Id*/
4395UA_SecurityGroup *
4396UA_SecurityGroup_findSGbyName(UA_Server *server, UA_String securityGroupName);
4397
4398/* finds the SecurityGroup within the server by NodeId*/
4399UA_SecurityGroup *
4400UA_SecurityGroup_findSGbyId(UA_Server *server, UA_NodeId identifier);
4401
4402void
4403UA_SecurityGroup_delete(UA_SecurityGroup *securityGroup);
4404
4405void
4406removeSecurityGroup(UA_Server *server, UA_SecurityGroup *securityGroup);
4407
4408#endif /* UA_ENABLE_PUBSUB_SKS */
4409
4410/******************/
4411/* PubSub Manager */
4412/******************/
4413
4414typedef struct UA_TopicAssign {
4415 UA_ReaderGroup *rgIdentifier;
4416 UA_String topic;
4417 TAILQ_ENTRY(UA_TopicAssign) listEntry;
4418} UA_TopicAssign;
4419
4420typedef enum {
4421 UA_WRITER_GROUP = 0,
4422 UA_DATA_SET_WRITER = 1,
4423} UA_ReserveIdType;
4424
4425typedef struct UA_ReserveId {
4426 UA_UInt16 id;
4427 UA_ReserveIdType reserveIdType;
4428 UA_String transportProfileUri;
4429 UA_NodeId sessionId;
4430 ZIP_ENTRY(UA_ReserveId) treeEntry;
4431} UA_ReserveId;
4432
4433typedef ZIP_HEAD(UA_ReserveIdTree, UA_ReserveId) UA_ReserveIdTree;
4434
4435typedef struct UA_PubSubManager {
4436 UA_UInt64 defaultPublisherId;
4437 /* Connections and PublishedDataSets can exist alone (own lifecycle) -> top
4438 * level components */
4439 size_t connectionsSize;
4440 TAILQ_HEAD(, UA_PubSubConnection) connections;
4441
4442 size_t publishedDataSetsSize;
4443 TAILQ_HEAD(, UA_PublishedDataSet) publishedDataSets;
4444
4445 size_t subscribedDataSetsSize;
4446 TAILQ_HEAD(, UA_StandaloneSubscribedDataSet) subscribedDataSets;
4447
4448 size_t topicAssignSize;
4449 TAILQ_HEAD(, UA_TopicAssign) topicAssign;
4450
4451 size_t reserveIdsSize;
4452 UA_ReserveIdTree reserveIds;
4453
4454#ifdef UA_ENABLE_PUBSUB_SKS
4455 LIST_HEAD(, UA_PubSubKeyStorage) pubSubKeyList;
4456
4457 size_t securityGroupsSize;
4458 TAILQ_HEAD(, UA_SecurityGroup) securityGroups;
4459#endif
4460
4461#ifndef UA_ENABLE_PUBSUB_INFORMATIONMODEL
4462 UA_UInt32 uniqueIdCount;
4463#endif
4464} UA_PubSubManager;
4465
4466UA_StatusCode
4467UA_PubSubManager_addPubSubTopicAssign(UA_Server *server, UA_ReaderGroup *readerGroup,
4468 UA_String topic);
4469
4470UA_StatusCode
4471UA_PubSubManager_reserveIds(UA_Server *server, UA_NodeId sessionId, UA_UInt16 numRegWriterGroupIds,
4472 UA_UInt16 numRegDataSetWriterIds, UA_String transportProfileUri,
4473 UA_UInt16 **writerGroupIds, UA_UInt16 **dataSetWriterIds);
4474
4475void
4476UA_PubSubManager_freeIds(UA_Server *server);
4477
4478void
4479UA_PubSubManager_init(UA_Server *server, UA_PubSubManager *pubSubManager);
4480
4481void
4482UA_PubSubManager_shutdown(UA_Server *server, UA_PubSubManager *pubSubManager);
4483
4484void
4485UA_PubSubManager_delete(UA_Server *server, UA_PubSubManager *pubSubManager);
4486
4487#ifndef UA_ENABLE_PUBSUB_INFORMATIONMODEL
4488void
4489UA_PubSubManager_generateUniqueNodeId(UA_PubSubManager *psm, UA_NodeId *nodeId);
4490#endif
4491
4492#ifdef UA_ENABLE_PUBSUB_FILE_CONFIG
4493/* Decodes the information from the ByteString. If the decoded content is a
4494 * PubSubConfiguration in a UABinaryFileDataType-object. It will overwrite the
4495 * current PubSub configuration from the server. */
4496UA_StatusCode
4497UA_PubSubManager_loadPubSubConfigFromByteString(UA_Server *server,
4498 const UA_ByteString buffer);
4499
4500/* Saves the current PubSub configuration of a server in a byteString. */
4501UA_StatusCode
4502UA_PubSubManager_getEncodedPubSubConfiguration(UA_Server *server,
4503 UA_ByteString *buffer);
4504#endif
4505
4506UA_Guid
4507UA_PubSubManager_generateUniqueGuid(UA_Server *server);
4508
4509UA_UInt32
4510UA_PubSubConfigurationVersionTimeDifference(void);
4511
4512/*************************************************/
4513/* PubSub component monitoring */
4514/*************************************************/
4515
4516#ifdef UA_ENABLE_PUBSUB_MONITORING
4517
4518UA_StatusCode
4519UA_PubSubManager_setDefaultMonitoringCallbacks(UA_PubSubMonitoringInterface *monitoringInterface);
4520
4521#endif /* UA_ENABLE_PUBSUB_MONITORING */
4522
4523#endif /* UA_ENABLE_PUBSUB */
4524
4525_UA_END_DECLS
4526
4527
4528/**** amalgamated original file "/src/pubsub/ua_pubsub_ns0.h" ****/
4529
4530/* This Source Code Form is subject to the terms of the Mozilla Public
4531 * License, v. 2.0. If a copy of the MPL was not distributed with this
4532 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4533 *
4534 * Copyright (c) 2017-2018 Fraunhofer IOSB (Author: Andreas Ebner)
4535 * Copyright (c) 2019 Kalycito Infotech Private Limited
4536 * Copyright (c) 2022 Siemens AG (Author: Thomas Fischer)
4537 * Copyright (c) 2022 Linutronix GmbH (Author: Muddasir Shakil)
4538 */
4539
4540#ifndef UA_PUBSUB_NS0_H_
4541#define UA_PUBSUB_NS0_H_
4542
4543
4544_UA_BEGIN_DECLS
4545
4546#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL /* conditional compilation */
4547
4548UA_StatusCode
4549initPubSubNS0(UA_Server *server);
4550
4551UA_StatusCode
4552addPubSubConnectionRepresentation(UA_Server *server, UA_PubSubConnection *connection);
4553
4554UA_StatusCode
4555addWriterGroupRepresentation(UA_Server *server, UA_WriterGroup *writerGroup);
4556
4557UA_StatusCode
4558addReaderGroupRepresentation(UA_Server *server, UA_ReaderGroup *readerGroup);
4559
4560UA_StatusCode
4561addDataSetWriterRepresentation(UA_Server *server, UA_DataSetWriter *dataSetWriter);
4562
4563UA_StatusCode
4564addPublishedDataItemsRepresentation(UA_Server *server, UA_PublishedDataSet *publishedDataSet);
4565
4566UA_StatusCode
4567addStandaloneSubscribedDataSetRepresentation(UA_Server *server, UA_StandaloneSubscribedDataSet *subscribedDataSet);
4568
4569UA_StatusCode
4570addDataSetReaderRepresentation(UA_Server *server, UA_DataSetReader *dataSetReader);
4571
4572UA_StatusCode
4573connectDataSetReaderToDataSet(UA_Server *server, UA_NodeId dsrId, UA_NodeId standaloneSdsId);
4574
4575#ifdef UA_ENABLE_PUBSUB_SKS
4576UA_StatusCode
4577addSecurityGroupRepresentation(UA_Server *server, UA_SecurityGroup *securityGroup);
4578#endif /* UA_ENABLE_PUBSUB_SKS */
4579
4580#endif /* UA_ENABLE_PUBSUB_INFORMATIONMODEL */
4581
4582_UA_END_DECLS
4583
4584#endif /* UA_PUBSUB_NS0_H_ */
4585
4586/**** amalgamated original file "/src/pubsub/ua_pubsub_keystorage.h" ****/
4587
4588/* This Source Code Form is subject to the terms of the Mozilla Public
4589 * License, v. 2.0. If a copy of the MPL was not distributed with this
4590 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4591 *
4592 * Copyright (c) 2019 ifak e.V. Magdeburg (Holger Zipper)
4593 * Copyright (c) 2022 Linutronix GmbH (Author: Muddasir Shakil)
4594 */
4595
4596#ifndef UA_PUBSUB_KEYSTORAGE
4597#define UA_PUBSUB_KEYSTORAGE
4598
4599
4600
4601_UA_BEGIN_DECLS
4602
4603#ifdef UA_ENABLE_PUBSUB_SKS
4604
4605/**
4606 * PubSubKeyStorage
4607 * ================
4608 * A PubSubKeyStorage provides a linked list to store all the keys used to
4609 * secure the messages. It keeps the records of old keys (past keys), current
4610 * key, new keys (futurekeys), time to move to next key and callback id.
4611 *
4612 * PubSubKeyListItem is the basic item stored in the KeyList of KeyStorage. It
4613 * provides keyId, Key, and pointer to the next key in KeyList. The KeyId is used
4614 * to identify and update currentKey in the keystorage. The KeyId is the SecurityTokenId
4615 * that appears in the header of messages secured with the CurrentKey.
4616 *
4617 * Working
4618 * =======
4619 * +------------------------------+
4620 * |AddReaderGroup/AddWriterGroup |
4621 * +------------------------------+
4622 * |
4623 * V
4624 * +--------------------+
4625 * |CheckSecurityGroupId|
4626 * +--------------------+
4627 * |Yes
4628 * V
4629 * +--------------------+
4630 * |InitializeKeyStorage|
4631 * +--------------------+
4632 * |
4633 * V
4634 * +----------------------------+
4635 * |store/updateKeysInKeyStorage|
4636 * +----------------------------+
4637 * |
4638 * V
4639 * +------------------------------------------+
4640 * |activateKeysToAllPubSubGroupChannelContext|
4641 * +------------------------------------------+
4642 * | É…
4643 * V |
4644 * +-----------------------+ |
4645 * |addKeyRolloverCallbacks| |
4646 * +-----------------------+ |
4647 * | |
4648 * V |
4649 * +-------------------+ |
4650 * |keyRolloverCallback| |
4651 * +-------------------+ |
4652 * |CurrentKey!=LastItem |
4653 * -------------------------+
4654 *
4655 * A KeyStorage is created and initialized when a ReaderGroup or WriterGroup is
4656 * created with securityGroupId and SecurityMode SignAndEncrypt. The new
4657 * KeyStorage is added to the server KeyStorageList. At this time KeyList is empty.
4658 *
4659 * UA_PubSubKeyStorage_storeSecurityKeys is used to push the keys into existing
4660 * keystorage. In order to update the KeyList of an existing keyStorage,
4661 * UA_PubSubKeyStorage_update is called.
4662 *
4663 * After adding/updating the keys to keystorage, the current key should be
4664 * activated to the associated PubSub Group's ChannelContext in the server. The
4665 * security Policy associated with PubSub Group will take the keys from
4666 * channel context and use them to secure the messages.
4667 * The UA_PubSubKeyStorage_storeSecurityKeys and UA_PubSubKeyStorage_update
4668 * method will be used by setSecurityKeysAction and getSecurityKeysAction to
4669 * retrieve the keys from SKS server and store keys in local storage.
4670 *
4671 * Each key has a life time, after which the current key is expired and move to
4672 * next key in the existing list. For this a callback function is added to the
4673 * server. The callback function keyRolloverCallback is added to the server as a
4674 * timed callback. The addKeyRolloverCallbacks function calculates the time
4675 * stamp to trigger the callback when the current Key expires and roll
4676 * over to the next key in existing list.
4677 *
4678 */
4679
4680/**
4681 * @brief This structure holds the information about the keys
4682 */
4683typedef struct UA_PubSubKeyListItem {
4684 /* The SecurityTokenId associated with Key*/
4685 UA_UInt32 keyID;
4686
4687 /* This key is not used directly since the protocol associated with the PubSubGroup(s)
4688 * specifies an algorithm to generate distinct keys for different types of
4689 * cryptography operations*/
4690 UA_ByteString key;
4691
4692 /* Pointers to the key list entries*/
4693 TAILQ_ENTRY(UA_PubSubKeyListItem) keyListEntry;
4694} UA_PubSubKeyListItem;
4695
4696/* Queue Definition*/
4697typedef TAILQ_HEAD(keyListItems, UA_PubSubKeyListItem) keyListItems;
4698
4699/**
4700 * @brief It is used to hold configuration information required to connect an SKS server
4701 * and fetch the security keys
4702 */
4703typedef struct UA_PubSubSKSConfig {
4704 UA_ClientConfig clientConfig;
4705 const char *endpointUrl;
4706 UA_Server_sksPullRequestCallback userNotifyCallback;
4707 void *context;
4708 UA_UInt32 reqId;
4709} UA_PubSubSKSConfig;
4710
4711/**
4712 * @brief This structure holds all info and keys related to one SecurityGroup.
4713 * it is used as a list.
4714 */
4715typedef struct UA_PubSubKeyStorage {
4716
4717 /**
4718 * security group id of the security group related to this storage
4719 */
4720 UA_String securityGroupID;
4721
4722 /**
4723 * none-owning pointer to the security policy related to this storage
4724 */
4725 UA_PubSubSecurityPolicy *policy;
4726
4727 /**
4728 * in case of the SKS server, the key storage structure is deleted when removing the
4729 * security group.
4730 * in case of publisher / subscriber, one key storage structure is
4731 * referenced by multiple reader / writer groups have a reference count to manage free
4732 */
4733 UA_UInt32 referenceCount;
4734
4735 /**
4736 * array of keys. the elements inside this array have a next pointer.
4737 * keyList can therefore be used as linked list.
4738 */
4739 keyListItems keyList;
4740
4741 /**
4742 * size of the keyList
4743 */
4744 size_t keyListSize;
4745
4746 /**
4747 * The maximum number of Past keys a keystorage is allowed to store
4748 */
4749 UA_UInt32 maxPastKeyCount;
4750
4751 /**
4752 * The maximum number of Future keys a keyStorage is allowed to store
4753 */
4754 UA_UInt32 maxFutureKeyCount;
4755
4756 /*
4757 * The maximum keylist size, calculated from maxPastKeyCount and maxFutureKeyCount
4758 */
4759 UA_UInt32 maxKeyListSize;
4760
4761 /**
4762 * The SecurityTokenId that appears in the header of messages secured with the
4763 * CurrentKey. It starts at 1 and is incremented by 1 each time the KeyLifetime
4764 * elapses even if no keys are requested. If the CurrentTokenId increments past the
4765 * maximum value of UInt32 it restarts a 1.
4766 */
4767 UA_UInt32 currentTokenId;
4768
4769 /**
4770 * the current key used to secure the messages
4771 */
4772 UA_PubSubKeyListItem *currentItem;
4773
4774 /**
4775 * keyLifeTime used to update the CurrentKey from the Local KeyStorage
4776 */
4777 UA_Duration keyLifeTime;
4778
4779 /**
4780 * id used to register the callback to retrieve the keys related to this security
4781 * group
4782 */
4783 UA_UInt64 callBackId;
4784
4785 /**
4786 * used to store the sks related information to connect with SKS server and fetch security keys.
4787 */
4788 UA_PubSubSKSConfig sksConfig;
4789
4790 /**
4791 * Pointer to the key storage list
4792 */
4793 LIST_ENTRY(UA_PubSubKeyStorage) keyStorageList;
4794
4795} UA_PubSubKeyStorage;
4796
4797/**
4798 * @brief Find the Keystorage from the Server KeyStorageList and returns the pointer to
4799 * the keystorage
4800 *
4801 * @param server holds the keystoragelist
4802 * @param securityGroupId of the keystorage to be found
4803 * @return Pointer to the keystorage on success, null pointer on failure
4804 */
4805UA_PubSubKeyStorage *
4806UA_PubSubKeyStorage_findKeyStorage(UA_Server *server, UA_String securityGroupId);
4807
4808/**
4809 * @brief retreives the security policy pointer from the PubSub configuration by
4810 * SecurityPolicyUri
4811 *
4812 * @param server the server object
4813 * @param securityPolicyUri the URI of the security policy
4814 * @param policy the pointer to the security policy
4815 * @return UA_StatusCode return status code
4816 */
4817UA_PubSubSecurityPolicy *
4818findPubSubSecurityPolicy(UA_Server *server, const UA_String *securityPolicyUri);
4819
4820/**
4821 * @brief Deletes the keystorage from the server and its members
4822 *
4823 * @param server where the keystorage is created
4824 * @param keyStorage pointer to the keystorage
4825 */
4826void
4827UA_PubSubKeyStorage_delete(UA_Server *server, UA_PubSubKeyStorage *keyStorage);
4828
4829/**
4830 * @brief Initializes an empty Keystorage for the SecurityGroupId and add it to the Server
4831 * KeyStorageList
4832 *
4833 * @param server The server object
4834 * @param keyStorage Pointer to the keystorage to be initialized
4835 * @param securityGroupId The identifier of the SecurityGroup
4836 * @param policy The security policy assocaited with the security algorithm
4837 * @param maxPastKeyCount maximum number of past keys a keystorage is allowed to store
4838 * @param maxFutureKeyCount maximum number of future keys a keystorage is allowed to store
4839 * @return UA_StatusCode return status code
4840 */
4841UA_StatusCode
4842UA_PubSubKeyStorage_init(UA_Server *server, UA_PubSubKeyStorage *keyStorage,
4843 const UA_String *securityGroupId,
4844 UA_PubSubSecurityPolicy *policy,
4845 UA_UInt32 maxPastKeyCount, UA_UInt32 maxFutureKeyCount);
4846
4847/**
4848 * @brief After Keystorage is initialized and added to the server, this method is called
4849 * to store the current Keys and futurekeys.
4850 *
4851 * @param server the server object
4852 * @param keyStorage pointer to the keyStorage
4853 * @param currentTokenId The token Id of the current key it starts with 1 and increaments
4854 * each time keylifetime expires
4855 * @param currentKey the key used for encrypt the current messages
4856 * @param futureKeys pointer to the future keys
4857 * @param futureKeyCount the number future keys provided
4858 * @param keyLifeTime the time period when the key expires and move to next future key in
4859 * milli seconds
4860 * @return UA_StatusCode the return status
4861 */
4862UA_StatusCode
4863UA_PubSubKeyStorage_storeSecurityKeys(UA_Server *server, UA_PubSubKeyStorage *keyStorage,
4864 UA_UInt32 currentTokenId, const UA_ByteString *currentKey,
4865 UA_ByteString *futureKeys, size_t futureKeyCount,
4866 UA_Duration msKeyLifeTime);
4867
4868/**
4869 * @brief Finds the KeyItem from the KeyList by KeyId
4870 *
4871 * @param keyId the identifier of the Key
4872 * @param keyStorage pointer to the keystorage
4873 * @param keyItem returned pointer to the keyItem in the KeyList
4874 * @return UA_StatusCode return status code
4875 */
4876UA_StatusCode
4877UA_PubSubKeyStorage_getKeyByKeyID(const UA_UInt32 keyId, UA_PubSubKeyStorage *keyStorage,
4878 UA_PubSubKeyListItem **keyItem);
4879
4880/**
4881 * @brief Adds a new KeyItem at the end of the KeyList
4882 * to the new KeyListItem.
4883 *
4884 * @param keyStorage pointer to the keystorage
4885 * @param key the key to be added
4886 * @param keyID the keyID associated with the key to be added
4887 */
4888UA_PubSubKeyListItem *
4889UA_PubSubKeyStorage_push(UA_PubSubKeyStorage *keyStorage, const UA_ByteString *key,
4890 UA_UInt32 keyID);
4891
4892/**
4893 * @brief It calculates the time to trigger the callback to update current key, adds the
4894 * callback to the server and returns the callbackId.
4895 *
4896 * @param server the server object
4897 * @param keyStorage the pointer to the existing keystorage in the server
4898 * @param callback the callback function to be added to the server
4899 * @param timeToNextMs time in milli seconds to trigger the callback function
4900 * @param callbackID the returned callbackId of the added callback function
4901 * @return UA_StatusCode the return status
4902 */
4903UA_StatusCode
4904UA_PubSubKeyStorage_addKeyRolloverCallback(UA_Server *server,
4905 UA_PubSubKeyStorage *keyStorage,
4906 UA_ServerCallback callback,
4907 UA_Duration timeToNextMs,
4908 UA_UInt64 *callbackID);
4909
4910/**
4911 * @brief It takes the current Key data, divide it into signing key, encrypting key and
4912 * keyNonce according to security policy associated with PubSub Group and set it in
4913 * channel context of the assocaited PubSub Group. In case of pubSubGroupId is
4914 * UA_NODEID_NULL, all the Reader/WriterGroup's channelcontext are updated with matching
4915 * SecurityGroupId.
4916 *
4917 * @param server The server object
4918 * @param pubSubGroupId the nodeId of the Reader/WirterGroup whose channel context to be
4919 * updated
4920 * @param securityGroupId The identifier for the SecurityGroup
4921 * @return UA_StatusCode return status code
4922 */
4923UA_StatusCode
4924UA_PubSubKeyStorage_activateKeyToChannelContext(UA_Server *server, const UA_NodeId pubSubGroupId,
4925 const UA_String securityGroupId);
4926
4927/**
4928 * @brief The callback function to update the current key from keystorage in the server
4929 * and activate the current key into channel context of the associated PubSub Group
4930 *
4931 * @param server the server object
4932 * @param keyStorage the pointer to the keystorage
4933 */
4934void
4935UA_PubSubKeyStorage_keyRolloverCallback(UA_Server *server, UA_PubSubKeyStorage *keyStorage);
4936
4937/**
4938 * @brief It updates/adds the current and future keys into the existing KeyStorage.
4939 * If the currentKeyID is known to existing keyStorage, then it is set as the currentKey
4940 * and any future keys are appended to the existing list. If the currentKeyId is not know
4941 * then, existing keyList is discarded and replaced with the new list.
4942 *
4943 * @param server the server object
4944 * @param keyStorage pointer to the keystorage
4945 * @param currentKey the currentKey data
4946 * @param currentKeyID the identifier of the current Key
4947 * @param futureKeySize the size of the future key list
4948 * @param futureKeys the pointer to the future keys list
4949 * @param msKeyLifeTime the updated time to move to next key
4950 * @return UA_StatusCode the return status
4951 */
4952UA_StatusCode
4953UA_PubSubKeyStorage_update(UA_Server *server, UA_PubSubKeyStorage *keyStorage,
4954 const UA_ByteString *currentKey, UA_UInt32 currentKeyID,
4955 const size_t futureKeySize, UA_ByteString *futureKeys,
4956 UA_Duration msKeyLifeTime);
4957
4958/* KeyStorage must be referenced by atleast one PubSubGroup. This method reduces
4959 * the reference count by one. If no PubSubGroup uses the key storage, then it
4960 * is deleted. */
4961void
4962UA_PubSubKeyStorage_detachKeyStorage(UA_Server *server, UA_PubSubKeyStorage *keyStorage);
4963
4964/*Calls get SecurityKeys Method and Store the returned keys into KeyStorage*/
4965UA_StatusCode
4966getSecurityKeysAndStoreFetchedKeys(UA_Server *server, UA_PubSubKeyStorage *keyStorage);
4967
4968#endif
4969
4970_UA_END_DECLS
4971
4972#endif /* UA_ENABLE_PUBSUB */
4973
4974/**** amalgamated original file "/src/server/ua_server_async.h" ****/
4975
4976/* This Source Code Form is subject to the terms of the Mozilla Public
4977 * License, v. 2.0. If a copy of the MPL was not distributed with this
4978 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4979 *
4980 * Copyright 2019 (c) Fraunhofer IOSB (Author: Klaus Schick)
4981 * based on
4982 * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
4983 * Copyright 2014, 2017 (c) Florian Palm
4984 * Copyright 2015 (c) Sten Grüner
4985 * Copyright 2015 (c) Oleksiy Vasylyev
4986 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
4987 */
4988
4989
4990
4991
4992_UA_BEGIN_DECLS
4993
4994#if UA_MULTITHREADING >= 100
4995
4996struct UA_AsyncResponse;
4997typedef struct UA_AsyncResponse UA_AsyncResponse;
4998
4999/* A single operation (of a larger request) */
5000typedef struct UA_AsyncOperation {
5001 TAILQ_ENTRY(UA_AsyncOperation) pointers;
5002 UA_CallMethodRequest request;
5003 UA_CallMethodResult response;
5004 size_t index; /* Index of the operation in the array of ops in
5005 * request/response */
5006 UA_AsyncResponse *parent; /* Always non-NULL. The parent is only removed
5007 * when its operations are removed */
5008} UA_AsyncOperation;
5009
5010struct UA_AsyncResponse {
5011 TAILQ_ENTRY(UA_AsyncResponse) pointers; /* Insert new at the end */
5012 UA_UInt32 requestId;
5013 UA_NodeId sessionId;
5014 UA_UInt32 requestHandle;
5015 UA_DateTime timeout;
5016 UA_AsyncOperationType operationType;
5017 union {
5018 UA_CallResponse callResponse;
5019 UA_ReadResponse readResponse;
5020 UA_WriteResponse writeResponse;
5021 } response;
5022 UA_UInt32 opCountdown; /* Counter for outstanding operations. The AR can
5023 * only be deleted when all have returned. */
5024};
5025
5026typedef TAILQ_HEAD(UA_AsyncOperationQueue, UA_AsyncOperation) UA_AsyncOperationQueue;
5027
5028typedef struct {
5029 /* Requests / Responses */
5030 TAILQ_HEAD(, UA_AsyncResponse) asyncResponses;
5031 size_t asyncResponsesCount;
5032
5033 /* Operations for the workers. The queues are all FIFO: Put in at the tail,
5034 * take out at the head.*/
5035 UA_Lock queueLock; /* Either take this lock free-standing (with no other
5036 * locks). Or take server->serviceMutex first and then
5037 * the queueLock. Never take the server->serviceMutex
5038 * when the queueLock is already acquired (deadlock)! */
5039 UA_AsyncOperationQueue newQueue; /* New operations for the workers */
5040 UA_AsyncOperationQueue dispatchedQueue; /* Operations taken by a worker. When a result is
5041 * returned, we search for the op here to see if it
5042 * is still "alive" (not timed out). */
5043 UA_AsyncOperationQueue resultQueue; /* Results to be integrated */
5044 size_t opsCount; /* How many operations are transient (in one of the three queues)? */
5045
5046 UA_UInt64 checkTimeoutCallbackId; /* Registered repeated callbacks */
5047} UA_AsyncManager;
5048
5049void UA_AsyncManager_init(UA_AsyncManager *am, UA_Server *server);
5050void UA_AsyncManager_clear(UA_AsyncManager *am, UA_Server *server);
5051
5052UA_StatusCode
5053UA_AsyncManager_createAsyncResponse(UA_AsyncManager *am, UA_Server *server,
5054 const UA_NodeId *sessionId,
5055 const UA_UInt32 requestId,
5056 const UA_UInt32 requestHandle,
5057 const UA_AsyncOperationType operationType,
5058 UA_AsyncResponse **outAr);
5059
5060/* Only remove the AsyncResponse when the operation count is zero */
5061void
5062UA_AsyncManager_removeAsyncResponse(UA_AsyncManager *am, UA_AsyncResponse *ar);
5063
5064UA_StatusCode
5065UA_AsyncManager_createAsyncOp(UA_AsyncManager *am, UA_Server *server,
5066 UA_AsyncResponse *ar, size_t opIndex,
5067 const UA_CallMethodRequest *opRequest);
5068
5069/* Send out the response with status set. Also removes all outstanding
5070 * operations from the dispatch queue. The queuelock needs to be taken before
5071 * calling _cancel. */
5072UA_UInt32
5073UA_AsyncManager_cancel(UA_Server *server, UA_Session *session, UA_UInt32 requestHandle);
5074
5075typedef void (*UA_AsyncServiceOperation)(UA_Server *server, UA_Session *session,
5076 UA_UInt32 requestId, UA_UInt32 requestHandle,
5077 size_t opIndex, const void *requestOperation,
5078 void *responseOperation, UA_AsyncResponse **ar);
5079
5080/* Creates an AsyncResponse in-situ when an async operation is encountered. If
5081 * that is the case, the sync responses are moved to the AsyncResponse. */
5082UA_StatusCode
5083UA_Server_processServiceOperationsAsync(UA_Server *server, UA_Session *session,
5084 UA_UInt32 requestId, UA_UInt32 requestHandle,
5085 UA_AsyncServiceOperation operationCallback,
5086 const size_t *requestOperations,
5087 const UA_DataType *requestOperationsType,
5088 size_t *responseOperations,
5089 const UA_DataType *responseOperationsType,
5090 UA_AsyncResponse **ar)
5091UA_FUNC_ATTR_WARN_UNUSED_RESULT;
5092
5093#endif /* UA_MULTITHREADING >= 100 */
5094
5095_UA_END_DECLS
5096
5097
5098/**** amalgamated original file "/src/server/ua_server_internal.h" ****/
5099
5100/* This Source Code Form is subject to the terms of the Mozilla Public
5101 * License, v. 2.0. If a copy of the MPL was not distributed with this
5102 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5103 *
5104 * Copyright 2019 (c) Fraunhofer IOSB (Author: Klaus Schick)
5105 * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
5106 * Copyright 2014, 2017 (c) Florian Palm
5107 * Copyright 2015-2016 (c) Sten Grüner
5108 * Copyright 2015 (c) Chris Iatrou
5109 * Copyright 2015-2016 (c) Oleksiy Vasylyev
5110 * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH
5111 * Copyright 2017 (c) Julian Grothoff
5112 * Copyright 2019 (c) Kalycito Infotech Private Limited
5113 * Copyright 2019 (c) HMS Industrial Networks AB (Author: Jonas Green)
5114 * Copyright 2021 (c) Fraunhofer IOSB (Author: Andreas Ebner)
5115 * Copyright 2022 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati)
5116 */
5117
5118
5119#define UA_INTERNAL
5120
5121
5122_UA_BEGIN_DECLS
5123
5124#ifdef UA_ENABLE_PUBSUB
5125#endif
5126
5127#ifdef UA_ENABLE_DISCOVERY
5128struct UA_DiscoveryManager;
5129typedef struct UA_DiscoveryManager UA_DiscoveryManager;
5130#endif
5131
5132#ifdef UA_ENABLE_SUBSCRIPTIONS
5133
5134typedef struct {
5135 UA_MonitoredItem monitoredItem;
5136 void *context;
5137 union {
5138 UA_Server_DataChangeNotificationCallback dataChangeCallback;
5139 /* UA_Server_EventNotificationCallback eventCallback; */
5140 } callback;
5141} UA_LocalMonitoredItem;
5142
5143#endif /* !UA_ENABLE_SUBSCRIPTIONS */
5144
5145/********************/
5146/* Server Component */
5147/********************/
5148
5149/* ServerComponents have an explicit lifecycle. But they can only be started
5150 * when the underlying server is started. The starting/stopping of
5151 * ServerComponents is asynchronous. That is, they might require several
5152 * iterations of the EventLoop to finish starting/stopping.
5153 *
5154 * ServerComponents can only be deleted when they are STOPPED. The server will
5155 * not fully shut down as long as there is a component remaining. */
5156
5157typedef struct UA_ServerComponent {
5158 UA_UInt64 identifier;
5159 UA_String name;
5160 ZIP_ENTRY(UA_ServerComponent) treeEntry;
5161 UA_LifecycleState state;
5162
5163 /* Starting fails if the server is not also already started */
5164 UA_StatusCode (*start)(UA_Server *server,
5165 struct UA_ServerComponent *sc);
5166
5167 /* Stopping is asynchronous and might need a few iterations of the main-loop
5168 * to succeed. */
5169 void (*stop)(UA_Server *server,
5170 struct UA_ServerComponent *sc);
5171
5172 /* Clean up the ServerComponent. Can fail if it is not stopped. */
5173 UA_StatusCode (*free)(UA_Server *server,
5174 struct UA_ServerComponent *sc);
5175
5176 /* To be set by the server. So the component can notify the server about
5177 * asynchronous state changes. */
5178 void (*notifyState)(UA_Server *server, struct UA_ServerComponent *sc,
5179 UA_LifecycleState state);
5180} UA_ServerComponent;
5181
5182enum ZIP_CMP
5183cmpServerComponent(const UA_UInt64 *a, const UA_UInt64 *b);
5184
5185typedef ZIP_HEAD(UA_ServerComponentTree, UA_ServerComponent) UA_ServerComponentTree;
5186
5187ZIP_FUNCTIONS(UA_ServerComponentTree, UA_ServerComponent, treeEntry,
5188 UA_UInt64, identifier, cmpServerComponent)
5189
5190/* Assigns the identifier if the pointer is non-NULL.
5191 * Starts the component if the server is started. */
5192void
5193addServerComponent(UA_Server *server, UA_ServerComponent *sc,
5194 UA_UInt64 *identifier);
5195
5196UA_ServerComponent *
5197getServerComponentByName(UA_Server *server, UA_String name);
5198
5199/********************/
5200/* Server Structure */
5201/********************/
5202
5203typedef struct session_list_entry {
5204 UA_DelayedCallback cleanupCallback;
5205 LIST_ENTRY(session_list_entry) pointers;
5206 UA_Session session;
5207} session_list_entry;
5208
5209struct UA_Server {
5210 /* Config */
5211 UA_ServerConfig config;
5212
5213 /* Runtime state */
5214 UA_DateTime startTime;
5215 UA_DateTime endTime; /* Zeroed out. If a time is set, then the server shuts
5216 * down once the time has been reached */
5217
5218 UA_LifecycleState state;
5219 UA_UInt64 houseKeepingCallbackId;
5220
5221 UA_UInt64 serverComponentIds; /* Counter to assign ids from */
5222 UA_ServerComponentTree serverComponents;
5223
5224#if UA_MULTITHREADING >= 100
5225 UA_AsyncManager asyncManager;
5226#endif
5227
5228 /* Session Management */
5229 LIST_HEAD(session_list, session_list_entry) sessions;
5230 UA_UInt32 sessionCount;
5231 UA_UInt32 activeSessionCount;
5232 UA_Session adminSession; /* Local access to the services (for startup and
5233 * maintenance) uses this Session with all possible
5234 * access rights (Session Id: 1) */
5235
5236 /* Namespaces */
5237 size_t namespacesSize;
5238 UA_String *namespaces;
5239
5240 /* For bootstrapping, omit some consistency checks, creating a reference to
5241 * the parent and member instantiation */
5242 UA_Boolean bootstrapNS0;
5243
5244 /* Subscriptions */
5245#ifdef UA_ENABLE_SUBSCRIPTIONS
5246 size_t subscriptionsSize; /* Number of active subscriptions */
5247 size_t monitoredItemsSize; /* Number of active monitored items */
5248 LIST_HEAD(, UA_Subscription) subscriptions; /* All subscriptions in the
5249 * server. They may be detached
5250 * from a session. */
5251 UA_UInt32 lastSubscriptionId; /* To generate unique SubscriptionIds */
5252
5253 /* To be cast to UA_LocalMonitoredItem to get the callback and context */
5254 LIST_HEAD(, UA_MonitoredItem) localMonitoredItems;
5255 UA_UInt32 lastLocalMonitoredItemId;
5256
5257# ifdef UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS
5258 LIST_HEAD(, UA_ConditionSource) conditionSources;
5259 UA_NodeId refreshEvents[2];
5260# endif
5261#endif
5262
5263 /* Publish/Subscribe */
5264#ifdef UA_ENABLE_PUBSUB
5265 UA_PubSubManager pubSubManager;
5266#endif
5267
5268#if UA_MULTITHREADING >= 100
5269 UA_Lock serviceMutex;
5270#endif
5271
5272 /* Statistics */
5273 UA_SecureChannelStatistics secureChannelStatistics;
5274 UA_ServerDiagnosticsSummaryDataType serverDiagnosticsSummary;
5275};
5276
5277/***********************/
5278/* References Handling */
5279/***********************/
5280
5281enum ZIP_CMP
5282cmpRefTargetId(const void *a, const void *b);
5283
5284enum ZIP_CMP
5285cmpRefTargetName(const void *a, const void *b);
5286
5287/* Static inline methods for tree handling */
5288typedef ZIP_HEAD(UA_ReferenceIdTree, UA_ReferenceTargetTreeElem) UA_ReferenceIdTree;
5289ZIP_FUNCTIONS(UA_ReferenceIdTree, UA_ReferenceTargetTreeElem, idTreeEntry,
5290 UA_ReferenceTargetTreeElem, target, cmpRefTargetId)
5291
5292typedef ZIP_HEAD(UA_ReferenceNameTree, UA_ReferenceTargetTreeElem) UA_ReferenceNameTree;
5293ZIP_FUNCTIONS(UA_ReferenceNameTree, UA_ReferenceTargetTreeElem, nameTreeEntry,
5294 UA_ReferenceTarget, target, cmpRefTargetName)
5295
5296/**************************/
5297/* SecureChannel Handling */
5298/**************************/
5299
5300void
5301serverNetworkCallback(UA_ConnectionManager *cm, uintptr_t connectionId,
5302 void *application, void **connectionContext,
5303 UA_ConnectionState state,
5304 const UA_KeyValueMap *params,
5305 UA_ByteString msg);
5306
5307UA_StatusCode
5308sendServiceFault(UA_SecureChannel *channel, UA_UInt32 requestId,
5309 UA_UInt32 requestHandle, UA_StatusCode statusCode);
5310
5311/* Gets the a pointer to the context of a security policy supported by the
5312 * server matched by the security policy uri. */
5313UA_SecurityPolicy *
5314getSecurityPolicyByUri(const UA_Server *server,
5315 const UA_ByteString *securityPolicyUri);
5316
5317UA_UInt32
5318generateSecureChannelTokenId(UA_Server *server);
5319
5320/********************/
5321/* Session Handling */
5322/********************/
5323
5324UA_StatusCode
5325getNamespaceByName(UA_Server *server, const UA_String namespaceUri,
5326 size_t *foundIndex);
5327
5328UA_StatusCode
5329getNamespaceByIndex(UA_Server *server, const size_t namespaceIndex,
5330 UA_String *foundUri);
5331
5332UA_StatusCode
5333getBoundSession(UA_Server *server, const UA_SecureChannel *channel,
5334 const UA_NodeId *token, UA_Session **session);
5335
5336UA_StatusCode
5337UA_Server_createSession(UA_Server *server, UA_SecureChannel *channel,
5338 const UA_CreateSessionRequest *request, UA_Session **session);
5339
5340void
5341UA_Server_removeSession(UA_Server *server, session_list_entry *sentry,
5342 UA_ShutdownReason shutdownReason);
5343
5344UA_StatusCode
5345UA_Server_removeSessionByToken(UA_Server *server, const UA_NodeId *token,
5346 UA_ShutdownReason shutdownReason);
5347
5348void
5349UA_Server_cleanupSessions(UA_Server *server, UA_DateTime nowMonotonic);
5350
5351UA_Session *
5352getSessionByToken(UA_Server *server, const UA_NodeId *token);
5353
5354UA_Session *
5355getSessionById(UA_Server *server, const UA_NodeId *sessionId);
5356
5357/*****************/
5358/* Node Handling */
5359/*****************/
5360
5361/* Calls the callback with the node retrieved from the nodestore on top of the
5362 * stack. Either a copy or the original node for in-situ editing. Depends on
5363 * multithreading and the nodestore.*/
5364typedef UA_StatusCode (*UA_EditNodeCallback)(UA_Server*, UA_Session*,
5365 UA_Node *node, void*);
5366UA_StatusCode UA_Server_editNode(UA_Server *server, UA_Session *session,
5367 const UA_NodeId *nodeId,
5368 UA_EditNodeCallback callback,
5369 void *data);
5370
5371/*********************/
5372/* Utility Functions */
5373/*********************/
5374
5375void setServerLifecycleState(UA_Server *server, UA_LifecycleState state);
5376
5377void setupNs1Uri(UA_Server *server);
5378UA_UInt16 addNamespace(UA_Server *server, const UA_String name);
5379
5380UA_Boolean
5381UA_Node_hasSubTypeOrInstances(const UA_NodeHead *head);
5382
5383/* Recursively searches "upwards" in the tree following specific reference types */
5384UA_Boolean
5385isNodeInTree(UA_Server *server, const UA_NodeId *leafNode,
5386 const UA_NodeId *nodeToFind, const UA_ReferenceTypeSet *relevantRefs);
5387
5388/* Convenience function with just a single ReferenceTypeIndex */
5389UA_Boolean
5390isNodeInTree_singleRef(UA_Server *server, const UA_NodeId *leafNode,
5391 const UA_NodeId *nodeToFind, const UA_Byte relevantRefTypeIndex);
5392
5393/* Returns an array with the hierarchy of nodes. The start nodes can be returned
5394 * as well. The returned array starts at the leaf and continues "upwards" or
5395 * "downwards". Duplicate entries are removed. */
5396UA_StatusCode
5397browseRecursive(UA_Server *server, size_t startNodesSize, const UA_NodeId *startNodes,
5398 UA_BrowseDirection browseDirection, const UA_ReferenceTypeSet *refTypes,
5399 UA_UInt32 nodeClassMask, UA_Boolean includeStartNodes,
5400 size_t *resultsSize, UA_ExpandedNodeId **results);
5401
5402/* Get the bitfield indices of a ReferenceType and possibly its subtypes.
5403 * refType must point to a ReferenceTypeNode. */
5404UA_StatusCode
5405referenceTypeIndices(UA_Server *server, const UA_NodeId *refType,
5406 UA_ReferenceTypeSet *indices, UA_Boolean includeSubtypes);
5407
5408/* Returns the recursive type and interface hierarchy of the node */
5409UA_StatusCode
5410getParentTypeAndInterfaceHierarchy(UA_Server *server, const UA_NodeId *typeNode,
5411 UA_NodeId **typeHierarchy, size_t *typeHierarchySize);
5412
5413/* Returns the recursive interface hierarchy of the node */
5414UA_StatusCode
5415getAllInterfaceChildNodeIds(UA_Server *server, const UA_NodeId *objectNode, const UA_NodeId *objectTypeNode,
5416 UA_NodeId **interfaceChildNodes, size_t *interfaceChildNodesSize);
5417
5418#ifdef UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS
5419
5420UA_StatusCode
5421UA_getConditionId(UA_Server *server, const UA_NodeId *conditionNodeId,
5422 UA_NodeId *outConditionId);
5423
5424void
5425UA_ConditionList_delete(UA_Server *server);
5426
5427UA_Boolean
5428isConditionOrBranch(UA_Server *server,
5429 const UA_NodeId *condition,
5430 const UA_NodeId *conditionSource,
5431 UA_Boolean *isCallerAC);
5432
5433#endif /* UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS */
5434
5435/* Returns the type node from the node on the stack top. The type node is pushed
5436 * on the stack and returned. */
5437const UA_Node *
5438getNodeType(UA_Server *server, const UA_NodeHead *nodeHead);
5439
5440UA_StatusCode
5441sendResponse(UA_Server *server, UA_Session *session, UA_SecureChannel *channel,
5442 UA_UInt32 requestId, UA_Response *response, const UA_DataType *responseType);
5443
5444/* Many services come as an array of operations. This function generalizes the
5445 * processing of the operations. */
5446typedef void (*UA_ServiceOperation)(UA_Server *server, UA_Session *session,
5447 const void *context,
5448 const void *requestOperation,
5449 void *responseOperation);
5450
5451UA_StatusCode
5452UA_Server_processServiceOperations(UA_Server *server, UA_Session *session,
5453 UA_ServiceOperation operationCallback,
5454 const void *context,
5455 const size_t *requestOperations,
5456 const UA_DataType *requestOperationsType,
5457 size_t *responseOperations,
5458 const UA_DataType *responseOperationsType)
5459 UA_FUNC_ATTR_WARN_UNUSED_RESULT;
5460
5461/*********************/
5462/* Locking/Unlocking */
5463/*********************/
5464
5465/* In order to prevent deadlocks between the EventLoop mutex and the
5466 * server-mutex, we always take the EventLoop mutex first. */
5467
5468void lockServer(UA_Server *server);
5469void unlockServer(UA_Server *server);
5470
5471/******************************************/
5472/* Internal function calls, without locks */
5473/******************************************/
5474UA_StatusCode
5475deleteNode(UA_Server *server, const UA_NodeId nodeId,
5476 UA_Boolean deleteReferences);
5477
5478UA_StatusCode
5479addRef(UA_Server *server, const UA_NodeId sourceId,
5480 const UA_NodeId referenceTypeId, const UA_NodeId targetId,
5481 UA_Boolean forward);
5482
5483UA_StatusCode
5484deleteReference(UA_Server *server, const UA_NodeId sourceNodeId,
5485 const UA_NodeId referenceTypeId, UA_Boolean isForward,
5486 const UA_ExpandedNodeId targetNodeId,
5487 UA_Boolean deleteBidirectional);
5488
5489UA_StatusCode
5490addRefWithSession(UA_Server *server, UA_Session *session, const UA_NodeId *sourceId,
5491 const UA_NodeId *referenceTypeId, const UA_NodeId *targetId,
5492 UA_Boolean forward);
5493
5494UA_StatusCode
5495setVariableNode_dataSource(UA_Server *server, const UA_NodeId nodeId,
5496 const UA_DataSource dataSource);
5497
5498UA_StatusCode
5499setVariableNode_valueCallback(UA_Server *server, const UA_NodeId nodeId,
5500 const UA_ValueCallback callback);
5501
5502UA_StatusCode
5503setMethodNode_callback(UA_Server *server, const UA_NodeId methodNodeId,
5504 UA_MethodCallback methodCallback);
5505
5506UA_StatusCode
5507setNodeTypeLifecycle(UA_Server *server, UA_NodeId nodeId,
5508 UA_NodeTypeLifecycle lifecycle);
5509
5510void
5511Operation_Write(UA_Server *server, UA_Session *session, void *context,
5512 const UA_WriteValue *wv, UA_StatusCode *result);
5513
5514UA_StatusCode
5515writeAttribute(UA_Server *server, UA_Session *session,
5516 const UA_NodeId *nodeId, const UA_AttributeId attributeId,
5517 const void *attr, const UA_DataType *attr_type);
5518
5519#define UA_WRITEATTRIBUTEFUNCS(ATTR, ATTRID, TYPE, TYPENAME) \
5520 static UA_INLINE UA_StatusCode \
5521 write##ATTR##Attribute(UA_Server *server, const UA_NodeId nodeId, \
5522 const TYPE value) { \
5523 return writeAttribute(server, &server->adminSession, &nodeId, \
5524 ATTRID, &value, &UA_TYPES[UA_TYPES_##TYPENAME]); \
5525 } \
5526 static UA_INLINE UA_StatusCode \
5527 write##ATTR##AttributeWithSession(UA_Server *server, UA_Session *session, \
5528 const UA_NodeId nodeId, const TYPE value) { \
5529 return writeAttribute(server, session, &nodeId, ATTRID, &value, \
5530 &UA_TYPES[UA_TYPES_##TYPENAME]); \
5531 }
5532
5533static UA_INLINE UA_StatusCode
5534writeValueAttribute(UA_Server *server, const UA_NodeId nodeId,
5535 const UA_Variant *value) {
5536 return writeAttribute(server, session: &server->adminSession, nodeId: &nodeId,
5537 attributeId: UA_ATTRIBUTEID_VALUE, attr: value, attr_type: &UA_TYPES[UA_TYPES_VARIANT]);
5538}
5539
5540UA_WRITEATTRIBUTEFUNCS(IsAbstract, UA_ATTRIBUTEID_ISABSTRACT, UA_Boolean, BOOLEAN)
5541UA_WRITEATTRIBUTEFUNCS(ValueRank, UA_ATTRIBUTEID_VALUERANK, UA_Int32, INT32)
5542UA_WRITEATTRIBUTEFUNCS(AccessLevel, UA_ATTRIBUTEID_ACCESSLEVEL, UA_Byte, BYTE)
5543UA_WRITEATTRIBUTEFUNCS(MinimumSamplingInterval, UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL,
5544 UA_Double, DOUBLE)
5545
5546void
5547Operation_Read(UA_Server *server, UA_Session *session, UA_TimestampsToReturn *ttr,
5548 const UA_ReadValueId *rvi, UA_DataValue *dv);
5549
5550UA_DataValue
5551readWithSession(UA_Server *server, UA_Session *session,
5552 const UA_ReadValueId *item,
5553 UA_TimestampsToReturn timestampsToReturn);
5554
5555UA_StatusCode
5556readWithReadValue(UA_Server *server, const UA_NodeId *nodeId,
5557 const UA_AttributeId attributeId, void *v);
5558
5559UA_StatusCode
5560readObjectProperty(UA_Server *server, const UA_NodeId objectId,
5561 const UA_QualifiedName propertyName,
5562 UA_Variant *value);
5563
5564UA_BrowsePathResult
5565translateBrowsePathToNodeIds(UA_Server *server, const UA_BrowsePath *browsePath);
5566
5567#ifdef UA_ENABLE_SUBSCRIPTIONS
5568
5569void monitoredItem_sampleCallback(UA_Server *server, UA_MonitoredItem *mon);
5570
5571UA_Subscription *
5572getSubscriptionById(UA_Server *server, UA_UInt32 subscriptionId);
5573
5574#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
5575
5576UA_StatusCode
5577createEvent(UA_Server *server, const UA_NodeId eventType,
5578 UA_NodeId *outNodeId);
5579
5580UA_StatusCode
5581triggerEvent(UA_Server *server, const UA_NodeId eventNodeId,
5582 const UA_NodeId origin, UA_ByteString *outEventId,
5583 const UA_Boolean deleteEventNode);
5584
5585/* Filters the given event with the given filter and writes the results into a
5586 * notification */
5587UA_StatusCode
5588filterEvent(UA_Server *server, UA_Session *session,
5589 const UA_NodeId *eventNode, UA_EventFilter *filter,
5590 UA_EventFieldList *efl, UA_EventFilterResult *result);
5591
5592#endif /* UA_ENABLE_SUBSCRIPTIONS_EVENTS */
5593
5594#endif /* UA_ENABLE_SUBSCRIPTIONS */
5595
5596/* Returns a configured SecurityPolicy with encryption. Use Basic256Sha256 if
5597 * available. Otherwise use any encrypted SecurityPolicy. */
5598UA_SecurityPolicy *
5599getDefaultEncryptedSecurityPolicy(UA_Server *server);
5600
5601UA_StatusCode
5602setCurrentEndPointsArray(UA_Server *server, const UA_String endpointURL,
5603 UA_String *profileUris, size_t profileUrisSize,
5604 UA_EndpointDescription **arr, size_t *arrSize);
5605
5606UA_BrowsePathResult
5607browseSimplifiedBrowsePath(UA_Server *server, const UA_NodeId origin,
5608 size_t browsePathSize, const UA_QualifiedName *browsePath);
5609
5610UA_StatusCode
5611writeObjectProperty(UA_Server *server, const UA_NodeId objectId,
5612 const UA_QualifiedName propertyName, const UA_Variant value);
5613
5614UA_StatusCode
5615writeObjectProperty_scalar(UA_Server *server, const UA_NodeId objectId,
5616 const UA_QualifiedName propertyName,
5617 const void *value, const UA_DataType *type);
5618
5619UA_StatusCode
5620getNodeContext(UA_Server *server, UA_NodeId nodeId, void **nodeContext);
5621
5622UA_StatusCode
5623setNodeContext(UA_Server *server, UA_NodeId nodeId, void *nodeContext);
5624
5625void
5626removeCallback(UA_Server *server, UA_UInt64 callbackId);
5627
5628UA_StatusCode
5629changeRepeatedCallbackInterval(UA_Server *server, UA_UInt64 callbackId,
5630 UA_Double interval_ms);
5631
5632UA_StatusCode
5633addRepeatedCallback(UA_Server *server, UA_ServerCallback callback,
5634 void *data, UA_Double interval_ms, UA_UInt64 *callbackId);
5635
5636#ifdef UA_ENABLE_DISCOVERY
5637UA_ServerComponent *
5638UA_DiscoveryManager_new(UA_Server *server);
5639#endif
5640
5641UA_String
5642securityPolicyUriPostfix(const UA_String uri);
5643
5644UA_ServerComponent *
5645UA_BinaryProtocolManager_new(UA_Server *server);
5646
5647/***********/
5648/* RefTree */
5649/***********/
5650
5651/* A RefTree is a sorted set of NodeIds that ensures we consider each node just
5652 * once. It holds a single array for both the ExpandedNodeIds and the entries of
5653 * a tree-structure for fast lookup. A single realloc operation (with some
5654 * pointer repairing) can be used to increase the capacity of the RefTree.
5655 *
5656 * When the RefTree is complete, the tree-part at the end of the targets array
5657 * can be ignored / cut away to use it as a simple ExpandedNodeId array.
5658 *
5659 * The layout of the targets array is as follows:
5660 *
5661 * | Targets [ExpandedNodeId, n times] | Tree [RefEntry, n times] | */
5662
5663#define UA_REFTREE_INITIAL_SIZE 16
5664
5665typedef struct RefEntry {
5666 ZIP_ENTRY(RefEntry) zipfields;
5667 const UA_ExpandedNodeId *target;
5668 UA_UInt32 targetHash; /* Hash of the target nodeid */
5669} RefEntry;
5670
5671ZIP_HEAD(RefHead, RefEntry);
5672typedef struct RefHead RefHead;
5673
5674typedef struct {
5675 UA_ExpandedNodeId *targets;
5676 RefHead head;
5677 size_t capacity; /* available space */
5678 size_t size; /* used space */
5679} RefTree;
5680
5681UA_StatusCode UA_FUNC_ATTR_WARN_UNUSED_RESULT
5682RefTree_init(RefTree *rt);
5683
5684void RefTree_clear(RefTree *rt);
5685
5686UA_StatusCode UA_FUNC_ATTR_WARN_UNUSED_RESULT
5687RefTree_addNodeId(RefTree *rt, const UA_NodeId *target, UA_Boolean *duplicate);
5688
5689UA_Boolean
5690RefTree_contains(RefTree *rt, const UA_ExpandedNodeId *target);
5691
5692UA_Boolean
5693RefTree_containsNodeId(RefTree *rt, const UA_NodeId *target);
5694
5695/***************************************/
5696/* Check Information Model Consistency */
5697/***************************************/
5698
5699/* Read a node attribute in the context of a "checked-out" node. So the
5700 * attribute will not be copied when possible. The variant then points into the
5701 * node and has UA_VARIANT_DATA_NODELETE set. */
5702void
5703ReadWithNode(const UA_Node *node, UA_Server *server, UA_Session *session,
5704 UA_TimestampsToReturn timestampsToReturn,
5705 const UA_ReadValueId *id, UA_DataValue *v);
5706
5707UA_StatusCode
5708readValueAttribute(UA_Server *server, UA_Session *session,
5709 const UA_VariableNode *vn, UA_DataValue *v);
5710
5711/* Test whether the value matches a variable definition given by
5712 * - datatype
5713 * - valuerank
5714 * - array dimensions.
5715 * Sometimes it can be necessary to transform the content of the value, e.g.
5716 * byte array to bytestring or uint32 to some enum. If editableValue is non-NULL,
5717 * we try to create a matching variant that points to the original data.
5718 *
5719 * The reason is set whenever the return value is false */
5720UA_Boolean
5721compatibleValue(UA_Server *server, UA_Session *session, const UA_NodeId *targetDataTypeId,
5722 UA_Int32 targetValueRank, size_t targetArrayDimensionsSize,
5723 const UA_UInt32 *targetArrayDimensions, const UA_Variant *value,
5724 const UA_NumericRange *range, const char **reason);
5725
5726/* Is the DataType compatible */
5727UA_Boolean
5728compatibleDataTypes(UA_Server *server, const UA_NodeId *dataType,
5729 const UA_NodeId *constraintDataType);
5730
5731/* Set to the target type if compatible */
5732void
5733adjustValueType(UA_Server *server, UA_Variant *value,
5734 const UA_NodeId *targetDataTypeId);
5735
5736/* Is the Value compatible with the DataType? Can perform additional checks
5737 * compared to compatibleDataTypes. */
5738UA_Boolean
5739compatibleValueDataType(UA_Server *server, const UA_DataType *dataType,
5740 const UA_NodeId *constraintDataType);
5741
5742
5743UA_Boolean
5744compatibleArrayDimensions(size_t constraintArrayDimensionsSize,
5745 const UA_UInt32 *constraintArrayDimensions,
5746 size_t testArrayDimensionsSize,
5747 const UA_UInt32 *testArrayDimensions);
5748
5749UA_Boolean
5750compatibleValueArrayDimensions(const UA_Variant *value, size_t targetArrayDimensionsSize,
5751 const UA_UInt32 *targetArrayDimensions);
5752
5753UA_Boolean
5754compatibleValueRankArrayDimensions(UA_Server *server, UA_Session *session,
5755 UA_Int32 valueRank, size_t arrayDimensionsSize);
5756
5757UA_Boolean
5758compatibleValueRanks(UA_Int32 valueRank, UA_Int32 constraintValueRank);
5759
5760struct BrowseOpts {
5761 UA_UInt32 maxReferences;
5762 UA_Boolean recursive;
5763};
5764
5765void
5766Operation_Browse(UA_Server *server, UA_Session *session, const UA_UInt32 *maxrefs,
5767 const UA_BrowseDescription *descr, UA_BrowseResult *result);
5768
5769/************/
5770/* AddNodes */
5771/************/
5772
5773UA_StatusCode
5774addNode(UA_Server *server, const UA_NodeClass nodeClass,
5775 const UA_NodeId requestedNewNodeId,
5776 const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
5777 const UA_QualifiedName browseName, const UA_NodeId typeDefinition,
5778 const void *attr, const UA_DataType *attributeType,
5779 void *nodeContext, UA_NodeId *outNewNodeId);
5780
5781UA_StatusCode
5782addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
5783 const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
5784 const UA_QualifiedName browseName,
5785 const UA_MethodAttributes *attr, UA_MethodCallback method,
5786 size_t inputArgumentsSize, const UA_Argument *inputArguments,
5787 const UA_NodeId inputArgumentsRequestedNewNodeId,
5788 UA_NodeId *inputArgumentsOutNewNodeId,
5789 size_t outputArgumentsSize, const UA_Argument *outputArguments,
5790 const UA_NodeId outputArgumentsRequestedNewNodeId,
5791 UA_NodeId *outputArgumentsOutNewNodeId,
5792 void *nodeContext, UA_NodeId *outNewNodeId);
5793
5794UA_StatusCode
5795addNode_begin(UA_Server *server, const UA_NodeClass nodeClass,
5796 const UA_NodeId requestedNewNodeId, const UA_NodeId parentNodeId,
5797 const UA_NodeId referenceTypeId, const UA_QualifiedName browseName,
5798 const UA_NodeId typeDefinition, const void *attr,
5799 const UA_DataType *attributeType, void *nodeContext,
5800 UA_NodeId *outNewNodeId);
5801
5802/* Creates a new node in the nodestore. */
5803UA_StatusCode
5804addNode_raw(UA_Server *server, UA_Session *session, void *nodeContext,
5805 const UA_AddNodesItem *item, UA_NodeId *outNewNodeId);
5806
5807/* Check the reference to the parent node; Add references. */
5808UA_StatusCode
5809addNode_addRefs(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
5810 const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId,
5811 const UA_NodeId *typeDefinitionId);
5812
5813/* Type-check type-definition; Run the constructors */
5814UA_StatusCode
5815addNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId);
5816
5817/**********************/
5818/* Create Namespace 0 */
5819/**********************/
5820
5821UA_StatusCode initNS0(UA_Server *server);
5822
5823#ifdef UA_ENABLE_DIAGNOSTICS
5824void createSessionObject(UA_Server *server, UA_Session *session);
5825
5826void createSubscriptionObject(UA_Server *server, UA_Session *session,
5827 UA_Subscription *sub);
5828
5829UA_StatusCode
5830readDiagnostics(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
5831 const UA_NodeId *nodeId, void *nodeContext, UA_Boolean sourceTimestamp,
5832 const UA_NumericRange *range, UA_DataValue *value);
5833
5834UA_StatusCode
5835readSubscriptionDiagnosticsArray(UA_Server *server,
5836 const UA_NodeId *sessionId, void *sessionContext,
5837 const UA_NodeId *nodeId, void *nodeContext,
5838 UA_Boolean sourceTimestamp,
5839 const UA_NumericRange *range, UA_DataValue *value);
5840
5841UA_StatusCode
5842readSessionDiagnosticsArray(UA_Server *server,
5843 const UA_NodeId *sessionId, void *sessionContext,
5844 const UA_NodeId *nodeId, void *nodeContext,
5845 UA_Boolean sourceTimestamp,
5846 const UA_NumericRange *range, UA_DataValue *value);
5847
5848UA_StatusCode
5849readSessionSecurityDiagnostics(UA_Server *server,
5850 const UA_NodeId *sessionId, void *sessionContext,
5851 const UA_NodeId *nodeId, void *nodeContext,
5852 UA_Boolean sourceTimestamp,
5853 const UA_NumericRange *range, UA_DataValue *value);
5854#endif
5855
5856/***************************/
5857/* Nodestore Access Macros */
5858/***************************/
5859
5860#define UA_NODESTORE_NEW(server, nodeClass) \
5861 server->config.nodestore.newNode(server->config.nodestore.context, nodeClass)
5862
5863#define UA_NODESTORE_DELETE(server, node) \
5864 server->config.nodestore.deleteNode(server->config.nodestore.context, node)
5865
5866/* Get the node with all attributes and references */
5867static UA_INLINE const UA_Node *
5868UA_NODESTORE_GET(UA_Server *server, const UA_NodeId *nodeId) {
5869 return server->config.nodestore.
5870 getNode(server->config.nodestore.context, nodeId, UA_NODEATTRIBUTESMASK_ALL,
5871 UA_REFERENCETYPESET_ALL, UA_BROWSEDIRECTION_BOTH);
5872}
5873
5874/* Get the node with all attributes and references */
5875static UA_INLINE const UA_Node *
5876UA_NODESTORE_GETFROMREF(UA_Server *server, UA_NodePointer target) {
5877 return server->config.nodestore.
5878 getNodeFromPtr(server->config.nodestore.context, target, UA_NODEATTRIBUTESMASK_ALL,
5879 UA_REFERENCETYPESET_ALL, UA_BROWSEDIRECTION_BOTH);
5880}
5881
5882#define UA_NODESTORE_GET_SELECTIVE(server, nodeid, attrMask, refs, refDirs) \
5883 server->config.nodestore.getNode(server->config.nodestore.context, \
5884 nodeid, attrMask, refs, refDirs)
5885
5886#define UA_NODESTORE_GETFROMREF_SELECTIVE(server, target, attrMask, refs, refDirs) \
5887 server->config.nodestore.getNodeFromPtr(server->config.nodestore.context, \
5888 target, attrMask, refs, refDirs)
5889
5890#define UA_NODESTORE_RELEASE(server, node) \
5891 server->config.nodestore.releaseNode(server->config.nodestore.context, node)
5892
5893#define UA_NODESTORE_GETCOPY(server, nodeid, outnode) \
5894 server->config.nodestore.getNodeCopy(server->config.nodestore.context, \
5895 nodeid, outnode)
5896
5897#define UA_NODESTORE_INSERT(server, node, addedNodeId) \
5898 server->config.nodestore.insertNode(server->config.nodestore.context, \
5899 node, addedNodeId)
5900
5901#define UA_NODESTORE_REPLACE(server, node) \
5902 server->config.nodestore.replaceNode(server->config.nodestore.context, node)
5903
5904#define UA_NODESTORE_REMOVE(server, nodeId) \
5905 server->config.nodestore.removeNode(server->config.nodestore.context, nodeId)
5906
5907#define UA_NODESTORE_GETREFERENCETYPEID(server, index) \
5908 server->config.nodestore.getReferenceTypeId(server->config.nodestore.context, \
5909 index)
5910
5911/* Handling of Locales */
5912
5913/* Returns a shallow copy */
5914UA_LocalizedText
5915UA_Session_getNodeDisplayName(const UA_Session *session,
5916 const UA_NodeHead *head);
5917
5918UA_LocalizedText
5919UA_Session_getNodeDescription(const UA_Session *session,
5920 const UA_NodeHead *head);
5921
5922UA_StatusCode
5923UA_Node_insertOrUpdateDisplayName(UA_NodeHead *head,
5924 const UA_LocalizedText *value);
5925
5926UA_StatusCode
5927UA_Node_insertOrUpdateDescription(UA_NodeHead *head,
5928 const UA_LocalizedText *value);
5929
5930_UA_END_DECLS
5931
5932
5933/**** amalgamated original file "/src/server/ua_services.h" ****/
5934
5935/* This Source Code Form is subject to the terms of the Mozilla Public
5936 * License, v. 2.0. If a copy of the MPL was not distributed with this
5937 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5938 *
5939 * Copyright 2014-2017, 2024 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
5940 * Copyright 2014-2017 (c) Florian Palm
5941 * Copyright 2015 (c) Sten Grüner
5942 * Copyright 2014 (c) LEvertz
5943 * Copyright 2015 (c) Chris Iatrou
5944 * Copyright 2015 (c) Christian Fimmers
5945 * Copyright 2015-2016 (c) Oleksiy Vasylyev
5946 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
5947 */
5948
5949
5950
5951_UA_BEGIN_DECLS
5952
5953typedef void (*UA_Service)(UA_Server*, UA_Session*,
5954 const void *request, void *response);
5955
5956typedef void (*UA_ChannelService)(UA_Server*, UA_SecureChannel*,
5957 const void *request, void *response);
5958
5959/** Discovery Service Set **/
5960void Service_FindServers(UA_Server *server, UA_Session *session,
5961 const UA_FindServersRequest *request,
5962 UA_FindServersResponse *response);
5963
5964void Service_GetEndpoints(UA_Server *server, UA_Session *session,
5965 const UA_GetEndpointsRequest *request,
5966 UA_GetEndpointsResponse *response);
5967
5968#ifdef UA_ENABLE_DISCOVERY
5969
5970void Service_RegisterServer(UA_Server *server, UA_Session *session,
5971 const UA_RegisterServerRequest *request,
5972 UA_RegisterServerResponse *response);
5973
5974void Service_RegisterServer2(UA_Server *server, UA_Session *session,
5975 const UA_RegisterServer2Request *request,
5976 UA_RegisterServer2Response *response);
5977
5978# ifdef UA_ENABLE_DISCOVERY_MULTICAST
5979
5980void Service_FindServersOnNetwork(UA_Server *server, UA_Session *session,
5981 const UA_FindServersOnNetworkRequest *request,
5982 UA_FindServersOnNetworkResponse *response);
5983
5984# endif /* UA_ENABLE_DISCOVERY_MULTICAST */
5985
5986#endif /* UA_ENABLE_DISCOVERY */
5987
5988/** SecureChannel Service Set **/
5989void Service_OpenSecureChannel(UA_Server *server, UA_SecureChannel* channel,
5990 UA_OpenSecureChannelRequest *request,
5991 UA_OpenSecureChannelResponse *response);
5992
5993void Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel);
5994
5995/** Session Service Set **/
5996void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
5997 const UA_CreateSessionRequest *request,
5998 UA_CreateSessionResponse *response);
5999
6000void Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel,
6001 const UA_ActivateSessionRequest *request,
6002 UA_ActivateSessionResponse *response);
6003
6004void Service_CloseSession(UA_Server *server, UA_SecureChannel *channel,
6005 const UA_CloseSessionRequest *request,
6006 UA_CloseSessionResponse *response);
6007
6008void Service_Cancel(UA_Server *server, UA_Session *session,
6009 const UA_CancelRequest *request,
6010 UA_CancelResponse *response);
6011
6012/** NodeManagement Service Set **/
6013void Service_AddNodes(UA_Server *server, UA_Session *session,
6014 const UA_AddNodesRequest *request,
6015 UA_AddNodesResponse *response);
6016
6017void Service_AddReferences(UA_Server *server, UA_Session *session,
6018 const UA_AddReferencesRequest *request,
6019 UA_AddReferencesResponse *response);
6020
6021void Service_DeleteNodes(UA_Server *server, UA_Session *session,
6022 const UA_DeleteNodesRequest *request,
6023 UA_DeleteNodesResponse *response);
6024
6025void Service_DeleteReferences(UA_Server *server, UA_Session *session,
6026 const UA_DeleteReferencesRequest *request,
6027 UA_DeleteReferencesResponse *response);
6028
6029/** View Service Set **/
6030void Service_Browse(UA_Server *server, UA_Session *session,
6031 const UA_BrowseRequest *request,
6032 UA_BrowseResponse *response);
6033
6034void Service_BrowseNext(UA_Server *server, UA_Session *session,
6035 const UA_BrowseNextRequest *request,
6036 UA_BrowseNextResponse *response);
6037
6038void Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *session,
6039 const UA_TranslateBrowsePathsToNodeIdsRequest *request,
6040 UA_TranslateBrowsePathsToNodeIdsResponse *response);
6041
6042void Service_RegisterNodes(UA_Server *server, UA_Session *session,
6043 const UA_RegisterNodesRequest *request,
6044 UA_RegisterNodesResponse *response);
6045
6046void Service_UnregisterNodes(UA_Server *server, UA_Session *session,
6047 const UA_UnregisterNodesRequest *request,
6048 UA_UnregisterNodesResponse *response);
6049
6050/** Query Service Set (not implemented) **/
6051
6052/** Attribute Service Set **/
6053void Service_Read(UA_Server *server, UA_Session *session,
6054 const UA_ReadRequest *request,
6055 UA_ReadResponse *response);
6056
6057void Service_Write(UA_Server *server, UA_Session *session,
6058 const UA_WriteRequest *request,
6059 UA_WriteResponse *response);
6060
6061#ifdef UA_ENABLE_HISTORIZING
6062void Service_HistoryRead(UA_Server *server, UA_Session *session,
6063 const UA_HistoryReadRequest *request,
6064 UA_HistoryReadResponse *response);
6065
6066void Service_HistoryUpdate(UA_Server *server, UA_Session *session,
6067 const UA_HistoryUpdateRequest *request,
6068 UA_HistoryUpdateResponse *response);
6069#endif
6070
6071/** Method Service Set **/
6072#ifdef UA_ENABLE_METHODCALLS
6073void Service_Call(UA_Server *server, UA_Session *session,
6074 const UA_CallRequest *request,
6075 UA_CallResponse *response);
6076
6077# if UA_MULTITHREADING >= 100
6078void Service_CallAsync(UA_Server *server, UA_Session *session, UA_UInt32 requestId,
6079 const UA_CallRequest *request, UA_CallResponse *response,
6080 UA_Boolean *finished);
6081#endif
6082#endif
6083
6084#ifdef UA_ENABLE_SUBSCRIPTIONS
6085
6086/** MonitoredItem Service Set **/
6087void Service_CreateMonitoredItems(UA_Server *server, UA_Session *session,
6088 const UA_CreateMonitoredItemsRequest *request,
6089 UA_CreateMonitoredItemsResponse *response);
6090
6091void Service_DeleteMonitoredItems(UA_Server *server, UA_Session *session,
6092 const UA_DeleteMonitoredItemsRequest *request,
6093 UA_DeleteMonitoredItemsResponse *response);
6094
6095void Service_ModifyMonitoredItems(UA_Server *server, UA_Session *session,
6096 const UA_ModifyMonitoredItemsRequest *request,
6097 UA_ModifyMonitoredItemsResponse *response);
6098
6099void Service_SetMonitoringMode(UA_Server *server, UA_Session *session,
6100 const UA_SetMonitoringModeRequest *request,
6101 UA_SetMonitoringModeResponse *response);
6102
6103void Service_SetTriggering(UA_Server *server, UA_Session *session,
6104 const UA_SetTriggeringRequest *request,
6105 UA_SetTriggeringResponse *response);
6106
6107/** Subscription Service Set **/
6108void Service_CreateSubscription(UA_Server *server, UA_Session *session,
6109 const UA_CreateSubscriptionRequest *request,
6110 UA_CreateSubscriptionResponse *response);
6111
6112void Service_ModifySubscription(UA_Server *server, UA_Session *session,
6113 const UA_ModifySubscriptionRequest *request,
6114 UA_ModifySubscriptionResponse *response);
6115
6116void Service_SetPublishingMode(UA_Server *server, UA_Session *session,
6117 const UA_SetPublishingModeRequest *request,
6118 UA_SetPublishingModeResponse *response);
6119
6120/* Special async service. Do not answer if StatusCode == Good. */
6121UA_StatusCode
6122Service_Publish(UA_Server *server, UA_Session *session,
6123 const UA_PublishRequest *request, UA_UInt32 requestId);
6124
6125void Service_Republish(UA_Server *server, UA_Session *session,
6126 const UA_RepublishRequest *request,
6127 UA_RepublishResponse *response);
6128
6129void Service_DeleteSubscriptions(UA_Server *server, UA_Session *session,
6130 const UA_DeleteSubscriptionsRequest *request,
6131 UA_DeleteSubscriptionsResponse *response);
6132
6133void Service_TransferSubscriptions(UA_Server *server, UA_Session *session,
6134 const UA_TransferSubscriptionsRequest *request,
6135 UA_TransferSubscriptionsResponse *response);
6136
6137#endif /* UA_ENABLE_SUBSCRIPTIONS */
6138
6139_UA_END_DECLS
6140
6141
6142/**** amalgamated original file "/src/client/ua_client_internal.h" ****/
6143
6144/* This Source Code Form is subject to the terms of the Mozilla Public
6145 * License, v. 2.0. If a copy of the MPL was not distributed with this
6146 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6147 *
6148 * Copyright 2015-2016 (c) Sten Grüner
6149 * Copyright 2015-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
6150 * Copyright 2015 (c) Oleksiy Vasylyev
6151 * Copyright 2016-2017 (c) Florian Palm
6152 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
6153 * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB
6154 */
6155
6156
6157#define UA_INTERNAL
6158
6159
6160_UA_BEGIN_DECLS
6161
6162/**************************/
6163/* Subscriptions Handling */
6164/**************************/
6165
6166typedef struct UA_Client_NotificationsAckNumber {
6167 LIST_ENTRY(UA_Client_NotificationsAckNumber) listEntry;
6168 UA_SubscriptionAcknowledgement subAck;
6169} UA_Client_NotificationsAckNumber;
6170
6171typedef struct UA_Client_MonitoredItem {
6172 ZIP_ENTRY(UA_Client_MonitoredItem) zipfields;
6173 UA_UInt32 monitoredItemId;
6174 UA_UInt32 clientHandle;
6175 void *context;
6176 UA_Client_DeleteMonitoredItemCallback deleteCallback;
6177 union {
6178 UA_Client_DataChangeNotificationCallback dataChangeCallback;
6179 UA_Client_EventNotificationCallback eventCallback;
6180 } handler;
6181 UA_Boolean isEventMonitoredItem; /* Otherwise a DataChange MoniitoredItem */
6182} UA_Client_MonitoredItem;
6183
6184ZIP_HEAD(MonitorItemsTree, UA_Client_MonitoredItem);
6185typedef struct MonitorItemsTree MonitorItemsTree;
6186
6187typedef struct UA_Client_Subscription {
6188 LIST_ENTRY(UA_Client_Subscription) listEntry;
6189 UA_UInt32 subscriptionId;
6190 void *context;
6191 UA_Double publishingInterval;
6192 UA_UInt32 maxKeepAliveCount;
6193 UA_Client_StatusChangeNotificationCallback statusChangeCallback;
6194 UA_Client_DeleteSubscriptionCallback deleteCallback;
6195 UA_UInt32 sequenceNumber;
6196 UA_DateTime lastActivity;
6197 MonitorItemsTree monitoredItems;
6198} UA_Client_Subscription;
6199
6200void
6201__Client_Subscriptions_clean(UA_Client *client);
6202
6203/* Exposed for fuzzing */
6204UA_StatusCode
6205__Client_preparePublishRequest(UA_Client *client, UA_PublishRequest *request);
6206
6207void
6208__Client_Subscriptions_backgroundPublish(UA_Client *client);
6209
6210void
6211__Client_Subscriptions_backgroundPublishInactivityCheck(UA_Client *client);
6212
6213/**********/
6214/* Client */
6215/**********/
6216
6217typedef struct AsyncServiceCall {
6218 LIST_ENTRY(AsyncServiceCall) pointers;
6219 UA_UInt32 requestId; /* Unique id */
6220 UA_UInt32 requestHandle; /* Potentially non-unique if manually defined in
6221 * the request header*/
6222 UA_ClientAsyncServiceCallback callback;
6223 const UA_DataType *responseType;
6224 void *userdata;
6225 UA_DateTime start;
6226 UA_UInt32 timeout;
6227 UA_Response *syncResponse; /* If non-null, then this is the synchronous
6228 * response to be filled. Set back to null to
6229 * indicate that the response was filled. */
6230} AsyncServiceCall;
6231
6232typedef LIST_HEAD(UA_AsyncServiceList, AsyncServiceCall) UA_AsyncServiceList;
6233
6234void
6235__Client_AsyncService_removeAll(UA_Client *client, UA_StatusCode statusCode);
6236
6237typedef struct CustomCallback {
6238 UA_UInt32 callbackId;
6239
6240 UA_ClientAsyncServiceCallback userCallback;
6241 void *userData;
6242
6243 void *clientData;
6244} CustomCallback;
6245
6246struct UA_Client {
6247 UA_ClientConfig config;
6248
6249 /* Callback ID to remove it from the EventLoop */
6250 UA_UInt64 houseKeepingCallbackId;
6251
6252 /* Overall connection status */
6253 UA_StatusCode connectStatus;
6254
6255 /* Old status to notify only changes */
6256 UA_SecureChannelState oldChannelState;
6257 UA_SessionState oldSessionState;
6258 UA_StatusCode oldConnectStatus;
6259
6260 UA_Boolean findServersHandshake; /* Ongoing FindServers */
6261 UA_Boolean endpointsHandshake; /* Ongoing GetEndpoints */
6262
6263 /* The discoveryUrl can be different from the EndpointUrl in the client
6264 * configuration. The EndpointUrl is used to connect initially, then the
6265 * DiscoveryUrl is selected via FindServers. This triggers a reconnect if
6266 * EndpointUrl != DiscoveryUrl. */
6267 UA_String discoveryUrl;
6268
6269 /* Contains the Server description, etc. */
6270 UA_EndpointDescription endpoint;
6271
6272 /* SecureChannel */
6273 UA_SecureChannel channel;
6274 UA_UInt32 requestId; /* Unique, internally defined for each request */
6275 UA_DateTime nextChannelRenewal;
6276
6277 /* Reverse connect (listen) connections */
6278 UA_ConnectionManager *reverseConnectionCM;
6279 uintptr_t reverseConnectionIds[16];
6280
6281 /* Session */
6282 UA_SessionState sessionState;
6283 UA_NodeId authenticationToken;
6284 UA_UInt32 requestHandle; /* Unique handles >100,000 are generated if the
6285 * request header contains a zero-handle. */
6286 UA_ByteString serverSessionNonce;
6287 UA_ByteString clientSessionNonce;
6288
6289 /* Connectivity check */
6290 UA_DateTime lastConnectivityCheck;
6291 UA_Boolean pendingConnectivityCheck;
6292
6293 /* Async Service */
6294 UA_AsyncServiceList asyncServiceCalls;
6295
6296 /* Subscriptions */
6297 LIST_HEAD(, UA_Client_NotificationsAckNumber) pendingNotificationsAcks;
6298 LIST_HEAD(, UA_Client_Subscription) subscriptions;
6299 UA_UInt32 monitoredItemHandles;
6300 UA_UInt16 currentlyOutStandingPublishRequests;
6301
6302 /* Internal locking for thread-safety. Methods starting with UA_Client_ that
6303 * are marked with UA_THREADSAFE take the lock. The lock is released before
6304 * dropping into the EventLoop and before calling user-defined callbacks.
6305 * That way user-defined callbacks can themselves call thread-safe client
6306 * methods. */
6307#if UA_MULTITHREADING >= 100
6308 UA_Lock clientMutex;
6309#endif
6310};
6311
6312/* In order to prevent deadlocks between the EventLoop mutex and the
6313 * client-mutex, we always take the EventLoop mutex first. */
6314
6315void lockClient(UA_Client *client);
6316void unlockClient(UA_Client *client);
6317
6318UA_StatusCode
6319__Client_AsyncService(UA_Client *client, const void *request,
6320 const UA_DataType *requestType,
6321 UA_ClientAsyncServiceCallback callback,
6322 const UA_DataType *responseType,
6323 void *userdata, UA_UInt32 *requestId);
6324
6325void
6326__Client_Service(UA_Client *client, const void *request,
6327 const UA_DataType *requestType, void *response,
6328 const UA_DataType *responseType);
6329
6330UA_StatusCode
6331__UA_Client_startup(UA_Client *client);
6332
6333UA_StatusCode
6334__Client_renewSecureChannel(UA_Client *client);
6335
6336UA_StatusCode
6337processServiceResponse(UA_Client *client, UA_SecureChannel *channel,
6338 UA_MessageType messageType, UA_UInt32 requestId,
6339 UA_ByteString *message);
6340
6341UA_StatusCode connectInternal(UA_Client *client, UA_Boolean async);
6342UA_StatusCode connectSecureChannel(UA_Client *client, const char *endpointUrl);
6343UA_Boolean isFullyConnected(UA_Client *client);
6344void connectSync(UA_Client *client);
6345void notifyClientState(UA_Client *client);
6346void processRHEMessage(UA_Client *client, const UA_ByteString *chunk);
6347void processERRResponse(UA_Client *client, const UA_ByteString *chunk);
6348void processACKResponse(UA_Client *client, const UA_ByteString *chunk);
6349void processOPNResponse(UA_Client *client, const UA_ByteString *message);
6350void closeSecureChannel(UA_Client *client);
6351void cleanupSession(UA_Client *client);
6352
6353void
6354Client_warnEndpointsResult(UA_Client *client,
6355 const UA_GetEndpointsResponse *response,
6356 const UA_String *endpointUrl);
6357
6358_UA_END_DECLS
6359
6360
6361/**** amalgamated original file "/build/src_generated/open62541/namespace0_generated.h" ****/
6362
6363/* WARNING: This is a generated file.
6364 * Any manual changes will be overwritten. */
6365
6366#ifndef NAMESPACE0_GENERATED_H_
6367#define NAMESPACE0_GENERATED_H_
6368
6369
6370#ifdef UA_ENABLE_AMALGAMATION
6371
6372/* The following declarations are in the open62541.c file so here's needed when compiling nodesets externally */
6373
6374# ifndef UA_INTERNAL //this definition is needed to hide this code in the amalgamated .c file
6375
6376typedef UA_StatusCode (*UA_exchangeEncodeBuffer)(void *handle, UA_Byte **bufPos,
6377 const UA_Byte **bufEnd);
6378
6379UA_StatusCode
6380UA_encodeBinary(const void *src, const UA_DataType *type,
6381 UA_Byte **bufPos, const UA_Byte **bufEnd,
6382 UA_exchangeEncodeBuffer exchangeCallback,
6383 void *exchangeHandle) UA_FUNC_ATTR_WARN_UNUSED_RESULT;
6384
6385UA_StatusCode
6386UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst,
6387 const UA_DataType *type, size_t customTypesSize,
6388 const UA_DataType *customTypes) UA_FUNC_ATTR_WARN_UNUSED_RESULT;
6389
6390size_t
6391UA_calcSizeBinary(void *p, const UA_DataType *type);
6392
6393const UA_DataType *
6394UA_findDataTypeByBinary(const UA_NodeId *typeId);
6395
6396# endif // UA_INTERNAL
6397
6398#else // UA_ENABLE_AMALGAMATION
6399#endif
6400
6401
6402
6403
6404_UA_BEGIN_DECLS
6405
6406extern UA_StatusCode namespace0_generated(UA_Server *server);
6407
6408_UA_END_DECLS
6409
6410#endif /* NAMESPACE0_GENERATED_H_ */
6411
6412/**** amalgamated original file "/deps/cj5.h" ****/
6413
6414// MIT License
6415//
6416// Copyright (c) 2020 Sepehr Taghdisian
6417// Copyright (c) 2022 Julius Pfrommer
6418//
6419// Permission is hereby granted, free of charge, to any person obtaining a copy
6420// of this software and associated documentation files (the "Software"), to deal
6421// in the Software without restriction, including without limitation the rights
6422// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6423// copies of the Software, and to permit persons to whom the Software is
6424// furnished to do so, subject to the following conditions:
6425//
6426// The above copyright notice and this permission notice shall be included in all
6427// copies or substantial portions of the Software.
6428//
6429// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6430// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6431// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
6432// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
6433// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
6434// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
6435// SOFTWARE.
6436//
6437// Very minimal single header JSON5 parser in C99, dervied from jsmn This is the
6438// modified version of jsmn library Thus main parts of the code is taken from
6439// jsmn project (https://github.com/zserge/jsmn).
6440//
6441// Compliance with JSON5:
6442// [x] Object keys may be an ECMAScript 5.1 IdentifierName.
6443// [x] Objects may have a single trailing comma.
6444// [x] Strings may be single quoted.
6445// [x] Strings may span multiple lines by escaping new line characters.
6446// [x] Strings may include character escapes.
6447// [x] Numbers may be hexadecimal.
6448// [x] Numbers may have a leading or trailing decimal point.
6449// [x] Numbers may be IEEE 754 positive infinity, negative infinity, and NaN.
6450// [x] Numbers may begin with an explicit plus sign.
6451// [x] Single and multi-line comments are allowed.
6452// [x] Additional white space characters are allowed.
6453//
6454// Extensions to JSON5 (more permissive):
6455// [x] Root objects can be an array or a primitive value
6456// [x] The root object may omit the surrounding brackets
6457// [x] Hash ('#') comments out until the end of the line.
6458// [x] Strings may include unescaped utf8 bytes
6459// [x] Optionally: Stop early when the first encountered JSON element (object,
6460// array, value) has been successfully parsed. Do not return an error when
6461// the input string was not processed to its full length. This allows the
6462// detection of JSON sub-strings as part of an input "lexer".
6463//
6464// Usage:
6465// The main function to parse json is `cj5_parse`. Like in jsmn, you provide
6466// all tokens to be filled as an array and provide the maximum count The result
6467// will be return in `cj5_result` struct, and `num_tokens` will represent the
6468// actual token count that is parsed. In case of errors, cj_result.error will
6469// be set to an error code Here's a quick example of the usage.
6470//
6471// #include "cj5.h"
6472//
6473// cj5_token tokens[32];
6474// cj5_result r = cj5_parse(g_json, (int)strlen(g_json), tokens, 32, NULL);
6475// if(r.error != CJ5_ERROR_NONE) {
6476// if(r.error == CJ5_ERROR_OVERFLOW) {
6477// // you can use r.num_tokens to determine the actual token count and reparse
6478// printf("Error: line: %d, col: %d\n", r.error_line, r.error_code);
6479// }
6480// }
6481
6482#ifndef __CJ5_H_
6483#define __CJ5_H_
6484
6485#ifdef __cplusplus
6486# define CJ5_API extern "C"
6487#else
6488# define CJ5_API
6489#endif
6490
6491#if !defined(_MSC_VER) || _MSC_VER >= 1800
6492# include <stdint.h>
6493# include <stdbool.h>
6494#else
6495# if !defined(__bool_true_false_are_defined)
6496# define bool unsigned char
6497# define true 1
6498# define false 0
6499# define __bool_true_false_are_defined
6500# endif
6501#endif
6502
6503typedef enum cj5_token_type {
6504 CJ5_TOKEN_OBJECT = 0,
6505 CJ5_TOKEN_ARRAY,
6506 CJ5_TOKEN_NUMBER,
6507 CJ5_TOKEN_STRING,
6508 CJ5_TOKEN_BOOL,
6509 CJ5_TOKEN_NULL
6510} cj5_token_type;
6511
6512typedef enum cj5_error_code {
6513 CJ5_ERROR_NONE = 0,
6514 CJ5_ERROR_INVALID, // Invalid character/syntax
6515 CJ5_ERROR_INCOMPLETE, // Incomplete JSON string
6516 CJ5_ERROR_OVERFLOW, // Token buffer overflow (see cj5_result.num_tokens)
6517 CJ5_ERROR_NOTFOUND
6518} cj5_error_code;
6519
6520typedef struct cj5_token {
6521 cj5_token_type type;
6522 unsigned int start; // Start position in the json5 string
6523 unsigned int end; // Position of the last character (included)
6524 unsigned int size; // For objects and arrays the number of direct
6525 // children. Note that this is *not* the number of
6526 // overall (recursively nested) child tokens. For
6527 // other tokens the length of token in the json
6528 // encoding.
6529 unsigned int parent_id; // The root object is at position zero. It is an
6530 // object that has itself as parent.
6531} cj5_token;
6532
6533typedef struct cj5_result {
6534 cj5_error_code error;
6535 unsigned int error_line;
6536 unsigned int error_col;
6537 unsigned int num_tokens;
6538 const cj5_token* tokens;
6539 const char* json5;
6540} cj5_result;
6541
6542typedef struct cj5_options {
6543 bool stop_early; /* Return when the first element was parsed. Otherwise an
6544 * error is returned if the input was not fully
6545 * processed. (default: false) */
6546} cj5_options;
6547
6548/* Options can be NULL */
6549CJ5_API cj5_result
6550cj5_parse(const char *json5, unsigned int len,
6551 cj5_token *tokens, unsigned int max_tokens,
6552 cj5_options *options);
6553
6554CJ5_API cj5_error_code
6555cj5_get_bool(const cj5_result *r, unsigned int tok_index, bool *out);
6556
6557CJ5_API cj5_error_code
6558cj5_get_float(const cj5_result *r, unsigned int tok_index, double *out);
6559
6560CJ5_API cj5_error_code
6561cj5_get_int(const cj5_result *r, unsigned int tok_index, int64_t *out);
6562
6563CJ5_API cj5_error_code
6564cj5_get_uint(const cj5_result *r, unsigned int tok_index, uint64_t *out);
6565
6566// Replaces escape characters, utf8 codepoints, etc.
6567// The buffer shall have a length of at least token->size + 1.
6568// Upon success, the length is written to buflen.
6569// The output string is terminated with \0.
6570CJ5_API cj5_error_code
6571cj5_get_str(const cj5_result *r, unsigned int tok_index,
6572 char *buf, unsigned int *buflen);
6573
6574// Skips the (nested) structure that starts at the current index. The index is
6575// updated accordingly. Afterwards it points to the beginning of the following
6576// structure.
6577//
6578// Attention! The index can point to the first element after the token array if
6579// the root object is skipped.
6580//
6581// Cannot fail as long as the token array is the result of cj5_parse.
6582CJ5_API void
6583cj5_skip(const cj5_result *r, unsigned int *tok_index);
6584
6585// Lookup of a key within an object (linear search).
6586// The current token (index) must point to an object.
6587// The error code CJ5_ERROR_NOTFOUND is returned if the key is not present.
6588// Otherwise the index is updated to point to the value associated with the key.
6589CJ5_API cj5_error_code
6590cj5_find(const cj5_result *r, unsigned int *tok_index, const char *key);
6591
6592#endif /* __CJ5_H_ */
6593
6594/**** amalgamated original file "/deps/parse_num.h" ****/
6595
6596#ifndef ATOI_H
6597#define ATOI_H
6598
6599#ifdef __cplusplus
6600extern "C" {
6601#endif
6602
6603#if !defined(_MSC_VER) || _MSC_VER >= 1800
6604# include <stddef.h>
6605# include <stdint.h>
6606# include <stdbool.h> /* C99 Boolean */
6607#else
6608# if !defined(__bool_true_false_are_defined)
6609# define bool unsigned char
6610# define true 1
6611# define false 0
6612# define __bool_true_false_are_defined
6613# endif
6614#endif
6615
6616/* Parse integer numbers. Returns the number of parsed digits until the first
6617 * non-valid character. Returns 0 upon failure.
6618 *
6619 * Hex numbers start with 0x.
6620 * Signed numbers may have a +/- prefix. */
6621
6622size_t parseUInt64(const char *str, size_t size, uint64_t *result);
6623size_t parseInt64(const char *str, size_t size, int64_t *result);
6624size_t parseDouble(const char *str, size_t size, double *result);
6625
6626#ifdef __cplusplus
6627}
6628#endif
6629
6630#endif /* ATOI_H */
6631
6632
6633/**** amalgamated original file "/src/ua_types_encoding_json.h" ****/
6634
6635/* This Source Code Form is subject to the terms of the Mozilla Public
6636 * License, v. 2.0. If a copy of the MPL was not distributed with this
6637 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6638 *
6639 * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
6640 * Copyright 2018 (c) Fraunhofer IOSB (Author: Lukas Meling)
6641 */
6642
6643
6644
6645
6646
6647_UA_BEGIN_DECLS
6648
6649#define UA_JSON_MAXTOKENCOUNT 256
6650#define UA_JSON_ENCODING_MAX_RECURSION 100
6651
6652typedef struct {
6653 uint8_t *pos;
6654 const uint8_t *end;
6655
6656 uint16_t depth; /* How often did we en-/decoding recurse? */
6657 UA_Boolean commaNeeded[UA_JSON_ENCODING_MAX_RECURSION];
6658 UA_Boolean useReversible;
6659 UA_Boolean calcOnly; /* Only compute the length of the decoding */
6660
6661 size_t namespacesSize;
6662 const UA_String *namespaces;
6663
6664 size_t serverUrisSize;
6665 const UA_String *serverUris;
6666
6667 UA_Boolean prettyPrint;
6668 UA_Boolean unquotedKeys;
6669 UA_Boolean stringNodeIds;
6670} CtxJson;
6671
6672UA_StatusCode writeJsonObjStart(CtxJson *ctx);
6673UA_StatusCode writeJsonObjElm(CtxJson *ctx, const char *key,
6674 const void *value, const UA_DataType *type);
6675UA_StatusCode writeJsonObjEnd(CtxJson *ctx);
6676
6677UA_StatusCode writeJsonArrStart(CtxJson *ctx);
6678UA_StatusCode writeJsonArrElm(CtxJson *ctx, const void *value,
6679 const UA_DataType *type);
6680UA_StatusCode writeJsonArrEnd(CtxJson *ctx);
6681
6682UA_StatusCode writeJsonKey(CtxJson *ctx, const char* key);
6683
6684/* Adds a comma if needed. Distinct elements go on a new line if pretty-printing
6685 * is enabled. */
6686UA_StatusCode writeJsonBeforeElement(CtxJson *ctx, UA_Boolean distinct);
6687
6688typedef struct {
6689 const char *json5;
6690 cj5_token *tokens;
6691 size_t tokensSize;
6692 size_t index;
6693 UA_Byte depth;
6694
6695 size_t namespacesSize;
6696 const UA_String *namespaces;
6697
6698 size_t serverUrisSize;
6699 const UA_String *serverUris;
6700
6701 const UA_DataTypeArray *customTypes;
6702
6703 /* Additonal data for special cases such as networkmessage/datasetmessage
6704 * Currently only used for dataSetWriterIds */
6705 size_t numCustom;
6706 void * custom;
6707 size_t currentCustomIndex;
6708} ParseCtx;
6709
6710typedef UA_StatusCode
6711(*encodeJsonSignature)(CtxJson *ctx, const void *src, const UA_DataType *type);
6712
6713typedef UA_StatusCode
6714(*decodeJsonSignature)(ParseCtx *ctx, void *dst, const UA_DataType *type);
6715
6716/* Map for decoding a Json Object. An array of this is passed to the
6717 * decodeFields function. If the key "fieldName" is found in the json object
6718 * (mark as found and) decode the value with the "function" and write result
6719 * into "fieldPointer" (destination). */
6720typedef struct {
6721 const char *fieldName;
6722 void *fieldPointer;
6723 decodeJsonSignature function;
6724 UA_Boolean found;
6725 const UA_DataType *type; /* Must be set for values that can be "null". If
6726 * the function is not set, decode via the
6727 * type->typeKind. */
6728} DecodeEntry;
6729
6730UA_StatusCode decodeFields(ParseCtx *ctx, DecodeEntry *entries, size_t entryCount);
6731
6732/* Expose the jump tables and some methods for PubSub JSON decoding */
6733extern const encodeJsonSignature encodeJsonJumpTable[UA_DATATYPEKINDS];
6734extern const decodeJsonSignature decodeJsonJumpTable[UA_DATATYPEKINDS];
6735
6736UA_StatusCode lookAheadForKey(ParseCtx *ctx, const char *search, size_t *resultIndex);
6737UA_StatusCode tokenize(ParseCtx *ctx, const UA_ByteString *src, size_t tokensSize);
6738
6739static UA_INLINE
6740cj5_token_type currentTokenType(const ParseCtx *ctx) {
6741 return ctx->tokens[ctx->index].type;
6742}
6743
6744static UA_INLINE
6745size_t getTokenLength(const cj5_token *t) {
6746 return (size_t)(1u + t->end - t->start);
6747}
6748
6749_UA_END_DECLS
6750
6751
6752/**** amalgamated original file "/src/server/ua_discovery.h" ****/
6753
6754/* This Source Code Form is subject to the terms of the Mozilla Public
6755 * License, v. 2.0. If a copy of the MPL was not distributed with this
6756 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6757 *
6758 * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
6759 * Copyright 2014, 2017 (c) Florian Palm
6760 * Copyright 2015-2016 (c) Sten Grüner
6761 * Copyright 2015 (c) Chris Iatrou
6762 * Copyright 2015-2016 (c) Oleksiy Vasylyev
6763 * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH
6764 * Copyright 2017 (c) Julian Grothoff
6765 */
6766
6767
6768
6769_UA_BEGIN_DECLS
6770
6771#ifdef UA_ENABLE_DISCOVERY
6772
6773typedef struct registeredServer_list_entry {
6774 LIST_ENTRY(registeredServer_list_entry) pointers;
6775 UA_RegisteredServer registeredServer;
6776 UA_DateTime lastSeen;
6777} registeredServer_list_entry;
6778
6779/* Store async register service calls. So we can cancel outstanding requests
6780 * during shutdown. */
6781typedef struct {
6782 UA_DelayedCallback cleanupCallback; /* delayed cleanup */
6783 UA_Server *server;
6784 UA_DiscoveryManager *dm;
6785 UA_Client *client;
6786 UA_String semaphoreFilePath;
6787 UA_Boolean unregister;
6788
6789 UA_Boolean register2;
6790 UA_Boolean shutdown;
6791 UA_Boolean connectSuccess;
6792} asyncRegisterRequest;
6793#define UA_MAXREGISTERREQUESTS 4
6794
6795#ifdef UA_ENABLE_DISCOVERY_MULTICAST
6796
6797#define UA_MAXMDNSRECVSOCKETS 8
6798
6799/**
6800 * TXT record:
6801 * [servername]-[hostname]._opcua-tcp._tcp.local. TXT path=/ caps=NA,DA,...
6802 *
6803 * A/AAAA record for all ip addresses:
6804 * [servername]-[hostname]._opcua-tcp._tcp.local. A [ip].
6805 * [hostname]. A [ip].
6806 */
6807
6808typedef struct serverOnNetwork_list_entry {
6809 LIST_ENTRY(serverOnNetwork_list_entry) pointers;
6810 UA_ServerOnNetwork serverOnNetwork;
6811 UA_DateTime created;
6812 UA_DateTime lastSeen;
6813 UA_Boolean txtSet;
6814 UA_Boolean srvSet;
6815 char* pathTmp;
6816} serverOnNetwork_list_entry;
6817
6818#define SERVER_ON_NETWORK_HASH_SIZE 1000
6819typedef struct serverOnNetwork_hash_entry {
6820 serverOnNetwork_list_entry* entry;
6821 struct serverOnNetwork_hash_entry* next;
6822} serverOnNetwork_hash_entry;
6823
6824#endif
6825
6826struct UA_DiscoveryManager {
6827 UA_ServerComponent sc;
6828
6829 UA_UInt64 discoveryCallbackId;
6830
6831 /* Taken from the server config during startup */
6832 const UA_Logger *logging;
6833 UA_ServerConfig *serverConfig;
6834
6835 /* Outstanding requests. So they can be cancelled during shutdown. */
6836 asyncRegisterRequest registerRequests[UA_MAXREGISTERREQUESTS];
6837
6838 LIST_HEAD(, registeredServer_list_entry) registeredServers;
6839 size_t registeredServersSize;
6840 UA_Server_registerServerCallback registerServerCallback;
6841 void* registerServerCallbackData;
6842
6843# ifdef UA_ENABLE_DISCOVERY_MULTICAST
6844 mdns_daemon_t *mdnsDaemon;
6845 UA_ConnectionManager *cm;
6846 uintptr_t mdnsSendConnection;
6847 uintptr_t mdnsRecvConnections[UA_MAXMDNSRECVSOCKETS];
6848 size_t mdnsRecvConnectionsSize;
6849 UA_Boolean mdnsMainSrvAdded;
6850
6851 /* Full Domain Name of server itself. Used to detect if received mDNS
6852 * message was from itself */
6853 UA_String selfFqdnMdnsRecord;
6854
6855 LIST_HEAD(, serverOnNetwork_list_entry) serverOnNetwork;
6856
6857 UA_UInt32 serverOnNetworkRecordIdCounter;
6858 UA_DateTime serverOnNetworkRecordIdLastReset;
6859
6860 /* hash mapping domain name to serverOnNetwork list entry */
6861 struct serverOnNetwork_hash_entry* serverOnNetworkHash[SERVER_ON_NETWORK_HASH_SIZE];
6862
6863 UA_Server_serverOnNetworkCallback serverOnNetworkCallback;
6864 void *serverOnNetworkCallbackData;
6865
6866 UA_UInt64 mdnsCallbackId;
6867# endif /* UA_ENABLE_DISCOVERY_MULTICAST */
6868};
6869
6870void
6871UA_DiscoveryManager_setState(UA_Server *server,
6872 UA_DiscoveryManager *dm,
6873 UA_LifecycleState state);
6874
6875#ifdef UA_ENABLE_DISCOVERY_MULTICAST
6876
6877/* Sends out a new mDNS package for the given server data. This Method is
6878 * normally called when another server calls the RegisterServer Service on this
6879 * server. Then this server is responsible to send out a new mDNS package to
6880 * announce it.
6881 *
6882 * Additionally this method also adds the given server to the internal
6883 * serversOnNetwork list so that a client finds it when calling
6884 * FindServersOnNetwork. */
6885void
6886UA_Discovery_updateMdnsForDiscoveryUrl(UA_DiscoveryManager *dm, const UA_String *serverName,
6887 const UA_MdnsDiscoveryConfiguration *mdnsConfig,
6888 const UA_String *discoveryUrl, UA_Boolean isOnline,
6889 UA_Boolean updateTxt);
6890
6891void mdns_record_received(const struct resource *r, void *data);
6892
6893void mdns_create_txt(UA_DiscoveryManager *dm, const char *fullServiceDomain,
6894 const char *path, const UA_String *capabilites,
6895 const size_t capabilitiesSize,
6896 void (*conflict)(char *host, int type, void *arg));
6897
6898void mdns_set_address_record(UA_DiscoveryManager *dm, const char *fullServiceDomain,
6899 const char *localDomain);
6900
6901mdns_record_t *
6902mdns_find_record(mdns_daemon_t *mdnsDaemon, unsigned short type,
6903 const char *host, const char *rdname);
6904
6905void startMulticastDiscoveryServer(UA_Server *server);
6906void stopMulticastDiscoveryServer(UA_Server *server);
6907void sendMulticastMessages(UA_DiscoveryManager *dm);
6908
6909UA_StatusCode
6910UA_DiscoveryManager_addEntryToServersOnNetwork(UA_DiscoveryManager *dm,
6911 const char *fqdnMdnsRecord,
6912 const char *serverName,
6913 size_t serverNameLen,
6914 struct serverOnNetwork_list_entry **addedEntry);
6915
6916UA_StatusCode
6917UA_DiscoveryManager_removeEntryFromServersOnNetwork(UA_DiscoveryManager *dm,
6918 const char *fqdnMdnsRecord,
6919 const char *serverName,
6920 size_t serverNameLen);
6921
6922#endif /* UA_ENABLE_DISCOVERY_MULTICAST */
6923
6924#endif /* UA_ENABLE_DISCOVERY */
6925
6926_UA_END_DECLS
6927
6928
6929/**** amalgamated original file "/src/ua_types.c" ****/
6930
6931/* This Source Code Form is subject to the terms of the Mozilla Public
6932 * License, v. 2.0. If a copy of the MPL was not distributed with this
6933 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6934 *
6935 * Copyright 2020 (c) Fraunhofer IOSB (Author: Andreas Ebner)
6936 * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
6937 * Copyright 2014, 2016-2017 (c) Florian Palm
6938 * Copyright 2014-2016 (c) Sten Grüner
6939 * Copyright 2014 (c) Leon Urbas
6940 * Copyright 2015 (c) Chris Iatrou
6941 * Copyright 2015 (c) Markus Graube
6942 * Copyright 2015 (c) Reza Ebrahimi
6943 * Copyright 2015-2016 (c) Oleksiy Vasylyev
6944 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
6945 * Copyright 2016 (c) Lorenz Haas
6946 */
6947
6948
6949
6950#define UA_MAX_ARRAY_DIMS 100 /* Max dimensions of an array */
6951
6952/* Datatype Handling
6953 * -----------------
6954 * This file contains handling functions for the builtin types and functions
6955 * handling of structured types and arrays. These need type descriptions in a
6956 * UA_DataType structure. The UA_DataType structures as well as all non-builtin
6957 * datatypes are autogenerated. */
6958
6959/* Global definition of NULL type instances. These are always zeroed out, as
6960 * mandated by the C/C++ standard for global values with no initializer. */
6961const UA_String UA_STRING_NULL = {0, NULL};
6962const UA_ByteString UA_BYTESTRING_NULL = {0, NULL};
6963const UA_Guid UA_GUID_NULL = {0, 0, 0, {0,0,0,0,0,0,0,0}};
6964const UA_NodeId UA_NODEID_NULL = {0, UA_NODEIDTYPE_NUMERIC, {0}};
6965const UA_ExpandedNodeId UA_EXPANDEDNODEID_NULL = {{0, UA_NODEIDTYPE_NUMERIC, {0}}, {0, NULL}, 0};
6966
6967typedef UA_StatusCode
6968(*UA_copySignature)(const void *src, void *dst, const UA_DataType *type);
6969extern const UA_copySignature copyJumpTable[UA_DATATYPEKINDS];
6970
6971typedef void (*UA_clearSignature)(void *p, const UA_DataType *type);
6972extern const UA_clearSignature clearJumpTable[UA_DATATYPEKINDS];
6973
6974typedef UA_Order
6975(*UA_orderSignature)(const void *p1, const void *p2, const UA_DataType *type);
6976extern const UA_orderSignature orderJumpTable[UA_DATATYPEKINDS];
6977
6978static UA_Order
6979nodeIdOrder(const UA_NodeId *p1, const UA_NodeId *p2, const UA_DataType *_);
6980static UA_Order
6981expandedNodeIdOrder(const UA_ExpandedNodeId *p1, const UA_ExpandedNodeId *p2,
6982 const UA_DataType *_);
6983static UA_Order
6984guidOrder(const UA_Guid *p1, const UA_Guid *p2, const UA_DataType *_);
6985
6986const UA_DataType *
6987UA_findDataTypeWithCustom(const UA_NodeId *typeId,
6988 const UA_DataTypeArray *customTypes) {
6989 /* Always look in built-in types first (may contain data types from all
6990 * namespaces).
6991 *
6992 * TODO: The standard-defined types are ordered. See if binary search is
6993 * more efficient. */
6994 for(size_t i = 0; i < UA_TYPES_COUNT; ++i) {
6995 if(nodeIdOrder(p1: &UA_TYPES[i].typeId, p2: typeId, NULL) == UA_ORDER_EQ)
6996 return &UA_TYPES[i];
6997 }
6998
6999 /* Search in the customTypes */
7000 while(customTypes) {
7001 for(size_t i = 0; i < customTypes->typesSize; ++i) {
7002 if(nodeIdOrder(p1: &customTypes->types[i].typeId, p2: typeId, NULL) == UA_ORDER_EQ)
7003 return &customTypes->types[i];
7004 }
7005 customTypes = customTypes->next;
7006 }
7007
7008 return NULL;
7009}
7010
7011const UA_DataType *
7012UA_findDataType(const UA_NodeId *typeId) {
7013 return UA_findDataTypeWithCustom(typeId, NULL);
7014}
7015
7016void
7017UA_cleanupDataTypeWithCustom(const UA_DataTypeArray *customTypes) {
7018 while (customTypes) {
7019 const UA_DataTypeArray *next = customTypes->next;
7020 if (customTypes->cleanup) {
7021 for(size_t i = 0; i < customTypes->typesSize; ++i) {
7022 const UA_DataType *type = &customTypes->types[i];
7023 UA_free(ptr: (void*)(uintptr_t)type->typeName);
7024 for(size_t j = 0; j < type->membersSize; ++j) {
7025 const UA_DataTypeMember *m = &type->members[j];
7026 UA_free(ptr: (void*)(uintptr_t)m->memberName);
7027 }
7028 UA_free(ptr: (void*)type->members);
7029 }
7030 UA_free(ptr: (void*)(uintptr_t)customTypes->types);
7031 UA_free(ptr: (void*)(uintptr_t)customTypes);
7032 }
7033 customTypes = next;
7034 }
7035}
7036
7037/*****************/
7038/* Builtin Types */
7039/*****************/
7040
7041UA_String
7042UA_String_fromChars(const char *src) {
7043 UA_String s; s.length = 0; s.data = NULL;
7044 if(!src)
7045 return s;
7046 s.length = strlen(s: src);
7047 if(s.length > 0) {
7048 s.data = (u8*)UA_malloc(size: s.length);
7049 if(UA_UNLIKELY(!s.data)) {
7050 s.length = 0;
7051 return s;
7052 }
7053 memcpy(dest: s.data, src: src, n: s.length);
7054 } else {
7055 s.data = (u8*)UA_EMPTY_ARRAY_SENTINEL;
7056 }
7057 return s;
7058}
7059
7060UA_Boolean
7061UA_String_isEmpty(const UA_String *s) {
7062 return (s->length == 0 || s->data == NULL);
7063}
7064
7065static UA_Byte
7066lowercase(UA_Byte c) {
7067 if(((int)c) - 'A' < 26) return c | 32;
7068 return c;
7069}
7070
7071static int
7072casecmp(const UA_Byte *l, const UA_Byte *r, size_t n) {
7073 if(!n--) return 0;
7074 for(; *l && *r && n && (*l == *r || lowercase(c: *l) == lowercase(c: *r)); l++, r++, n--);
7075 return lowercase(c: *l) - lowercase(c: *r);
7076}
7077
7078/* Do not expose UA_String_equal_ignorecase to public API as it currently only handles
7079 * ASCII strings, and not UTF8! */
7080UA_Boolean
7081UA_String_equal_ignorecase(const UA_String *s1, const UA_String *s2) {
7082 if(s1->length != s2->length)
7083 return false;
7084 if(s1->length == 0)
7085 return true;
7086 if(s2->data == NULL)
7087 return false;
7088
7089 return casecmp(l: s1->data, r: s2->data, n: s1->length) == 0;
7090}
7091
7092static UA_StatusCode
7093String_copy(UA_String const *src, UA_String *dst, const UA_DataType *_) {
7094 UA_StatusCode res =
7095 UA_Array_copy(src: src->data, size: src->length, dst: (void**)&dst->data,
7096 type: &UA_TYPES[UA_TYPES_BYTE]);
7097 if(res == UA_STATUSCODE_GOOD)
7098 dst->length = src->length;
7099 return res;
7100}
7101
7102static void
7103String_clear(UA_String *s, const UA_DataType *_) {
7104 UA_Array_delete(p: s->data, size: s->length, type: &UA_TYPES[UA_TYPES_BYTE]);
7105}
7106
7107/* QualifiedName */
7108static UA_StatusCode
7109QualifiedName_copy(const UA_QualifiedName *src, UA_QualifiedName *dst,
7110 const UA_DataType *_) {
7111 dst->namespaceIndex = src->namespaceIndex;
7112 return String_copy(src: &src->name, dst: &dst->name, NULL);
7113}
7114
7115static void
7116QualifiedName_clear(UA_QualifiedName *p, const UA_DataType *_) {
7117 String_clear(s: &p->name, NULL);
7118}
7119
7120u32
7121UA_QualifiedName_hash(const UA_QualifiedName *q) {
7122 return UA_ByteString_hash(initialHashValue: q->namespaceIndex,
7123 data: q->name.data, size: q->name.length);
7124}
7125
7126/* DateTime */
7127UA_DateTimeStruct
7128UA_DateTime_toStruct(UA_DateTime t) {
7129 /* Divide, then subtract -> avoid underflow. Also, negative numbers are
7130 * rounded up, not down. */
7131 long long secSinceUnixEpoch = (long long)(t / UA_DATETIME_SEC)
7132 - (long long)(UA_DATETIME_UNIX_EPOCH / UA_DATETIME_SEC);
7133
7134 /* Negative fractions of a second? Remove one full second from the epoch
7135 * distance and allow only a positive fraction. */
7136 UA_DateTime frac = t % UA_DATETIME_SEC;
7137 if(frac < 0) {
7138 secSinceUnixEpoch--;
7139 frac += UA_DATETIME_SEC;
7140 }
7141
7142 struct musl_tm ts;
7143 memset(s: &ts, c: 0, n: sizeof(struct musl_tm));
7144 musl_secs_to_tm(t: secSinceUnixEpoch, tm: &ts);
7145
7146 UA_DateTimeStruct dateTimeStruct;
7147 dateTimeStruct.year = (i16)(ts.tm_year + 1900);
7148 dateTimeStruct.month = (u16)(ts.tm_mon + 1);
7149 dateTimeStruct.day = (u16)ts.tm_mday;
7150 dateTimeStruct.hour = (u16)ts.tm_hour;
7151 dateTimeStruct.min = (u16)ts.tm_min;
7152 dateTimeStruct.sec = (u16)ts.tm_sec;
7153 dateTimeStruct.milliSec = (u16)((frac % 10000000) / 10000);
7154 dateTimeStruct.microSec = (u16)((frac % 10000) / 10);
7155 dateTimeStruct.nanoSec = (u16)((frac % 10) * 100);
7156 return dateTimeStruct;
7157}
7158
7159UA_DateTime
7160UA_DateTime_fromStruct(UA_DateTimeStruct ts) {
7161 /* Seconds since the Unix epoch */
7162 struct musl_tm tm;
7163 memset(s: &tm, c: 0, n: sizeof(struct musl_tm));
7164 tm.tm_year = ts.year - 1900;
7165 tm.tm_mon = ts.month - 1;
7166 tm.tm_mday = ts.day;
7167 tm.tm_hour = ts.hour;
7168 tm.tm_min = ts.min;
7169 tm.tm_sec = ts.sec;
7170 long long sec_epoch = musl_tm_to_secs(tm: &tm);
7171
7172 UA_DateTime t = UA_DATETIME_UNIX_EPOCH;
7173 t += sec_epoch * UA_DATETIME_SEC;
7174 t += ts.milliSec * UA_DATETIME_MSEC;
7175 t += ts.microSec * UA_DATETIME_USEC;
7176 t += ts.nanoSec / 100;
7177 return t;
7178}
7179
7180/* Guid */
7181static const u8 hexmapLower[16] =
7182 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
7183static const u8 hexmapUpper[16] =
7184 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
7185
7186void
7187UA_Guid_to_hex(const UA_Guid *guid, u8* out, UA_Boolean lower) {
7188 const u8 *hexmap = (lower) ? hexmapLower : hexmapUpper;
7189 size_t i = 0, j = 28;
7190 for(; i<8;i++,j-=4) /* pos 0-7, 4byte, (a) */
7191 out[i] = hexmap[(guid->data1 >> j) & 0x0Fu];
7192 out[i++] = '-'; /* pos 8 */
7193 for(j=12; i<13;i++,j-=4) /* pos 9-12, 2byte, (b) */
7194 out[i] = hexmap[(uint16_t)(guid->data2 >> j) & 0x0Fu];
7195 out[i++] = '-'; /* pos 13 */
7196 for(j=12; i<18;i++,j-=4) /* pos 14-17, 2byte (c) */
7197 out[i] = hexmap[(uint16_t)(guid->data3 >> j) & 0x0Fu];
7198 out[i++] = '-'; /* pos 18 */
7199 for(j=0;i<23;i+=2,j++) { /* pos 19-22, 2byte (d) */
7200 out[i] = hexmap[(guid->data4[j] & 0xF0u) >> 4u];
7201 out[i+1] = hexmap[guid->data4[j] & 0x0Fu];
7202 }
7203 out[i++] = '-'; /* pos 23 */
7204 for(j=2; i<36;i+=2,j++) { /* pos 24-35, 6byte (e) */
7205 out[i] = hexmap[(guid->data4[j] & 0xF0u) >> 4u];
7206 out[i+1] = hexmap[guid->data4[j] & 0x0Fu];
7207 }
7208}
7209
7210UA_StatusCode
7211UA_Guid_print(const UA_Guid *guid, UA_String *output) {
7212 if(output->length == 0) {
7213 UA_StatusCode res =
7214 UA_ByteString_allocBuffer(bs: (UA_ByteString*)output, length: 36);
7215 if(res != UA_STATUSCODE_GOOD)
7216 return res;
7217 } else {
7218 if(output->length < 36)
7219 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
7220 output->length = 36;
7221 }
7222 UA_Guid_to_hex(guid, out: output->data, true);
7223 return UA_STATUSCODE_GOOD;
7224}
7225
7226/* ByteString */
7227UA_StatusCode
7228UA_ByteString_allocBuffer(UA_ByteString *bs, size_t length) {
7229 UA_ByteString_init(p: bs);
7230 if(length == 0)
7231 return UA_STATUSCODE_GOOD;
7232 bs->data = (u8*)UA_malloc(size: length);
7233 if(UA_UNLIKELY(!bs->data))
7234 return UA_STATUSCODE_BADOUTOFMEMORY;
7235 bs->length = length;
7236 return UA_STATUSCODE_GOOD;
7237}
7238
7239/* NodeId */
7240static void
7241NodeId_clear(UA_NodeId *p, const UA_DataType *_) {
7242 switch(p->identifierType) {
7243 case UA_NODEIDTYPE_STRING:
7244 case UA_NODEIDTYPE_BYTESTRING:
7245 String_clear(s: &p->identifier.string, NULL);
7246 break;
7247 default: break;
7248 }
7249}
7250
7251static UA_StatusCode
7252NodeId_copy(UA_NodeId const *src, UA_NodeId *dst, const UA_DataType *_) {
7253 UA_StatusCode retval = UA_STATUSCODE_GOOD;
7254 switch(src->identifierType) {
7255 case UA_NODEIDTYPE_NUMERIC:
7256 *dst = *src;
7257 return UA_STATUSCODE_GOOD;
7258 case UA_NODEIDTYPE_STRING:
7259 case UA_NODEIDTYPE_BYTESTRING:
7260 retval |= String_copy(src: &src->identifier.string,
7261 dst: &dst->identifier.string, NULL);
7262 break;
7263 case UA_NODEIDTYPE_GUID:
7264 dst->identifier.guid = src->identifier.guid;
7265 break;
7266 default:
7267 return UA_STATUSCODE_BADINTERNALERROR;
7268 }
7269 dst->namespaceIndex = src->namespaceIndex;
7270 dst->identifierType = src->identifierType;
7271 return retval;
7272}
7273
7274UA_Boolean
7275UA_NodeId_isNull(const UA_NodeId *p) {
7276 if(p->namespaceIndex != 0)
7277 return false;
7278 switch (p->identifierType) {
7279 case UA_NODEIDTYPE_NUMERIC:
7280 return (p->identifier.numeric == 0);
7281 case UA_NODEIDTYPE_STRING:
7282 case UA_NODEIDTYPE_BYTESTRING:
7283 return (p->identifier.string.length == 0); /* Null and empty string */
7284 case UA_NODEIDTYPE_GUID:
7285 return (guidOrder(p1: &p->identifier.guid, p2: &UA_GUID_NULL, NULL) == UA_ORDER_EQ);
7286 }
7287 return false;
7288}
7289
7290UA_Order
7291UA_NodeId_order(const UA_NodeId *n1, const UA_NodeId *n2) {
7292 return nodeIdOrder(p1: n1, p2: n2, NULL);
7293}
7294
7295/* sdbm-hash (http://www.cse.yorku.ca/~oz/hash.html) */
7296u32
7297UA_ByteString_hash(u32 initialHashValue,
7298 const u8 *data, size_t size) {
7299 u32 h = initialHashValue;
7300 for(size_t i = 0; i < size; i++)
7301 h = data[i] + (h << 6) + (h << 16) - h;
7302 return h;
7303}
7304
7305u32
7306UA_NodeId_hash(const UA_NodeId *n) {
7307 switch(n->identifierType) {
7308 case UA_NODEIDTYPE_NUMERIC:
7309 default:
7310 return UA_ByteString_hash(initialHashValue: n->namespaceIndex, data: (const u8*)&n->identifier.numeric,
7311 size: sizeof(UA_UInt32));
7312 case UA_NODEIDTYPE_STRING:
7313 case UA_NODEIDTYPE_BYTESTRING:
7314 return UA_ByteString_hash(initialHashValue: n->namespaceIndex, data: n->identifier.string.data,
7315 size: n->identifier.string.length);
7316 case UA_NODEIDTYPE_GUID:
7317 return UA_ByteString_hash(initialHashValue: n->namespaceIndex, data: (const u8*)&n->identifier.guid,
7318 size: sizeof(UA_Guid));
7319 }
7320}
7321
7322/* Computes length for the encoding size and pre-encodes the numeric values */
7323static size_t
7324nodeIdSize(const UA_NodeId *id,
7325 char *nsStr, size_t *nsStrSize,
7326 char *numIdStr, size_t *numIdStrSize) {
7327 /* Namespace length */
7328 size_t len = 0;
7329 if(id->namespaceIndex != 0) {
7330 len += 4; /* ns=; */
7331 *nsStrSize = itoaUnsigned(value: id->namespaceIndex, buffer: nsStr, base: 10);
7332 len += *nsStrSize;
7333 }
7334
7335 switch (id->identifierType) {
7336 case UA_NODEIDTYPE_NUMERIC:
7337 *numIdStrSize = itoaUnsigned(value: id->identifier.numeric, buffer: numIdStr, base: 10);
7338 len += 2 + *numIdStrSize;
7339 break;
7340 case UA_NODEIDTYPE_STRING:
7341 len += 2 + id->identifier.string.length;
7342 break;
7343 case UA_NODEIDTYPE_GUID:
7344 len += 2 + 36;
7345 break;
7346 case UA_NODEIDTYPE_BYTESTRING:
7347 len += 2 + (4*((id->identifier.byteString.length + 2) / 3));
7348 break;
7349 default:
7350 len = 0;
7351 }
7352 return len;
7353}
7354
7355#define PRINT_NODEID \
7356 /* Encode the namespace */ \
7357 if(id->namespaceIndex != 0) { \
7358 memcpy(pos, "ns=", 3); \
7359 pos += 3; \
7360 memcpy(pos, nsStr, nsStrSize); \
7361 pos += nsStrSize; \
7362 *pos++ = ';'; \
7363 } \
7364 \
7365 /* Encode the identifier */ \
7366 switch(id->identifierType) { \
7367 case UA_NODEIDTYPE_NUMERIC: \
7368 memcpy(pos, "i=", 2); \
7369 pos += 2; \
7370 memcpy(pos, numIdStr, numIdStrSize); \
7371 pos += numIdStrSize; \
7372 break; \
7373 case UA_NODEIDTYPE_STRING: \
7374 memcpy(pos, "s=", 2); \
7375 pos += 2; \
7376 memcpy(pos, id->identifier.string.data, \
7377 id->identifier.string.length); \
7378 pos += id->identifier.string.length; \
7379 break; \
7380 case UA_NODEIDTYPE_GUID: \
7381 memcpy(pos, "g=", 2); \
7382 pos += 2; \
7383 UA_Guid_to_hex(&id->identifier.guid, \
7384 (unsigned char*)pos, true); \
7385 pos += 36; \
7386 break; \
7387 case UA_NODEIDTYPE_BYTESTRING: \
7388 memcpy(pos, "b=", 2); \
7389 pos += 2; \
7390 pos += UA_base64_buf(id->identifier.byteString.data, \
7391 id->identifier.byteString.length, \
7392 (unsigned char*)pos); \
7393 break; \
7394 } \
7395 do { } while(false)
7396
7397UA_StatusCode
7398UA_NodeId_print(const UA_NodeId *id, UA_String *output) {
7399 /* Compute the string length */
7400 char nsStr[6];
7401 size_t nsStrSize = 0;
7402 char numIdStr[11];
7403 size_t numIdStrSize = 0;
7404 size_t idLen = nodeIdSize(id, nsStr, nsStrSize: &nsStrSize, numIdStr, numIdStrSize: &numIdStrSize);
7405 if(idLen == 0)
7406 return UA_STATUSCODE_BADINTERNALERROR;
7407
7408 /* Allocate memory if required */
7409 if(output->length == 0) {
7410 UA_StatusCode res = UA_ByteString_allocBuffer(bs: (UA_ByteString*)output, length: idLen);
7411 if(res != UA_STATUSCODE_GOOD)
7412 return res;
7413 } else {
7414 if(output->length < idLen)
7415 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
7416 output->length = idLen;
7417 }
7418
7419 /* Print the NodeId */
7420 char *pos = (char*)output->data;
7421 PRINT_NODEID;
7422
7423 UA_assert(output->length == (size_t)((UA_Byte*)pos - output->data));
7424 return UA_STATUSCODE_GOOD;
7425}
7426
7427/* ExpandedNodeId */
7428static void
7429ExpandedNodeId_clear(UA_ExpandedNodeId *p, const UA_DataType *_) {
7430 NodeId_clear(p: &p->nodeId, _);
7431 String_clear(s: &p->namespaceUri, NULL);
7432}
7433
7434static UA_StatusCode
7435ExpandedNodeId_copy(UA_ExpandedNodeId const *src, UA_ExpandedNodeId *dst,
7436 const UA_DataType *_) {
7437 UA_StatusCode retval = NodeId_copy(src: &src->nodeId, dst: &dst->nodeId, NULL);
7438 retval |= String_copy(src: &src->namespaceUri, dst: &dst->namespaceUri, NULL);
7439 dst->serverIndex = src->serverIndex;
7440 return retval;
7441}
7442
7443UA_Boolean
7444UA_ExpandedNodeId_isLocal(const UA_ExpandedNodeId *n) {
7445 return (n->namespaceUri.length == 0 && n->serverIndex == 0);
7446}
7447
7448UA_Order
7449UA_ExpandedNodeId_order(const UA_ExpandedNodeId *n1,
7450 const UA_ExpandedNodeId *n2) {
7451 return expandedNodeIdOrder(p1: n1, p2: n2, NULL);
7452}
7453
7454u32
7455UA_ExpandedNodeId_hash(const UA_ExpandedNodeId *n) {
7456 u32 h = UA_NodeId_hash(n: &n->nodeId);
7457 if(n->serverIndex != 0)
7458 h = UA_ByteString_hash(initialHashValue: h, data: (const UA_Byte*)&n->serverIndex, size: 4);
7459 if(n->namespaceUri.length != 0)
7460 h = UA_ByteString_hash(initialHashValue: h, data: n->namespaceUri.data, size: n->namespaceUri.length);
7461 return h;
7462}
7463
7464UA_StatusCode
7465UA_ExpandedNodeId_print(const UA_ExpandedNodeId *eid, UA_String *output) {
7466 /* Don't print the namespace-index if a NamespaceUri is set */
7467 UA_NodeId stackid = eid->nodeId;
7468 UA_NodeId *id = &stackid; /* for the print-macro below */
7469 if(eid->namespaceUri.data != NULL)
7470 id->namespaceIndex = 0;
7471
7472 /* Compute the string length */
7473 char nsStr[6];
7474 size_t nsStrSize = 0;
7475 char numIdStr[11];
7476 size_t numIdStrSize = 0;
7477 size_t idLen = nodeIdSize(id, nsStr, nsStrSize: &nsStrSize, numIdStr, numIdStrSize: &numIdStrSize);
7478 if(idLen == 0)
7479 return UA_STATUSCODE_BADINTERNALERROR;
7480
7481 char srvIdxStr[11];
7482 size_t srvIdxSize = 0;
7483 if(eid->serverIndex != 0) {
7484 idLen += 5; /* svr=; */
7485 srvIdxSize = itoaUnsigned(value: eid->serverIndex, buffer: srvIdxStr, base: 10);
7486 idLen += srvIdxSize;
7487 }
7488
7489 if(eid->namespaceUri.data != NULL) {
7490 idLen += 5; /* nsu=; */
7491 idLen += eid->namespaceUri.length;
7492 }
7493
7494 /* Allocate memory if required */
7495 if(output->length == 0) {
7496 UA_StatusCode res = UA_ByteString_allocBuffer(bs: (UA_ByteString*)output, length: idLen);
7497 if(res != UA_STATUSCODE_GOOD)
7498 return res;
7499 } else {
7500 if(output->length < idLen)
7501 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
7502 output->length = idLen;
7503 }
7504
7505 /* Encode the ServerIndex */
7506 char *pos = (char*)output->data;
7507 if(eid->serverIndex != 0) {
7508 memcpy(dest: pos, src: "svr=", n: 4);
7509 pos += 4;
7510 memcpy(dest: pos, src: srvIdxStr, n: srvIdxSize);
7511 pos += srvIdxSize;
7512 *pos++ = ';';
7513 }
7514
7515 /* Encode the NamespaceUri */
7516 if(eid->namespaceUri.data != NULL) {
7517 memcpy(dest: pos, src: "nsu=", n: 4);
7518 pos += 4;
7519 memcpy(dest: pos, src: eid->namespaceUri.data, n: eid->namespaceUri.length);
7520 pos += eid->namespaceUri.length;
7521 *pos++ = ';';
7522 }
7523
7524 /* Print the NodeId */
7525 PRINT_NODEID;
7526
7527 UA_assert(output->length == (size_t)((UA_Byte*)pos - output->data));
7528 return UA_STATUSCODE_GOOD;
7529}
7530
7531/* ExtensionObject */
7532static void
7533ExtensionObject_clear(UA_ExtensionObject *p, const UA_DataType *_) {
7534 switch(p->encoding) {
7535 case UA_EXTENSIONOBJECT_ENCODED_NOBODY:
7536 case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
7537 case UA_EXTENSIONOBJECT_ENCODED_XML:
7538 NodeId_clear(p: &p->content.encoded.typeId, NULL);
7539 String_clear(s: &p->content.encoded.body, NULL);
7540 break;
7541 case UA_EXTENSIONOBJECT_DECODED:
7542 if(p->content.decoded.data)
7543 UA_delete(p: p->content.decoded.data, type: p->content.decoded.type);
7544 break;
7545 default:
7546 break;
7547 }
7548}
7549
7550static UA_StatusCode
7551ExtensionObject_copy(UA_ExtensionObject const *src, UA_ExtensionObject *dst,
7552 const UA_DataType *_) {
7553 UA_StatusCode retval = UA_STATUSCODE_GOOD;
7554 switch(src->encoding) {
7555 case UA_EXTENSIONOBJECT_ENCODED_NOBODY:
7556 case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
7557 case UA_EXTENSIONOBJECT_ENCODED_XML:
7558 dst->encoding = src->encoding;
7559 retval = NodeId_copy(src: &src->content.encoded.typeId,
7560 dst: &dst->content.encoded.typeId, NULL);
7561 /* ByteString -> copy as string */
7562 retval |= String_copy(src: &src->content.encoded.body,
7563 dst: &dst->content.encoded.body, NULL);
7564 break;
7565 case UA_EXTENSIONOBJECT_DECODED:
7566 case UA_EXTENSIONOBJECT_DECODED_NODELETE:
7567 if(!src->content.decoded.type || !src->content.decoded.data)
7568 return UA_STATUSCODE_BADINTERNALERROR;
7569 dst->encoding = UA_EXTENSIONOBJECT_DECODED;
7570 dst->content.decoded.type = src->content.decoded.type;
7571 retval = UA_Array_copy(src: src->content.decoded.data, size: 1,
7572 dst: &dst->content.decoded.data, type: src->content.decoded.type);
7573 break;
7574 default:
7575 break;
7576 }
7577 return retval;
7578}
7579
7580void
7581UA_ExtensionObject_setValue(UA_ExtensionObject *eo,
7582 void * UA_RESTRICT p,
7583 const UA_DataType *type) {
7584 UA_ExtensionObject_init(p: eo);
7585 eo->content.decoded.data = p;
7586 eo->content.decoded.type = type;
7587 eo->encoding = UA_EXTENSIONOBJECT_DECODED;
7588}
7589
7590void
7591UA_ExtensionObject_setValueNoDelete(UA_ExtensionObject *eo,
7592 void * UA_RESTRICT p,
7593 const UA_DataType *type) {
7594 UA_ExtensionObject_init(p: eo);
7595 eo->content.decoded.data = p;
7596 eo->content.decoded.type = type;
7597 eo->encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
7598}
7599
7600UA_StatusCode
7601UA_ExtensionObject_setValueCopy(UA_ExtensionObject *eo,
7602 void * UA_RESTRICT p,
7603 const UA_DataType *type) {
7604 UA_ExtensionObject_init(p: eo);
7605
7606 /* Make a copy of the value */
7607 void *val = UA_malloc(size: type->memSize);
7608 if(UA_UNLIKELY(!val))
7609 return UA_STATUSCODE_BADOUTOFMEMORY;
7610 UA_StatusCode res = UA_copy(src: p, dst: val, type);
7611 if(UA_UNLIKELY(res != UA_STATUSCODE_GOOD)) {
7612 UA_free(ptr: val);
7613 return res;
7614 }
7615
7616 /* Set the ExtensionObject */
7617 eo->content.decoded.data = val;
7618 eo->content.decoded.type = type;
7619 eo->encoding = UA_EXTENSIONOBJECT_DECODED;
7620 return UA_STATUSCODE_GOOD;
7621}
7622
7623/* Variant */
7624static void
7625Variant_clear(UA_Variant *p, const UA_DataType *_) {
7626 /* The content is "borrowed" */
7627 if(p->storageType == UA_VARIANT_DATA_NODELETE)
7628 return;
7629
7630 /* Delete the value */
7631 if(p->type && p->data > UA_EMPTY_ARRAY_SENTINEL) {
7632 if(p->arrayLength == 0)
7633 p->arrayLength = 1;
7634 UA_Array_delete(p: p->data, size: p->arrayLength, type: p->type);
7635 p->data = NULL;
7636 }
7637
7638 /* Delete the array dimensions */
7639 if((void*)p->arrayDimensions > UA_EMPTY_ARRAY_SENTINEL)
7640 UA_free(ptr: p->arrayDimensions);
7641}
7642
7643static UA_StatusCode
7644Variant_copy(UA_Variant const *src, UA_Variant *dst, const UA_DataType *_) {
7645 size_t length = src->arrayLength;
7646 if(UA_Variant_isScalar(v: src))
7647 length = 1;
7648 UA_StatusCode retval = UA_Array_copy(src: src->data, size: length,
7649 dst: &dst->data, type: src->type);
7650 if(retval != UA_STATUSCODE_GOOD)
7651 return retval;
7652 dst->arrayLength = src->arrayLength;
7653 dst->type = src->type;
7654 if(src->arrayDimensions) {
7655 retval = UA_Array_copy(src: src->arrayDimensions, size: src->arrayDimensionsSize,
7656 dst: (void**)&dst->arrayDimensions, type: &UA_TYPES[UA_TYPES_INT32]);
7657 if(retval != UA_STATUSCODE_GOOD)
7658 return retval;
7659 dst->arrayDimensionsSize = src->arrayDimensionsSize;
7660 }
7661 return UA_STATUSCODE_GOOD;
7662}
7663
7664void
7665UA_Variant_setScalar(UA_Variant *v, void * UA_RESTRICT p,
7666 const UA_DataType *type) {
7667 UA_Variant_init(p: v);
7668 v->type = type;
7669 v->arrayLength = 0;
7670 v->data = p;
7671}
7672
7673UA_StatusCode
7674UA_Variant_setScalarCopy(UA_Variant *v, const void * UA_RESTRICT p,
7675 const UA_DataType *type) {
7676 void *n = UA_malloc(size: type->memSize);
7677 if(UA_UNLIKELY(!n))
7678 return UA_STATUSCODE_BADOUTOFMEMORY;
7679 UA_StatusCode retval = UA_copy(src: p, dst: n, type);
7680 if(UA_UNLIKELY(retval != UA_STATUSCODE_GOOD)) {
7681 UA_free(ptr: n);
7682 //cppcheck-suppress memleak
7683 return retval;
7684 }
7685 UA_Variant_setScalar(v, p: n, type);
7686 //cppcheck-suppress memleak
7687 return UA_STATUSCODE_GOOD;
7688}
7689
7690void UA_Variant_setArray(UA_Variant *v, void * UA_RESTRICT array,
7691 size_t arraySize, const UA_DataType *type) {
7692 UA_Variant_init(p: v);
7693 v->data = array;
7694 v->arrayLength = arraySize;
7695 v->type = type;
7696}
7697
7698UA_StatusCode
7699UA_Variant_setArrayCopy(UA_Variant *v, const void * UA_RESTRICT array,
7700 size_t arraySize, const UA_DataType *type) {
7701 UA_Variant_init(p: v);
7702 UA_StatusCode retval = UA_Array_copy(src: array, size: arraySize, dst: &v->data, type);
7703 if(retval != UA_STATUSCODE_GOOD)
7704 return retval;
7705 v->arrayLength = arraySize;
7706 v->type = type;
7707 return UA_STATUSCODE_GOOD;
7708}
7709
7710/* Test if a range is compatible with a variant. This may adjust the upper bound
7711 * (max) in order to fit the variant. */
7712static UA_StatusCode
7713checkAdjustRange(const UA_Variant *v, UA_NumericRange *range) {
7714 /* Test for max array size (64bit only) */
7715#if (SIZE_MAX > 0xffffffff)
7716 if(v->arrayLength > UA_UINT32_MAX)
7717 return UA_STATUSCODE_BADINTERNALERROR;
7718#endif
7719 u32 arrayLength = (u32)v->arrayLength;
7720
7721 /* Assume one array dimension if none defined */
7722 const u32 *dims = v->arrayDimensions;
7723 size_t dims_count = v->arrayDimensionsSize;
7724 if(v->arrayDimensionsSize == 0) {
7725 dims_count = 1;
7726 dims = &arrayLength;
7727 }
7728
7729 /* Does the range match the dimension of the variant? */
7730 if(range->dimensionsSize != dims_count)
7731 return UA_STATUSCODE_BADINDEXRANGENODATA;
7732
7733 /* Check that the number of elements in the variant matches the array
7734 * dimensions */
7735 size_t elements = 1;
7736 for(size_t i = 0; i < dims_count; ++i)
7737 elements *= dims[i];
7738 if(elements != v->arrayLength)
7739 return UA_STATUSCODE_BADINTERNALERROR;
7740
7741 /* Test the integrity of the range and compute the max index used for every
7742 * dimension. The standard says in Part 4, Section 7.22:
7743 *
7744 * When reading a value, the indexes may not specify a range that is within
7745 * the bounds of the array. The Server shall return a partial result if some
7746 * elements exist within the range. */
7747 for(size_t i = 0; i < dims_count; ++i) {
7748 if(range->dimensions[i].min > range->dimensions[i].max)
7749 return UA_STATUSCODE_BADINDEXRANGEINVALID;
7750 if(range->dimensions[i].min >= dims[i])
7751 return UA_STATUSCODE_BADINDEXRANGENODATA;
7752
7753 /* Reduce the max to fit the variant */
7754 if(range->dimensions[i].max >= dims[i])
7755 range->dimensions[i].max = dims[i] - 1;
7756 }
7757
7758 return UA_STATUSCODE_GOOD;
7759}
7760
7761/* Computes the stride for copying the range elements.
7762 * - total: how many elements are in the range
7763 * - block: how big is each contiguous block of elements in the variant that
7764 * maps into the range
7765 * - stride: how many elements are between the blocks (beginning to beginning)
7766 * - first: where does the first block begin */
7767static void
7768computeStrides(const UA_Variant *v, const UA_NumericRange range,
7769 size_t *total, size_t *block, size_t *stride, size_t *first) {
7770 /* Number of total elements to be copied */
7771 size_t count = 1;
7772 for(size_t i = 0; i < range.dimensionsSize; ++i)
7773 count *= (range.dimensions[i].max - range.dimensions[i].min) + 1;
7774 *total = count;
7775
7776 /* Assume one array dimension if none defined */
7777 u32 arrayLength = (u32)v->arrayLength;
7778 const u32 *dims = v->arrayDimensions;
7779 size_t dims_count = v->arrayDimensionsSize;
7780 if(v->arrayDimensionsSize == 0) {
7781 dims_count = 1;
7782 dims = &arrayLength;
7783 }
7784
7785 /* Compute the stride length and the position of the first element */
7786 *block = count; /* Assume the range describes the entire array. */
7787 *stride = v->arrayLength; /* So it can be copied as a contiguous block. */
7788 *first = 0;
7789 size_t running_dimssize = 1;
7790 UA_Boolean found_contiguous = false;
7791 for(size_t k = dims_count; k > 0;) {
7792 --k;
7793 size_t dimrange = 1 + range.dimensions[k].max - range.dimensions[k].min;
7794 if(!found_contiguous && dimrange != dims[k]) {
7795 /* Found the maximum block that can be copied contiguously */
7796 found_contiguous = true;
7797 *block = running_dimssize * dimrange;
7798 *stride = running_dimssize * dims[k];
7799 }
7800 *first += running_dimssize * range.dimensions[k].min;
7801 running_dimssize *= dims[k];
7802 }
7803}
7804
7805/* Is the type string-like? */
7806static UA_Boolean
7807isStringLike(const UA_DataType *type) {
7808 if(type == &UA_TYPES[UA_TYPES_STRING] ||
7809 type == &UA_TYPES[UA_TYPES_BYTESTRING] ||
7810 type == &UA_TYPES[UA_TYPES_XMLELEMENT])
7811 return true;
7812 return false;
7813}
7814
7815/* Returns the part of the string that lies within the rangedimension */
7816static UA_StatusCode
7817copySubString(const UA_String *src, UA_String *dst,
7818 const UA_NumericRangeDimension *dim) {
7819 if(dim->min > dim->max)
7820 return UA_STATUSCODE_BADINDEXRANGEINVALID;
7821 if(dim->min >= src->length)
7822 return UA_STATUSCODE_BADINDEXRANGENODATA;
7823
7824 size_t length;
7825 if(dim->max < src->length)
7826 length = dim->max - dim->min + 1;
7827 else
7828 length = src->length - dim->min;
7829
7830 UA_StatusCode retval = UA_ByteString_allocBuffer(bs: dst, length);
7831 if(retval != UA_STATUSCODE_GOOD)
7832 return retval;
7833
7834 memcpy(dest: dst->data, src: &src->data[dim->min], n: length);
7835 return UA_STATUSCODE_GOOD;
7836}
7837
7838UA_StatusCode
7839UA_Variant_copyRange(const UA_Variant *src, UA_Variant * UA_RESTRICT dst,
7840 const UA_NumericRange range) {
7841 if(!src->type)
7842 return UA_STATUSCODE_BADINVALIDARGUMENT;
7843
7844 UA_Boolean isScalar = UA_Variant_isScalar(v: src);
7845 UA_Boolean stringLike = isStringLike(type: src->type);
7846
7847 /* Upper bound of the dimensions for stack-allocation */
7848 if(range.dimensionsSize > UA_MAX_ARRAY_DIMS)
7849 return UA_STATUSCODE_BADINTERNALERROR;
7850
7851 /* Copy the const range to a mutable stack location */
7852 UA_NumericRangeDimension thisrangedims[UA_MAX_ARRAY_DIMS];
7853 memcpy(dest: thisrangedims, src: range.dimensions, n: sizeof(UA_NumericRangeDimension) * range.dimensionsSize);
7854 UA_NumericRange thisrange = {range.dimensionsSize, thisrangedims};
7855
7856 UA_NumericRangeDimension scalarThisDimension = {0,0}; /* a single entry */
7857 UA_NumericRange nextrange = {0, NULL};
7858
7859 /* Extract the range for copying at this level. The remaining range is dealt
7860 * with in the "scalar" type that may define an array by itself (string,
7861 * variant, ...). */
7862 UA_Variant arraySrc;
7863 if(isScalar) {
7864 /* Replace scalar src with array of length 1 */
7865 arraySrc = *src;
7866 arraySrc.arrayLength = 1;
7867 src = &arraySrc;
7868 /* Deal with all range dimensions within the scalar */
7869 thisrange.dimensions = &scalarThisDimension;
7870 thisrange.dimensionsSize = 1;
7871 nextrange = range;
7872 } else {
7873 /* Deal with as many range dimensions as possible right now */
7874 size_t dims = src->arrayDimensionsSize;
7875 if(dims == 0)
7876 dims = 1;
7877 if(dims > range.dimensionsSize)
7878 return UA_STATUSCODE_BADINDEXRANGEINVALID;
7879 thisrange.dimensionsSize = dims;
7880 nextrange.dimensions = &range.dimensions[dims];
7881 nextrange.dimensionsSize = range.dimensionsSize - dims;
7882 }
7883
7884 UA_StatusCode retval = checkAdjustRange(v: src, range: &thisrange);
7885 if(retval != UA_STATUSCODE_GOOD)
7886 return retval;
7887
7888 /* Compute the strides */
7889 size_t count, block, stride, first;
7890 computeStrides(v: src, range: thisrange, total: &count, block: &block, stride: &stride, first: &first);
7891 UA_assert(block > 0);
7892
7893 /* Allocate the array */
7894 UA_Variant_init(p: dst);
7895 dst->data = UA_Array_new(size: count, type: src->type);
7896 if(!dst->data)
7897 return UA_STATUSCODE_BADOUTOFMEMORY;
7898
7899 /* Copy the range */
7900 size_t block_count = count / block;
7901 size_t elem_size = src->type->memSize;
7902 uintptr_t nextdst = (uintptr_t)dst->data;
7903 uintptr_t nextsrc = (uintptr_t)src->data + (elem_size * first);
7904 if(nextrange.dimensionsSize == 0) {
7905 /* no nextrange */
7906 if(src->type->pointerFree) {
7907 for(size_t i = 0; i < block_count; ++i) {
7908 memcpy(dest: (void*)nextdst, src: (void*)nextsrc, n: elem_size * block);
7909 nextdst += block * elem_size;
7910 nextsrc += stride * elem_size;
7911 }
7912 } else {
7913 for(size_t i = 0; i < block_count; ++i) {
7914 for(size_t j = 0; j < block; ++j) {
7915 retval = UA_copy(src: (const void*)nextsrc,
7916 dst: (void*)nextdst, type: src->type);
7917 nextdst += elem_size;
7918 nextsrc += elem_size;
7919 }
7920 nextsrc += (stride - block) * elem_size;
7921 }
7922 }
7923 } else {
7924 /* nextrange can only be used for variants and stringlike with remaining
7925 * range of dimension 1 */
7926 if(src->type != &UA_TYPES[UA_TYPES_VARIANT]) {
7927 if(!stringLike)
7928 retval = UA_STATUSCODE_BADINDEXRANGENODATA;
7929 if(nextrange.dimensionsSize != 1)
7930 retval = UA_STATUSCODE_BADINDEXRANGENODATA;
7931 }
7932
7933 /* Copy the content */
7934 for(size_t i = 0; i < block_count; ++i) {
7935 for(size_t j = 0; j < block && retval == UA_STATUSCODE_GOOD; ++j) {
7936 if(stringLike)
7937 retval = copySubString(src: (const UA_String*)nextsrc,
7938 dst: (UA_String*)nextdst,
7939 dim: nextrange.dimensions);
7940 else
7941 retval = UA_Variant_copyRange(src: (const UA_Variant*)nextsrc,
7942 dst: (UA_Variant*)nextdst,
7943 range: nextrange);
7944 nextdst += elem_size;
7945 nextsrc += elem_size;
7946 }
7947 nextsrc += (stride - block) * elem_size;
7948 }
7949 }
7950
7951 /* Clean up if copying failed */
7952 if(retval != UA_STATUSCODE_GOOD) {
7953 UA_Array_delete(p: dst->data, size: count, type: src->type);
7954 dst->data = NULL;
7955 return retval;
7956 }
7957
7958 /* Done if scalar */
7959 dst->type = src->type;
7960 if(isScalar)
7961 return retval;
7962
7963 /* Copy array dimensions */
7964 dst->arrayLength = count;
7965 if(src->arrayDimensionsSize > 0) {
7966 dst->arrayDimensions =
7967 (u32*)UA_Array_new(size: thisrange.dimensionsSize, type: &UA_TYPES[UA_TYPES_UINT32]);
7968 if(!dst->arrayDimensions) {
7969 Variant_clear(p: dst, NULL);
7970 return UA_STATUSCODE_BADOUTOFMEMORY;
7971 }
7972 dst->arrayDimensionsSize = thisrange.dimensionsSize;
7973 for(size_t k = 0; k < thisrange.dimensionsSize; ++k)
7974 dst->arrayDimensions[k] =
7975 thisrange.dimensions[k].max - thisrange.dimensions[k].min + 1;
7976 }
7977 return UA_STATUSCODE_GOOD;
7978}
7979
7980/* TODO: Allow ranges to reach inside a scalars that are array-like, e.g.
7981 * variant and strings. This is already possible for reading... */
7982static UA_StatusCode
7983Variant_setRange(UA_Variant *v, void *array, size_t arraySize,
7984 const UA_NumericRange range, UA_Boolean copy) {
7985 if(!v->type)
7986 return UA_STATUSCODE_BADINVALIDARGUMENT;
7987
7988 /* Upper bound of the dimensions for stack-allocation */
7989 if(range.dimensionsSize > UA_MAX_ARRAY_DIMS)
7990 return UA_STATUSCODE_BADINTERNALERROR;
7991
7992 /* Copy the const range to a mutable stack location */
7993 UA_NumericRangeDimension thisrangedims[UA_MAX_ARRAY_DIMS];
7994 memcpy(dest: thisrangedims, src: range.dimensions, n: sizeof(UA_NumericRangeDimension) * range.dimensionsSize);
7995 UA_NumericRange thisrange = {range.dimensionsSize, thisrangedims};
7996
7997 UA_StatusCode retval = checkAdjustRange(v, range: &thisrange);
7998 if(retval != UA_STATUSCODE_GOOD)
7999 return retval;
8000
8001 /* Compute the strides */
8002 size_t count, block, stride, first;
8003 computeStrides(v, range, total: &count, block: &block, stride: &stride, first: &first);
8004 if(count != arraySize)
8005 return UA_STATUSCODE_BADINDEXRANGEINVALID;
8006
8007 /* Move/copy the elements */
8008 size_t block_count = count / block;
8009 size_t elem_size = v->type->memSize;
8010 uintptr_t nextdst = (uintptr_t)v->data + (first * elem_size);
8011 uintptr_t nextsrc = (uintptr_t)array;
8012 if(v->type->pointerFree || !copy) {
8013 for(size_t i = 0; i < block_count; ++i) {
8014 memcpy(dest: (void*)nextdst, src: (void*)nextsrc, n: elem_size * block);
8015 nextsrc += block * elem_size;
8016 nextdst += stride * elem_size;
8017 }
8018 } else {
8019 for(size_t i = 0; i < block_count; ++i) {
8020 for(size_t j = 0; j < block; ++j) {
8021 clearJumpTable[v->type->typeKind]((void*)nextdst, v->type);
8022 retval |= UA_copy(src: (void*)nextsrc, dst: (void*)nextdst, type: v->type);
8023 nextdst += elem_size;
8024 nextsrc += elem_size;
8025 }
8026 nextdst += (stride - block) * elem_size;
8027 }
8028 }
8029
8030 /* If members were moved, initialize original array to prevent reuse */
8031 if(!copy && !v->type->pointerFree)
8032 memset(s: array, c: 0, n: sizeof(elem_size)*arraySize);
8033
8034 return retval;
8035}
8036
8037UA_StatusCode
8038UA_Variant_setRange(UA_Variant *v, void * UA_RESTRICT array,
8039 size_t arraySize, const UA_NumericRange range) {
8040 return Variant_setRange(v, array, arraySize, range, false);
8041}
8042
8043UA_StatusCode
8044UA_Variant_setRangeCopy(UA_Variant *v, const void * UA_RESTRICT array,
8045 size_t arraySize, const UA_NumericRange range) {
8046 return Variant_setRange(v, array: (void*)(uintptr_t)array,
8047 arraySize, range, true);
8048}
8049
8050/* LocalizedText */
8051static void
8052LocalizedText_clear(UA_LocalizedText *p, const UA_DataType *_) {
8053 String_clear(s: &p->locale, NULL);
8054 String_clear(s: &p->text, NULL);
8055}
8056
8057static UA_StatusCode
8058LocalizedText_copy(UA_LocalizedText const *src, UA_LocalizedText *dst,
8059 const UA_DataType *_) {
8060 UA_StatusCode retval = String_copy(src: &src->locale, dst: &dst->locale, NULL);
8061 retval |= String_copy(src: &src->text, dst: &dst->text, NULL);
8062 return retval;
8063}
8064
8065/* DataValue */
8066static void
8067DataValue_clear(UA_DataValue *p, const UA_DataType *_) {
8068 Variant_clear(p: &p->value, NULL);
8069}
8070
8071static UA_StatusCode
8072DataValue_copy(UA_DataValue const *src, UA_DataValue *dst,
8073 const UA_DataType *_) {
8074 memcpy(dest: dst, src: src, n: sizeof(UA_DataValue));
8075 UA_Variant_init(p: &dst->value);
8076 UA_StatusCode retval = Variant_copy(src: &src->value, dst: &dst->value, NULL);
8077 if(retval != UA_STATUSCODE_GOOD)
8078 DataValue_clear(p: dst, NULL);
8079 return retval;
8080}
8081
8082UA_StatusCode
8083UA_DataValue_copyVariantRange(const UA_DataValue *src, UA_DataValue * UA_RESTRICT dst,
8084 const UA_NumericRange range) {
8085 memcpy(dest: dst, src: src, n: sizeof(UA_DataValue));
8086 UA_Variant_init(p: &dst->value);
8087 UA_StatusCode retval = UA_Variant_copyRange(src: &src->value, dst: &dst->value, range);
8088 if(retval != UA_STATUSCODE_GOOD)
8089 DataValue_clear(p: dst, NULL);
8090 return retval;
8091}
8092
8093/* DiagnosticInfo */
8094static void
8095DiagnosticInfo_clear(UA_DiagnosticInfo *p, const UA_DataType *_) {
8096 String_clear(s: &p->additionalInfo, NULL);
8097 if(p->hasInnerDiagnosticInfo && p->innerDiagnosticInfo) {
8098 DiagnosticInfo_clear(p: p->innerDiagnosticInfo, NULL);
8099 UA_free(ptr: p->innerDiagnosticInfo);
8100 }
8101}
8102
8103static UA_StatusCode
8104DiagnosticInfo_copy(UA_DiagnosticInfo const *src, UA_DiagnosticInfo *dst,
8105 const UA_DataType *_) {
8106 memcpy(dest: dst, src: src, n: sizeof(UA_DiagnosticInfo));
8107 UA_String_init(p: &dst->additionalInfo);
8108 dst->innerDiagnosticInfo = NULL;
8109 UA_StatusCode retval = UA_STATUSCODE_GOOD;
8110 if(src->hasAdditionalInfo)
8111 retval = String_copy(src: &src->additionalInfo, dst: &dst->additionalInfo, NULL);
8112 if(src->hasInnerDiagnosticInfo && src->innerDiagnosticInfo) {
8113 dst->innerDiagnosticInfo = (UA_DiagnosticInfo*)
8114 UA_malloc(size: sizeof(UA_DiagnosticInfo));
8115 if(UA_LIKELY(dst->innerDiagnosticInfo != NULL)) {
8116 retval |= DiagnosticInfo_copy(src: src->innerDiagnosticInfo,
8117 dst: dst->innerDiagnosticInfo, NULL);
8118 dst->hasInnerDiagnosticInfo = true;
8119 } else {
8120 dst->hasInnerDiagnosticInfo = false;
8121 retval |= UA_STATUSCODE_BADOUTOFMEMORY;
8122 }
8123 }
8124 return retval;
8125}
8126
8127/********************/
8128/* Structured Types */
8129/********************/
8130
8131void *
8132UA_new(const UA_DataType *type) {
8133 void *p = UA_calloc(nmemb: 1, size: type->memSize);
8134 return p;
8135}
8136
8137static UA_StatusCode
8138copyByte(const u8 *src, u8 *dst, const UA_DataType *_) {
8139 *dst = *src;
8140 return UA_STATUSCODE_GOOD;
8141}
8142
8143static UA_StatusCode
8144copy2Byte(const u16 *src, u16 *dst, const UA_DataType *_) {
8145 *dst = *src;
8146 return UA_STATUSCODE_GOOD;
8147}
8148
8149static UA_StatusCode
8150copy4Byte(const u32 *src, u32 *dst, const UA_DataType *_) {
8151 *dst = *src;
8152 return UA_STATUSCODE_GOOD;
8153}
8154
8155static UA_StatusCode
8156copy8Byte(const u64 *src, u64 *dst, const UA_DataType *_) {
8157 *dst = *src;
8158 return UA_STATUSCODE_GOOD;
8159}
8160
8161static UA_StatusCode
8162copyGuid(const UA_Guid *src, UA_Guid *dst, const UA_DataType *_) {
8163 *dst = *src;
8164 return UA_STATUSCODE_GOOD;
8165}
8166
8167static UA_StatusCode
8168copyStructure(const void *src, void *dst, const UA_DataType *type) {
8169 UA_StatusCode retval = UA_STATUSCODE_GOOD;
8170 uintptr_t ptrs = (uintptr_t)src;
8171 uintptr_t ptrd = (uintptr_t)dst;
8172 for(size_t i = 0; i < type->membersSize; ++i) {
8173 const UA_DataTypeMember *m = &type->members[i];
8174 const UA_DataType *mt = m->memberType;
8175 ptrs += m->padding;
8176 ptrd += m->padding;
8177 if(!m->isOptional) {
8178 if(!m->isArray) {
8179 retval |= copyJumpTable[mt->typeKind]((const void *)ptrs, (void *)ptrd, mt);
8180 ptrs += mt->memSize;
8181 ptrd += mt->memSize;
8182 } else {
8183 size_t *dst_size = (size_t*)ptrd;
8184 const size_t size = *((const size_t*)ptrs);
8185 ptrs += sizeof(size_t);
8186 ptrd += sizeof(size_t);
8187 retval |= UA_Array_copy(src: *(void* const*)ptrs, size, dst: (void**)ptrd, type: mt);
8188 if(retval == UA_STATUSCODE_GOOD)
8189 *dst_size = size;
8190 else
8191 *dst_size = 0;
8192 ptrs += sizeof(void*);
8193 ptrd += sizeof(void*);
8194 }
8195 } else {
8196 if(!m->isArray) {
8197 if(*(void* const*)ptrs != NULL)
8198 retval |= UA_Array_copy(src: *(void* const*)ptrs, size: 1, dst: (void**)ptrd, type: mt);
8199 } else {
8200 if(*(void* const*)(ptrs+sizeof(size_t)) != NULL) {
8201 size_t *dst_size = (size_t*)ptrd;
8202 const size_t size = *((const size_t*)ptrs);
8203 ptrs += sizeof(size_t);
8204 ptrd += sizeof(size_t);
8205 retval |= UA_Array_copy(src: *(void* const*)ptrs, size, dst: (void**)ptrd, type: mt);
8206 if(retval == UA_STATUSCODE_GOOD)
8207 *dst_size = size;
8208 else
8209 *dst_size = 0;
8210 } else {
8211 ptrs += sizeof(size_t);
8212 ptrd += sizeof(size_t);
8213 }
8214 }
8215 ptrs += sizeof(void*);
8216 ptrd += sizeof(void*);
8217 }
8218 }
8219 return retval;
8220}
8221
8222static UA_StatusCode
8223copyUnion(const void *src, void *dst, const UA_DataType *type) {
8224 uintptr_t ptrs = (uintptr_t) src;
8225 uintptr_t ptrd = (uintptr_t) dst;
8226 UA_UInt32 selection = *(UA_UInt32 *)ptrs;
8227 UA_copy(src: (const UA_UInt32 *) ptrs, dst: (UA_UInt32 *) ptrd, type: &UA_TYPES[UA_TYPES_UINT32]);
8228 if(selection == 0)
8229 return UA_STATUSCODE_GOOD;
8230 const UA_DataTypeMember *m = &type->members[selection-1];
8231 const UA_DataType *mt = m->memberType;
8232 ptrs += m->padding;
8233 ptrd += m->padding;
8234
8235 UA_StatusCode retval = UA_STATUSCODE_GOOD;
8236
8237 if (m->isArray) {
8238 size_t *dst_size = (size_t*)ptrd;
8239 const size_t size = *((const size_t*)ptrs);
8240 ptrs += sizeof(size_t);
8241 ptrd += sizeof(size_t);
8242 retval = UA_Array_copy(src: *(void* const*)ptrs, size, dst: (void**)ptrd, type: mt);
8243 if(retval == UA_STATUSCODE_GOOD)
8244 *dst_size = size;
8245 else
8246 *dst_size = 0;
8247 } else {
8248 retval = copyJumpTable[mt->typeKind]((const void *)ptrs, (void *)ptrd, mt);
8249 }
8250
8251 return retval;
8252}
8253
8254static UA_StatusCode
8255copyNotImplemented(const void *src, void *dst, const UA_DataType *type) {
8256 return UA_STATUSCODE_BADNOTIMPLEMENTED;
8257}
8258
8259const UA_copySignature copyJumpTable[UA_DATATYPEKINDS] = {
8260 (UA_copySignature)copyByte, /* Boolean */
8261 (UA_copySignature)copyByte, /* SByte */
8262 (UA_copySignature)copyByte, /* Byte */
8263 (UA_copySignature)copy2Byte, /* Int16 */
8264 (UA_copySignature)copy2Byte, /* UInt16 */
8265 (UA_copySignature)copy4Byte, /* Int32 */
8266 (UA_copySignature)copy4Byte, /* UInt32 */
8267 (UA_copySignature)copy8Byte, /* Int64 */
8268 (UA_copySignature)copy8Byte, /* UInt64 */
8269 (UA_copySignature)copy4Byte, /* Float */
8270 (UA_copySignature)copy8Byte, /* Double */
8271 (UA_copySignature)String_copy,
8272 (UA_copySignature)copy8Byte, /* DateTime */
8273 (UA_copySignature)copyGuid, /* Guid */
8274 (UA_copySignature)String_copy, /* ByteString */
8275 (UA_copySignature)String_copy, /* XmlElement */
8276 (UA_copySignature)NodeId_copy,
8277 (UA_copySignature)ExpandedNodeId_copy,
8278 (UA_copySignature)copy4Byte, /* StatusCode */
8279 (UA_copySignature)QualifiedName_copy,
8280 (UA_copySignature)LocalizedText_copy,
8281 (UA_copySignature)ExtensionObject_copy,
8282 (UA_copySignature)DataValue_copy,
8283 (UA_copySignature)Variant_copy,
8284 (UA_copySignature)DiagnosticInfo_copy,
8285 (UA_copySignature)copyNotImplemented, /* Decimal */
8286 (UA_copySignature)copy4Byte, /* Enumeration */
8287 (UA_copySignature)copyStructure,
8288 (UA_copySignature)copyStructure, /* Structure with Optional Fields */
8289 (UA_copySignature)copyUnion, /* Union */
8290 (UA_copySignature)copyNotImplemented /* BitfieldCluster*/
8291};
8292
8293UA_StatusCode
8294UA_copy(const void *src, void *dst, const UA_DataType *type) {
8295 memset(s: dst, c: 0, n: type->memSize); /* init */
8296 UA_StatusCode retval = copyJumpTable[type->typeKind](src, dst, type);
8297 if(retval != UA_STATUSCODE_GOOD)
8298 UA_clear(p: dst, type);
8299 return retval;
8300}
8301
8302static void
8303clearStructure(void *p, const UA_DataType *type) {
8304 uintptr_t ptr = (uintptr_t)p;
8305 for(size_t i = 0; i < type->membersSize; ++i) {
8306 const UA_DataTypeMember *m = &type->members[i];
8307 const UA_DataType *mt = m->memberType;
8308 ptr += m->padding;
8309 if(!m->isOptional) {
8310 if(!m->isArray) {
8311 clearJumpTable[mt->typeKind]((void*)ptr, mt);
8312 ptr += mt->memSize;
8313 } else {
8314 size_t length = *(size_t*)ptr;
8315 ptr += sizeof(size_t);
8316 UA_Array_delete(p: *(void**)ptr, size: length, type: mt);
8317 ptr += sizeof(void*);
8318 }
8319 } else { /* field is optional */
8320 if(!m->isArray) {
8321 /* optional scalar field is contained */
8322 if((*(void *const *)ptr != NULL))
8323 UA_Array_delete(p: *(void **)ptr, size: 1, type: mt);
8324 ptr += sizeof(void *);
8325 } else {
8326 /* optional array field is contained */
8327 if((*(void *const *)(ptr + sizeof(size_t)) != NULL)) {
8328 size_t length = *(size_t *)ptr;
8329 ptr += sizeof(size_t);
8330 UA_Array_delete(p: *(void **)ptr, size: length, type: mt);
8331 ptr += sizeof(void *);
8332 } else { /* optional array field not contained */
8333 ptr += sizeof(size_t);
8334 ptr += sizeof(void *);
8335 }
8336 }
8337 }
8338 }
8339}
8340
8341static void
8342clearUnion(void *p, const UA_DataType *type) {
8343 uintptr_t ptr = (uintptr_t) p;
8344 UA_UInt32 selection = *(UA_UInt32 *)ptr;
8345 if(selection == 0)
8346 return;
8347 const UA_DataTypeMember *m = &type->members[selection-1];
8348 const UA_DataType *mt = m->memberType;
8349 ptr += m->padding;
8350 if (m->isArray) {
8351 size_t length = *(size_t *)ptr;
8352 ptr += sizeof(size_t);
8353 UA_Array_delete(p: *(void **)ptr, size: length, type: mt);
8354 } else {
8355 UA_clear(p: (void *) ptr, type: mt);
8356 }
8357}
8358
8359static void nopClear(void *p, const UA_DataType *type) { }
8360
8361const
8362UA_clearSignature clearJumpTable[UA_DATATYPEKINDS] = {
8363 (UA_clearSignature)nopClear, /* Boolean */
8364 (UA_clearSignature)nopClear, /* SByte */
8365 (UA_clearSignature)nopClear, /* Byte */
8366 (UA_clearSignature)nopClear, /* Int16 */
8367 (UA_clearSignature)nopClear, /* UInt16 */
8368 (UA_clearSignature)nopClear, /* Int32 */
8369 (UA_clearSignature)nopClear, /* UInt32 */
8370 (UA_clearSignature)nopClear, /* Int64 */
8371 (UA_clearSignature)nopClear, /* UInt64 */
8372 (UA_clearSignature)nopClear, /* Float */
8373 (UA_clearSignature)nopClear, /* Double */
8374 (UA_clearSignature)String_clear, /* String */
8375 (UA_clearSignature)nopClear, /* DateTime */
8376 (UA_clearSignature)nopClear, /* Guid */
8377 (UA_clearSignature)String_clear, /* ByteString */
8378 (UA_clearSignature)String_clear, /* XmlElement */
8379 (UA_clearSignature)NodeId_clear,
8380 (UA_clearSignature)ExpandedNodeId_clear,
8381 (UA_clearSignature)nopClear, /* StatusCode */
8382 (UA_clearSignature)QualifiedName_clear,
8383 (UA_clearSignature)LocalizedText_clear,
8384 (UA_clearSignature)ExtensionObject_clear,
8385 (UA_clearSignature)DataValue_clear,
8386 (UA_clearSignature)Variant_clear,
8387 (UA_clearSignature)DiagnosticInfo_clear,
8388 (UA_clearSignature)nopClear, /* Decimal, not implemented */
8389 (UA_clearSignature)nopClear, /* Enumeration */
8390 (UA_clearSignature)clearStructure,
8391 (UA_clearSignature)clearStructure, /* Struct with Optional Fields*/
8392 (UA_clearSignature)clearUnion, /* Union*/
8393 (UA_clearSignature)nopClear /* BitfieldCluster, not implemented*/
8394};
8395
8396void
8397UA_clear(void *p, const UA_DataType *type) {
8398 clearJumpTable[type->typeKind](p, type);
8399 memset(s: p, c: 0, n: type->memSize); /* init */
8400}
8401
8402void
8403UA_delete(void *p, const UA_DataType *type) {
8404 clearJumpTable[type->typeKind](p, type);
8405 UA_free(ptr: p);
8406}
8407
8408/******************/
8409/* Value Ordering */
8410/******************/
8411
8412#define UA_NUMERICORDER(NAME, TYPE) \
8413 static UA_Order \
8414 NAME(const TYPE *p1, const TYPE *p2, const UA_DataType *type) { \
8415 if(*p1 != *p2) \
8416 return (*p1 < *p2) ? UA_ORDER_LESS : UA_ORDER_MORE; \
8417 return UA_ORDER_EQ; \
8418 }
8419
8420UA_NUMERICORDER(booleanOrder, UA_Boolean)
8421UA_NUMERICORDER(sByteOrder, UA_SByte)
8422UA_NUMERICORDER(byteOrder, UA_Byte)
8423UA_NUMERICORDER(int16Order, UA_Int16)
8424UA_NUMERICORDER(uInt16Order, UA_UInt16)
8425UA_NUMERICORDER(int32Order, UA_Int32)
8426UA_NUMERICORDER(uInt32Order, UA_UInt32)
8427UA_NUMERICORDER(int64Order, UA_Int64)
8428UA_NUMERICORDER(uInt64Order, UA_UInt64)
8429
8430#define UA_FLOATORDER(NAME, TYPE) \
8431 static UA_Order \
8432 NAME(const TYPE *p1, const TYPE *p2, const UA_DataType *type) { \
8433 if(*p1 != *p2) { \
8434 /* p1 is NaN */ \
8435 if(*p1 != *p1) { \
8436 if(*p2 != *p2) \
8437 return UA_ORDER_EQ; \
8438 return UA_ORDER_LESS; \
8439 } \
8440 /* p2 is NaN */ \
8441 if(*p2 != *p2) \
8442 return UA_ORDER_MORE; \
8443 return (*p1 < *p2) ? UA_ORDER_LESS : UA_ORDER_MORE; \
8444 } \
8445 return UA_ORDER_EQ; \
8446 }
8447
8448UA_FLOATORDER(floatOrder, UA_Float)
8449UA_FLOATORDER(doubleOrder, UA_Double)
8450
8451static UA_Order
8452guidOrder(const UA_Guid *p1, const UA_Guid *p2, const UA_DataType *type) {
8453 if(p1->data1 != p2->data1)
8454 return (p1->data1 < p2->data1) ? UA_ORDER_LESS : UA_ORDER_MORE;
8455 if(p1->data2 != p2->data2)
8456 return (p1->data2 < p2->data2) ? UA_ORDER_LESS : UA_ORDER_MORE;
8457 if(p1->data3 != p2->data3)
8458 return (p1->data3 < p2->data3) ? UA_ORDER_LESS : UA_ORDER_MORE;
8459 int cmp = memcmp(s1: p1->data4, s2: p2->data4, n: 8);
8460 if(cmp != 0)
8461 return (cmp < 0) ? UA_ORDER_LESS : UA_ORDER_MORE;
8462 return UA_ORDER_EQ;
8463}
8464
8465static UA_Order
8466stringOrder(const UA_String *p1, const UA_String *p2, const UA_DataType *type) {
8467 if(p1->length != p2->length)
8468 return (p1->length < p2->length) ? UA_ORDER_LESS : UA_ORDER_MORE;
8469 /* For zero-length arrays, every pointer not NULL is considered a
8470 * UA_EMPTY_ARRAY_SENTINEL. */
8471 if(p1->data == p2->data) return UA_ORDER_EQ;
8472 if(p1->data == NULL) return UA_ORDER_LESS;
8473 if(p2->data == NULL) return UA_ORDER_MORE;
8474 int cmp = memcmp(s1: (const char*)p1->data, s2: (const char*)p2->data, n: p1->length);
8475 if(cmp != 0)
8476 return (cmp < 0) ? UA_ORDER_LESS : UA_ORDER_MORE;
8477 return UA_ORDER_EQ;
8478}
8479
8480static UA_Order
8481nodeIdOrder(const UA_NodeId *p1, const UA_NodeId *p2, const UA_DataType *_) {
8482 /* Compare namespaceIndex */
8483 if(p1->namespaceIndex != p2->namespaceIndex)
8484 return (p1->namespaceIndex < p2->namespaceIndex) ? UA_ORDER_LESS : UA_ORDER_MORE;
8485
8486 /* Compare identifierType */
8487 if(p1->identifierType != p2->identifierType)
8488 return (p1->identifierType < p2->identifierType) ? UA_ORDER_LESS : UA_ORDER_MORE;
8489
8490 /* Compare the identifier */
8491 switch(p1->identifierType) {
8492 case UA_NODEIDTYPE_NUMERIC:
8493 default:
8494 if(p1->identifier.numeric != p2->identifier.numeric)
8495 return (p1->identifier.numeric < p2->identifier.numeric) ?
8496 UA_ORDER_LESS : UA_ORDER_MORE;
8497 return UA_ORDER_EQ;
8498 case UA_NODEIDTYPE_GUID:
8499 return guidOrder(p1: &p1->identifier.guid, p2: &p2->identifier.guid, NULL);
8500 case UA_NODEIDTYPE_STRING:
8501 case UA_NODEIDTYPE_BYTESTRING:
8502 return stringOrder(p1: &p1->identifier.string, p2: &p2->identifier.string, NULL);
8503 }
8504}
8505
8506static UA_Order
8507expandedNodeIdOrder(const UA_ExpandedNodeId *p1, const UA_ExpandedNodeId *p2,
8508 const UA_DataType *_) {
8509 if(p1->serverIndex != p2->serverIndex)
8510 return (p1->serverIndex < p2->serverIndex) ? UA_ORDER_LESS : UA_ORDER_MORE;
8511 UA_Order o = stringOrder(p1: &p1->namespaceUri, p2: &p2->namespaceUri, NULL);
8512 if(o != UA_ORDER_EQ)
8513 return o;
8514 return nodeIdOrder(p1: &p1->nodeId, p2: &p2->nodeId, NULL);
8515}
8516
8517static UA_Order
8518qualifiedNameOrder(const UA_QualifiedName *p1, const UA_QualifiedName *p2,
8519 const UA_DataType *_) {
8520 if(p1->namespaceIndex != p2->namespaceIndex)
8521 return (p1->namespaceIndex < p2->namespaceIndex) ? UA_ORDER_LESS : UA_ORDER_MORE;
8522 return stringOrder(p1: &p1->name, p2: &p2->name, NULL);
8523}
8524
8525static UA_Order
8526localizedTextOrder(const UA_LocalizedText *p1, const UA_LocalizedText *p2,
8527 const UA_DataType *_) {
8528 UA_Order o = stringOrder(p1: &p1->locale, p2: &p2->locale, NULL);
8529 if(o != UA_ORDER_EQ)
8530 return o;
8531 return stringOrder(p1: &p1->text, p2: &p2->text, NULL);
8532}
8533
8534static UA_Order
8535extensionObjectOrder(const UA_ExtensionObject *p1, const UA_ExtensionObject *p2,
8536 const UA_DataType *_) {
8537 UA_ExtensionObjectEncoding enc1 = p1->encoding;
8538 UA_ExtensionObjectEncoding enc2 = p2->encoding;
8539 if(enc1 > UA_EXTENSIONOBJECT_DECODED)
8540 enc1 = UA_EXTENSIONOBJECT_DECODED;
8541 if(enc2 > UA_EXTENSIONOBJECT_DECODED)
8542 enc2 = UA_EXTENSIONOBJECT_DECODED;
8543 if(enc1 != enc2)
8544 return (enc1 < enc2) ? UA_ORDER_LESS : UA_ORDER_MORE;
8545
8546 switch(enc1) {
8547 case UA_EXTENSIONOBJECT_ENCODED_NOBODY:
8548 return UA_ORDER_EQ;
8549
8550 case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
8551 case UA_EXTENSIONOBJECT_ENCODED_XML: {
8552 UA_Order o = nodeIdOrder(p1: &p1->content.encoded.typeId,
8553 p2: &p2->content.encoded.typeId, NULL);
8554 if(o != UA_ORDER_EQ)
8555 return o;
8556 return stringOrder(p1: (const UA_String*)&p1->content.encoded.body,
8557 p2: (const UA_String*)&p2->content.encoded.body, NULL);
8558 }
8559
8560 case UA_EXTENSIONOBJECT_DECODED:
8561 default: {
8562 const UA_DataType *type1 = p1->content.decoded.type;
8563 const UA_DataType *type2 = p2->content.decoded.type;
8564 if(type1 != type2)
8565 return ((uintptr_t)type1 < (uintptr_t)type2) ? UA_ORDER_LESS : UA_ORDER_MORE;
8566 if(!type1)
8567 return UA_ORDER_EQ;
8568 return orderJumpTable[type1->typeKind]
8569 (p1->content.decoded.data, p2->content.decoded.data, type1);
8570 }
8571 }
8572}
8573
8574/* Part 4: When testing for equality, a Server shall treat null and empty arrays
8575 * as equal.
8576 *
8577 * Don't compare overlayable types as "binary blobs". We have specific order
8578 * rules also for some overlayable types. For example how NaN floats are
8579 * compared. */
8580static UA_Order
8581arrayOrder(const void *p1, size_t p1Length,
8582 const void *p2, size_t p2Length,
8583 const UA_DataType *type) {
8584 if(p1Length != p2Length)
8585 return (p1Length < p2Length) ? UA_ORDER_LESS : UA_ORDER_MORE;
8586 uintptr_t u1 = (uintptr_t)p1;
8587 uintptr_t u2 = (uintptr_t)p2;
8588 for(size_t i = 0; i < p1Length; i++) {
8589 UA_Order o = orderJumpTable[type->typeKind]((const void*)u1, (const void*)u2, type);
8590 if(o != UA_ORDER_EQ)
8591 return o;
8592 u1 += type->memSize;
8593 u2 += type->memSize;
8594 }
8595 return UA_ORDER_EQ;
8596}
8597
8598static UA_Order
8599variantOrder(const UA_Variant *p1, const UA_Variant *p2, const UA_DataType *_) {
8600 if(p1->type != p2->type)
8601 return ((uintptr_t)p1->type < (uintptr_t)p2->type) ? UA_ORDER_LESS : UA_ORDER_MORE;
8602
8603 UA_Order o;
8604 if(p1->type != NULL) {
8605 /* Check if both variants are scalars or arrays */
8606 UA_Boolean s1 = UA_Variant_isScalar(v: p1);
8607 UA_Boolean s2 = UA_Variant_isScalar(v: p2);
8608 if(s1 != s2)
8609 return s1 ? UA_ORDER_LESS : UA_ORDER_MORE;
8610 if(s1) {
8611 o = orderJumpTable[p1->type->typeKind](p1->data, p2->data, p1->type);
8612 } else {
8613 /* Mismatching array length? */
8614 if(p1->arrayLength != p2->arrayLength)
8615 return (p1->arrayLength < p2->arrayLength) ? UA_ORDER_LESS : UA_ORDER_MORE;
8616 o = arrayOrder(p1: p1->data, p1Length: p1->arrayLength, p2: p2->data, p2Length: p2->arrayLength, type: p1->type);
8617 }
8618 if(o != UA_ORDER_EQ)
8619 return o;
8620 }
8621
8622 if(p1->arrayDimensionsSize != p2->arrayDimensionsSize)
8623 return (p1->arrayDimensionsSize < p2->arrayDimensionsSize) ?
8624 UA_ORDER_LESS : UA_ORDER_MORE;
8625 o = UA_ORDER_EQ;
8626 if(p1->arrayDimensionsSize > 0)
8627 o = arrayOrder(p1: p1->arrayDimensions, p1Length: p1->arrayDimensionsSize,
8628 p2: p2->arrayDimensions, p2Length: p2->arrayDimensionsSize,
8629 type: &UA_TYPES[UA_TYPES_UINT32]);
8630 return o;
8631}
8632
8633static UA_Order
8634dataValueOrder(const UA_DataValue *p1, const UA_DataValue *p2, const UA_DataType *_) {
8635 /* Value */
8636 if(p1->hasValue != p2->hasValue)
8637 return (!p1->hasValue) ? UA_ORDER_LESS : UA_ORDER_MORE;
8638 if(p1->hasValue) {
8639 UA_Order o = variantOrder(p1: &p1->value, p2: &p2->value, NULL);
8640 if(o != UA_ORDER_EQ)
8641 return o;
8642 }
8643
8644 /* Status */
8645 if(p1->hasStatus != p2->hasStatus)
8646 return (!p1->hasStatus) ? UA_ORDER_LESS : UA_ORDER_MORE;
8647 if(p1->hasStatus && p1->status != p2->status)
8648 return (p1->status < p2->status) ? UA_ORDER_LESS : UA_ORDER_MORE;
8649
8650 /* SourceTimestamp */
8651 if(p1->hasSourceTimestamp != p2->hasSourceTimestamp)
8652 return (!p1->hasSourceTimestamp) ? UA_ORDER_LESS : UA_ORDER_MORE;
8653 if(p1->hasSourceTimestamp && p1->sourceTimestamp != p2->sourceTimestamp)
8654 return (p1->sourceTimestamp < p2->sourceTimestamp) ? UA_ORDER_LESS : UA_ORDER_MORE;
8655
8656 /* ServerTimestamp */
8657 if(p1->hasServerTimestamp != p2->hasServerTimestamp)
8658 return (!p1->hasServerTimestamp) ? UA_ORDER_LESS : UA_ORDER_MORE;
8659 if(p1->hasServerTimestamp && p1->serverTimestamp != p2->serverTimestamp)
8660 return (p1->serverTimestamp < p2->serverTimestamp) ? UA_ORDER_LESS : UA_ORDER_MORE;
8661
8662 /* SourcePicoseconds */
8663 if(p1->hasSourcePicoseconds != p2->hasSourcePicoseconds)
8664 return (!p1->hasSourcePicoseconds) ? UA_ORDER_LESS : UA_ORDER_MORE;
8665 if(p1->hasSourcePicoseconds && p1->sourcePicoseconds != p2->sourcePicoseconds)
8666 return (p1->sourcePicoseconds < p2->sourcePicoseconds) ?
8667 UA_ORDER_LESS : UA_ORDER_MORE;
8668
8669 /* ServerPicoseconds */
8670 if(p1->hasServerPicoseconds != p2->hasServerPicoseconds)
8671 return (!p1->hasServerPicoseconds) ? UA_ORDER_LESS : UA_ORDER_MORE;
8672 if(p1->hasServerPicoseconds && p1->serverPicoseconds != p2->serverPicoseconds)
8673 return (p1->serverPicoseconds < p2->serverPicoseconds) ?
8674 UA_ORDER_LESS : UA_ORDER_MORE;
8675
8676 return UA_ORDER_EQ;
8677}
8678
8679static UA_Order
8680diagnosticInfoOrder(const UA_DiagnosticInfo *p1, const UA_DiagnosticInfo *p2,
8681 const UA_DataType *_) {
8682 /* SymbolicId */
8683 if(p1->hasSymbolicId != p2->hasSymbolicId)
8684 return (!p1->hasSymbolicId) ? UA_ORDER_LESS : UA_ORDER_MORE;
8685 if(p1->hasSymbolicId && p1->symbolicId != p2->symbolicId)
8686 return (p1->symbolicId < p2->symbolicId) ? UA_ORDER_LESS : UA_ORDER_MORE;
8687
8688 /* NamespaceUri */
8689 if(p1->hasNamespaceUri != p2->hasNamespaceUri)
8690 return (!p1->hasNamespaceUri) ? UA_ORDER_LESS : UA_ORDER_MORE;
8691 if(p1->hasNamespaceUri && p1->namespaceUri != p2->namespaceUri)
8692 return (p1->namespaceUri < p2->namespaceUri) ? UA_ORDER_LESS : UA_ORDER_MORE;
8693
8694 /* LocalizedText */
8695 if(p1->hasLocalizedText != p2->hasLocalizedText)
8696 return (!p1->hasLocalizedText) ? UA_ORDER_LESS : UA_ORDER_MORE;
8697 if(p1->hasLocalizedText && p1->localizedText != p2->localizedText)
8698 return (p1->localizedText < p2->localizedText) ? UA_ORDER_LESS : UA_ORDER_MORE;
8699
8700 /* Locale */
8701 if(p1->hasLocale != p2->hasLocale)
8702 return (!p1->hasLocale) ? UA_ORDER_LESS : UA_ORDER_MORE;
8703 if(p1->hasLocale && p1->locale != p2->locale)
8704 return (p1->locale < p2->locale) ? UA_ORDER_LESS : UA_ORDER_MORE;
8705
8706 /* AdditionalInfo */
8707 if(p1->hasAdditionalInfo != p2->hasAdditionalInfo)
8708 return (!p1->hasAdditionalInfo) ? UA_ORDER_LESS : UA_ORDER_MORE;
8709 if(p1->hasAdditionalInfo) {
8710 UA_Order o = stringOrder(p1: &p1->additionalInfo, p2: &p2->additionalInfo, NULL);
8711 if(o != UA_ORDER_EQ)
8712 return o;
8713 }
8714
8715 /* InnerStatusCode */
8716 if(p1->hasInnerStatusCode != p2->hasInnerStatusCode)
8717 return (!p1->hasInnerStatusCode) ? UA_ORDER_LESS : UA_ORDER_MORE;
8718 if(p1->hasInnerStatusCode && p1->innerStatusCode != p2->innerStatusCode)
8719 return (p1->innerStatusCode < p2->innerStatusCode) ? UA_ORDER_LESS : UA_ORDER_MORE;
8720
8721 /* InnerDiagnosticInfo */
8722 if(p1->hasInnerDiagnosticInfo != p2->hasInnerDiagnosticInfo)
8723 return (!p1->hasInnerDiagnosticInfo) ? UA_ORDER_LESS : UA_ORDER_MORE;
8724 if(p1->innerDiagnosticInfo == p2->innerDiagnosticInfo)
8725 return UA_ORDER_EQ;
8726 if(!p1->innerDiagnosticInfo || !p2->innerDiagnosticInfo)
8727 return (!p1->innerDiagnosticInfo) ? UA_ORDER_LESS : UA_ORDER_MORE;
8728 return diagnosticInfoOrder(p1: p1->innerDiagnosticInfo, p2: p2->innerDiagnosticInfo, NULL);
8729}
8730
8731static UA_Order
8732structureOrder(const void *p1, const void *p2, const UA_DataType *type) {
8733 uintptr_t u1 = (uintptr_t)p1;
8734 uintptr_t u2 = (uintptr_t)p2;
8735 UA_Order o = UA_ORDER_EQ;
8736 for(size_t i = 0; i < type->membersSize; ++i) {
8737 const UA_DataTypeMember *m = &type->members[i];
8738 const UA_DataType *mt = m->memberType;
8739 u1 += m->padding;
8740 u2 += m->padding;
8741 if(!m->isOptional) {
8742 if(!m->isArray) {
8743 o = orderJumpTable[mt->typeKind]((const void *)u1, (const void *)u2, mt);
8744 u1 += mt->memSize;
8745 u2 += mt->memSize;
8746 } else {
8747 size_t size1 = *(size_t*)u1;
8748 size_t size2 = *(size_t*)u2;
8749 u1 += sizeof(size_t);
8750 u2 += sizeof(size_t);
8751 o = arrayOrder(p1: *(void* const*)u1, p1Length: size1, p2: *(void* const*)u2, p2Length: size2, type: mt);
8752 u1 += sizeof(void*);
8753 u2 += sizeof(void*);
8754 }
8755 } else {
8756 if(!m->isArray) {
8757 const void *pp1 = *(void* const*)u1;
8758 const void *pp2 = *(void* const*)u2;
8759 if(pp1 == pp2) {
8760 o = UA_ORDER_EQ;
8761 } else if(pp1 == NULL) {
8762 o = UA_ORDER_LESS;
8763 } else if(pp2 == NULL) {
8764 o = UA_ORDER_MORE;
8765 } else {
8766 o = orderJumpTable[mt->typeKind](pp1, pp2, mt);
8767 }
8768 } else {
8769 size_t sa1 = *(size_t*)u1;
8770 size_t sa2 = *(size_t*)u2;
8771 u1 += sizeof(size_t);
8772 u2 += sizeof(size_t);
8773 o = arrayOrder(p1: *(void* const*)u1, p1Length: sa1, p2: *(void* const*)u2, p2Length: sa2, type: mt);
8774 }
8775 u1 += sizeof(void*);
8776 u2 += sizeof(void*);
8777 }
8778
8779 if(o != UA_ORDER_EQ)
8780 break;
8781 }
8782 return o;
8783}
8784
8785static UA_Order
8786unionOrder(const void *p1, const void *p2, const UA_DataType *type) {
8787 UA_UInt32 sel1 = *(const UA_UInt32 *)p1;
8788 UA_UInt32 sel2 = *(const UA_UInt32 *)p2;
8789 if(sel1 != sel2)
8790 return (sel1 < sel2) ? UA_ORDER_LESS : UA_ORDER_MORE;
8791
8792 if(sel1 == 0) {
8793 return UA_ORDER_EQ;
8794 }
8795
8796 const UA_DataTypeMember *m = &type->members[sel1-1];
8797 const UA_DataType *mt = m->memberType;
8798
8799 uintptr_t u1 = ((uintptr_t)p1) + m->padding; /* includes switchfield length */
8800 uintptr_t u2 = ((uintptr_t)p2) + m->padding;
8801 if(m->isArray) {
8802 size_t sa1 = *(size_t*)u1;
8803 size_t sa2 = *(size_t*)u2;
8804 u1 += sizeof(size_t);
8805 u2 += sizeof(size_t);
8806 return arrayOrder(p1: *(void* const*)u1, p1Length: sa1, p2: *(void* const*)u2, p2Length: sa2, type: mt);
8807 }
8808 return orderJumpTable[mt->typeKind]((const void*)u1, (const void*)u2, mt);
8809}
8810
8811static UA_Order
8812notImplementedOrder(const void *p1, const void *p2, const UA_DataType *type) {
8813 return UA_ORDER_EQ;
8814}
8815
8816const
8817UA_orderSignature orderJumpTable[UA_DATATYPEKINDS] = {
8818 (UA_orderSignature)booleanOrder,
8819 (UA_orderSignature)sByteOrder,
8820 (UA_orderSignature)byteOrder,
8821 (UA_orderSignature)int16Order,
8822 (UA_orderSignature)uInt16Order,
8823 (UA_orderSignature)int32Order,
8824 (UA_orderSignature)uInt32Order,
8825 (UA_orderSignature)int64Order,
8826 (UA_orderSignature)uInt64Order,
8827 (UA_orderSignature)floatOrder,
8828 (UA_orderSignature)doubleOrder,
8829 (UA_orderSignature)stringOrder,
8830 (UA_orderSignature)int64Order, /* DateTime */
8831 (UA_orderSignature)guidOrder,
8832 (UA_orderSignature)stringOrder, /* ByteString */
8833 (UA_orderSignature)stringOrder, /* XmlElement */
8834 (UA_orderSignature)nodeIdOrder,
8835 (UA_orderSignature)expandedNodeIdOrder,
8836 (UA_orderSignature)uInt32Order, /* StatusCode */
8837 (UA_orderSignature)qualifiedNameOrder,
8838 (UA_orderSignature)localizedTextOrder,
8839 (UA_orderSignature)extensionObjectOrder,
8840 (UA_orderSignature)dataValueOrder,
8841 (UA_orderSignature)variantOrder,
8842 (UA_orderSignature)diagnosticInfoOrder,
8843 notImplementedOrder, /* Decimal, not implemented */
8844 (UA_orderSignature)uInt32Order, /* Enumeration */
8845 (UA_orderSignature)structureOrder,
8846 (UA_orderSignature)structureOrder, /* Struct with Optional Fields*/
8847 (UA_orderSignature)unionOrder, /* Union*/
8848 notImplementedOrder /* BitfieldCluster, not implemented */
8849};
8850
8851UA_Order UA_order(const void *p1, const void *p2, const UA_DataType *type) {
8852 return orderJumpTable[type->typeKind](p1, p2, type);
8853}
8854
8855/******************/
8856/* Array Handling */
8857/******************/
8858
8859void *
8860UA_Array_new(size_t size, const UA_DataType *type) {
8861 if(size > UA_INT32_MAX)
8862 return NULL;
8863 if(size == 0)
8864 return UA_EMPTY_ARRAY_SENTINEL;
8865 return UA_calloc(nmemb: size, size: type->memSize);
8866}
8867
8868UA_StatusCode
8869UA_Array_copy(const void *src, size_t size,
8870 void **dst, const UA_DataType *type) {
8871 if(size == 0) {
8872 if(src == NULL)
8873 *dst = NULL;
8874 else
8875 *dst= UA_EMPTY_ARRAY_SENTINEL;
8876 return UA_STATUSCODE_GOOD;
8877 }
8878
8879 /* Check the array consistency -- defensive programming in case the user
8880 * manually created an inconsistent array */
8881 if(UA_UNLIKELY(!type || !src))
8882 return UA_STATUSCODE_BADINTERNALERROR;
8883
8884 /* calloc, so we don't have to check retval in every iteration of copying */
8885 *dst = UA_calloc(nmemb: size, size: type->memSize);
8886 if(!*dst)
8887 return UA_STATUSCODE_BADOUTOFMEMORY;
8888
8889 if(type->pointerFree) {
8890 memcpy(dest: *dst, src: src, n: type->memSize * size);
8891 return UA_STATUSCODE_GOOD;
8892 }
8893
8894 uintptr_t ptrs = (uintptr_t)src;
8895 uintptr_t ptrd = (uintptr_t)*dst;
8896 UA_StatusCode retval = UA_STATUSCODE_GOOD;
8897 for(size_t i = 0; i < size; ++i) {
8898 retval |= UA_copy(src: (void*)ptrs, dst: (void*)ptrd, type);
8899 ptrs += type->memSize;
8900 ptrd += type->memSize;
8901 }
8902 if(retval != UA_STATUSCODE_GOOD) {
8903 UA_Array_delete(p: *dst, size, type);
8904 *dst = NULL;
8905 }
8906 return retval;
8907}
8908
8909UA_StatusCode
8910UA_Array_resize(void **p, size_t *size, size_t newSize,
8911 const UA_DataType *type) {
8912 if(*size == newSize)
8913 return UA_STATUSCODE_GOOD;
8914
8915 /* Empty array? */
8916 if(newSize == 0) {
8917 UA_Array_delete(p: *p, size: *size, type);
8918 *p = UA_EMPTY_ARRAY_SENTINEL;
8919 *size = 0;
8920 return UA_STATUSCODE_GOOD;
8921 }
8922
8923 /* Make a copy of the members that shall be removed. Realloc can fail during
8924 * trimming. So we cannot clear the members already here. */
8925 void *deleteMembers = NULL;
8926 if(newSize < *size && !type->pointerFree) {
8927 size_t deleteSize = *size - newSize;
8928 deleteMembers = UA_malloc(size: deleteSize * type->memSize);
8929 if(!deleteMembers)
8930 return UA_STATUSCODE_BADOUTOFMEMORY;
8931 memcpy(dest: deleteMembers, src: (void*)((uintptr_t)*p + (newSize * type->memSize)),
8932 n: deleteSize * type->memSize); /* shallow copy */
8933 }
8934
8935 void *oldP = *p;
8936 if(oldP == UA_EMPTY_ARRAY_SENTINEL)
8937 oldP = NULL;
8938
8939 /* Realloc */
8940 void *newP = UA_realloc(ptr: oldP, size: newSize * type->memSize);
8941 if(!newP) {
8942 if(deleteMembers)
8943 UA_free(ptr: deleteMembers);
8944 return UA_STATUSCODE_BADOUTOFMEMORY;
8945 }
8946
8947 /* Clear removed members or initialize the new ones. Note that deleteMembers
8948 * depends on type->pointerFree. */
8949 if(newSize > *size)
8950 memset(s: (void*)((uintptr_t)newP + (*size * type->memSize)), c: 0,
8951 n: (newSize - *size) * type->memSize);
8952 else if(deleteMembers)
8953 UA_Array_delete(p: deleteMembers, size: *size - newSize, type);
8954
8955 /* Set the new array */
8956 *p = newP;
8957 *size = newSize;
8958 return UA_STATUSCODE_GOOD;
8959}
8960
8961UA_StatusCode
8962UA_Array_append(void **p, size_t *size, void *newElem,
8963 const UA_DataType *type) {
8964 /* Resize the array */
8965 size_t oldSize = *size;
8966 UA_StatusCode res = UA_Array_resize(p, size, newSize: oldSize+1, type);
8967 if(res != UA_STATUSCODE_GOOD)
8968 return res;
8969
8970 /* Move the value */
8971 memcpy(dest: (void*)((uintptr_t)*p + (oldSize * type->memSize)),
8972 src: newElem, n: type->memSize);
8973 UA_init(p: newElem, type);
8974 return UA_STATUSCODE_GOOD;
8975}
8976
8977UA_StatusCode
8978UA_Array_appendCopy(void **p, size_t *size, const void *newElem,
8979 const UA_DataType *type) {
8980 char scratch[512];
8981 if(type->memSize > 512)
8982 return UA_STATUSCODE_BADINTERNALERROR;
8983
8984 /* Copy the value */
8985 UA_StatusCode res = UA_copy(src: newElem, dst: (void*)scratch, type);
8986 if(res != UA_STATUSCODE_GOOD)
8987 return res;
8988
8989 /* Append */
8990 res = UA_Array_append(p, size, newElem: (void*)scratch, type);
8991 if(res != UA_STATUSCODE_GOOD)
8992 UA_clear(p: (void*)scratch, type);
8993 return res;
8994}
8995
8996void
8997UA_Array_delete(void *p, size_t size, const UA_DataType *type) {
8998 if(!type->pointerFree) {
8999 uintptr_t ptr = (uintptr_t)p;
9000 for(size_t i = 0; i < size; ++i) {
9001 UA_clear(p: (void*)ptr, type);
9002 ptr += type->memSize;
9003 }
9004 }
9005 UA_free(ptr: (void*)((uintptr_t)p & ~(uintptr_t)UA_EMPTY_ARRAY_SENTINEL));
9006}
9007
9008#ifdef UA_ENABLE_TYPEDESCRIPTION
9009UA_Boolean
9010UA_DataType_getStructMember(const UA_DataType *type, const char *memberName,
9011 size_t *outOffset, const UA_DataType **outMemberType,
9012 UA_Boolean *outIsArray) {
9013 if(type->typeKind != UA_DATATYPEKIND_STRUCTURE &&
9014 type->typeKind != UA_DATATYPEKIND_OPTSTRUCT)
9015 return false;
9016
9017 size_t offset = 0;
9018 for(size_t i = 0; i < type->membersSize; ++i) {
9019 const UA_DataTypeMember *m = &type->members[i];
9020 const UA_DataType *mt = m->memberType;
9021 offset += m->padding;
9022
9023 if(strcmp(s1: memberName, s2: m->memberName) == 0) {
9024 *outOffset = offset;
9025 *outMemberType = mt;
9026 *outIsArray = m->isArray;
9027 return true;
9028 }
9029
9030 if(!m->isOptional) {
9031 if(!m->isArray) {
9032 offset += mt->memSize;
9033 } else {
9034 offset += sizeof(size_t);
9035 offset += sizeof(void*);
9036 }
9037 } else { /* field is optional */
9038 if(!m->isArray) {
9039 offset += sizeof(void *);
9040 } else {
9041 offset += sizeof(size_t);
9042 offset += sizeof(void *);
9043 }
9044 }
9045 }
9046
9047 return false;
9048}
9049#endif
9050
9051UA_Boolean
9052UA_DataType_isNumeric(const UA_DataType *type) {
9053 switch(type->typeKind) {
9054 case UA_DATATYPEKIND_SBYTE:
9055 case UA_DATATYPEKIND_BYTE:
9056 case UA_DATATYPEKIND_INT16:
9057 case UA_DATATYPEKIND_UINT16:
9058 case UA_DATATYPEKIND_INT32:
9059 case UA_DATATYPEKIND_UINT32:
9060 case UA_DATATYPEKIND_INT64:
9061 case UA_DATATYPEKIND_UINT64:
9062 case UA_DATATYPEKIND_FLOAT:
9063 case UA_DATATYPEKIND_DOUBLE:
9064 /* not implemented: UA_DATATYPEKIND_DECIMAL */
9065 return true;
9066 default:
9067 return false;
9068 }
9069}
9070
9071/**********************/
9072/* Parse NumericRange */
9073/**********************/
9074
9075static size_t
9076readDimension(UA_Byte *buf, size_t buflen, UA_NumericRangeDimension *dim) {
9077 size_t progress = UA_readNumber(buf, buflen, number: &dim->min);
9078 if(progress == 0)
9079 return 0;
9080 if(buflen <= progress + 1 || buf[progress] != ':') {
9081 dim->max = dim->min;
9082 return progress;
9083 }
9084
9085 ++progress;
9086 size_t progress2 = UA_readNumber(buf: &buf[progress], buflen: buflen - progress, number: &dim->max);
9087 if(progress2 == 0)
9088 return 0;
9089
9090 /* invalid range */
9091 if(dim->min >= dim->max)
9092 return 0;
9093
9094 return progress + progress2;
9095}
9096
9097UA_StatusCode
9098UA_NumericRange_parse(UA_NumericRange *range, const UA_String str) {
9099 size_t idx = 0;
9100 size_t dimensionsMax = 0;
9101 UA_NumericRangeDimension *dimensions = NULL;
9102 UA_StatusCode retval = UA_STATUSCODE_GOOD;
9103 size_t offset = 0;
9104 while(true) {
9105 /* alloc dimensions */
9106 if(idx >= dimensionsMax) {
9107 UA_NumericRangeDimension *newds;
9108 size_t newdssize = sizeof(UA_NumericRangeDimension) * (dimensionsMax + 2);
9109 newds = (UA_NumericRangeDimension*)UA_realloc(ptr: dimensions, size: newdssize);
9110 if(!newds) {
9111 retval = UA_STATUSCODE_BADOUTOFMEMORY;
9112 break;
9113 }
9114 dimensions = newds;
9115 dimensionsMax = dimensionsMax + 2;
9116 }
9117
9118 /* read the dimension */
9119 size_t progress = readDimension(buf: &str.data[offset], buflen: str.length - offset,
9120 dim: &dimensions[idx]);
9121 if(progress == 0) {
9122 retval = UA_STATUSCODE_BADINDEXRANGEINVALID;
9123 break;
9124 }
9125 offset += progress;
9126 ++idx;
9127
9128 /* loop into the next dimension */
9129 if(offset >= str.length)
9130 break;
9131
9132 if(str.data[offset] != ',') {
9133 retval = UA_STATUSCODE_BADINDEXRANGEINVALID;
9134 break;
9135 }
9136 ++offset;
9137 }
9138
9139 if(retval == UA_STATUSCODE_GOOD && idx > 0) {
9140 range->dimensions = dimensions;
9141 range->dimensionsSize = idx;
9142 } else {
9143 UA_free(ptr: dimensions);
9144 }
9145
9146 return retval;
9147}
9148
9149/**** amalgamated original file "/src/ua_types_encoding_binary.c" ****/
9150
9151/* This Source Code Form is subject to the terms of the Mozilla Public
9152 * License, v. 2.0. If a copy of the MPL was not distributed with this
9153 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9154 *
9155 * Copyright 2020 (c) Fraunhofer IOSB (Author: Andreas Ebner)
9156 * Copyright 2020 (c) Grigory Friedman
9157 * Copyright 2014-2021 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
9158 * Copyright 2014-2017 (c) Florian Palm
9159 * Copyright 2014-2016 (c) Sten Grüner
9160 * Copyright 2014 (c) Leon Urbas
9161 * Copyright 2015 (c) LEvertz
9162 * Copyright 2015 (c) Chris Iatrou
9163 * Copyright 2015-2016 (c) Oleksiy Vasylyev
9164 * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH
9165 * Copyright 2016 (c) Lorenz Haas
9166 * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB
9167 * Copyright 2017 (c) Henrik Norrman
9168 */
9169
9170
9171
9172/**
9173 * Type Encoding and Decoding
9174 * --------------------------
9175 * The following methods contain encoding and decoding functions for the builtin
9176 * data types and generic functions that operate on all types and arrays. This
9177 * requires the type description from a UA_DataType structure.
9178 *
9179 * Breaking a message up into chunks is integrated with the encoding. When the
9180 * end of a buffer is reached, a callback is executed that sends the current
9181 * buffer as a chunk and exchanges the encoding buffer "underneath" the ongoing
9182 * encoding. This reduces the RAM requirements and unnecessary copying. */
9183
9184/* Part 6 §5.1.5: Decoders shall support at least 100 nesting levels */
9185#define UA_ENCODING_MAX_RECURSION 100
9186
9187typedef struct {
9188 /* Pointers to the current and last buffer position */
9189 u8 *pos;
9190 const u8 *end;
9191
9192 /* How often did we en-/decoding recurse? */
9193 u16 depth;
9194
9195 const UA_DataTypeArray *customTypes;
9196 UA_exchangeEncodeBuffer exchangeBufferCallback;
9197 void *exchangeBufferCallbackHandle;
9198} Ctx;
9199
9200typedef status
9201(*encodeBinarySignature)(const void *UA_RESTRICT src, const UA_DataType *type,
9202 Ctx *UA_RESTRICT ctx);
9203typedef status
9204(*decodeBinarySignature)(void *UA_RESTRICT dst, const UA_DataType *type,
9205 Ctx *UA_RESTRICT ctx);
9206typedef size_t
9207(*calcSizeBinarySignature)(const void *UA_RESTRICT p, const UA_DataType *type);
9208
9209#define ENCODE_BINARY(TYPE) static status \
9210 TYPE##_encodeBinary(const UA_##TYPE *UA_RESTRICT src, \
9211 const UA_DataType *type, Ctx *UA_RESTRICT ctx)
9212#define DECODE_BINARY(TYPE) static status \
9213 TYPE##_decodeBinary(UA_##TYPE *UA_RESTRICT dst, \
9214 const UA_DataType *type, Ctx *UA_RESTRICT ctx)
9215#define CALCSIZE_BINARY(TYPE) static size_t \
9216 TYPE##_calcSizeBinary(const UA_##TYPE *UA_RESTRICT src, const UA_DataType *_)
9217#define ENCODE_DIRECT(SRC, TYPE) TYPE##_encodeBinary((const UA_##TYPE*)SRC, NULL, ctx)
9218#define DECODE_DIRECT(DST, TYPE) TYPE##_decodeBinary((UA_##TYPE*)DST, NULL, ctx)
9219
9220/* Jumptables for de-/encoding and computing the buffer length. The methods in
9221 * the decoding jumptable do not all clean up their allocated memory when an
9222 * error occurs. So a final _clear needs to be called before returning to the
9223 * user. */
9224extern const encodeBinarySignature encodeBinaryJumpTable[UA_DATATYPEKINDS];
9225extern const decodeBinarySignature decodeBinaryJumpTable[UA_DATATYPEKINDS];
9226extern const calcSizeBinarySignature calcSizeBinaryJumpTable[UA_DATATYPEKINDS];
9227
9228/* Send the current chunk and replace the buffer */
9229static status exchangeBuffer(Ctx *ctx) {
9230 if(!ctx->exchangeBufferCallback)
9231 return UA_STATUSCODE_BADENCODINGERROR;
9232 return ctx->exchangeBufferCallback(ctx->exchangeBufferCallbackHandle,
9233 &ctx->pos, &ctx->end);
9234}
9235
9236/* If encoding fails, exchange the buffer and try again. */
9237static status
9238encodeWithExchangeBuffer(const void *ptr, const UA_DataType *type, Ctx *ctx) {
9239 u8 *oldpos = ctx->pos; /* Last known good position */
9240#ifndef NDEBUG
9241 /* We have to ensure that the buffer was not exchanged AND
9242 * BADENCODINGLIMITSEXCEEDED was returned. If that were the case, oldpos
9243 * would be invalid. That means, a type encoding must never return
9244 * BADENCODINGLIMITSEXCEEDED once the buffer could have been exchanged. This
9245 * is achieved by the use of encodeWithExchangeBuffer. */
9246 const u8 *oldend = ctx->end;
9247 (void)oldend; /* For compilers who don't understand NDEBUG... */
9248#endif
9249 status ret = encodeBinaryJumpTable[type->typeKind](ptr, type, ctx);
9250 if(ret == UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED) {
9251 UA_assert(ctx->end == oldend);
9252 ctx->pos = oldpos; /* Set to the last known good position and exchange */
9253 ret = exchangeBuffer(ctx);
9254 UA_CHECK_STATUS(ret, return ret);
9255 ret = encodeBinaryJumpTable[type->typeKind](ptr, type, ctx);
9256 }
9257 return ret;
9258}
9259
9260/*****************/
9261/* Integer Types */
9262/*****************/
9263
9264#if !UA_BINARY_OVERLAYABLE_INTEGER
9265
9266#pragma message "Integer endianness could not be detected to be little endian. Use slow generic encoding."
9267
9268/* These en/decoding functions are only used when the architecture isn't little-endian. */
9269static void
9270UA_encode16(const u16 v, u8 buf[2]) {
9271 buf[0] = (u8)v;
9272 buf[1] = (u8)(v >> 8);
9273}
9274
9275static void
9276UA_decode16(const u8 buf[2], u16 *v) {
9277 *v = (u16)((u16)buf[0] + (((u16)buf[1]) << 8));
9278}
9279
9280static void
9281UA_encode32(const u32 v, u8 buf[4]) {
9282 buf[0] = (u8)v;
9283 buf[1] = (u8)(v >> 8);
9284 buf[2] = (u8)(v >> 16);
9285 buf[3] = (u8)(v >> 24);
9286}
9287
9288static void
9289UA_decode32(const u8 buf[4], u32 *v) {
9290 *v = (u32)((u32)buf[0] + (((u32)buf[1]) << 8) +
9291 (((u32)buf[2]) << 16) + (((u32)buf[3]) << 24));
9292}
9293
9294static void
9295UA_encode64(const u64 v, u8 buf[8]) {
9296 buf[0] = (u8)v;
9297 buf[1] = (u8)(v >> 8);
9298 buf[2] = (u8)(v >> 16);
9299 buf[3] = (u8)(v >> 24);
9300 buf[4] = (u8)(v >> 32);
9301 buf[5] = (u8)(v >> 40);
9302 buf[6] = (u8)(v >> 48);
9303 buf[7] = (u8)(v >> 56);
9304}
9305
9306static void
9307UA_decode64(const u8 buf[8], u64 *v) {
9308 *v = (u64)((u64)buf[0] + (((u64)buf[1]) << 8) +
9309 (((u64)buf[2]) << 16) + (((u64)buf[3]) << 24) +
9310 (((u64)buf[4]) << 32) + (((u64)buf[5]) << 40) +
9311 (((u64)buf[6]) << 48) + (((u64)buf[7]) << 56));
9312}
9313
9314#endif /* !UA_BINARY_OVERLAYABLE_INTEGER */
9315
9316/* Boolean */
9317/* Note that sizeof(bool) != 1 on some platforms. Overlayable integer encoding
9318 * is disabled in those cases. */
9319ENCODE_BINARY(Boolean) {
9320 UA_CHECK(ctx->pos + 1 <= ctx->end, return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9321 *ctx->pos = *(const u8*)src;
9322 ++ctx->pos;
9323 return UA_STATUSCODE_GOOD;
9324}
9325
9326DECODE_BINARY(Boolean) {
9327 UA_CHECK(ctx->pos + 1 <= ctx->end, return UA_STATUSCODE_BADDECODINGERROR);
9328 *dst = (*ctx->pos > 0) ? true : false;
9329 ++ctx->pos;
9330 return UA_STATUSCODE_GOOD;
9331}
9332
9333/* Byte */
9334ENCODE_BINARY(Byte) {
9335 UA_CHECK(ctx->pos + sizeof(u8) <= ctx->end,
9336 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9337 *ctx->pos = *(const u8*)src;
9338 ++ctx->pos;
9339 return UA_STATUSCODE_GOOD;
9340}
9341
9342DECODE_BINARY(Byte) {
9343 UA_CHECK(ctx->pos + sizeof(u8) <= ctx->end,
9344 return UA_STATUSCODE_BADDECODINGERROR);
9345 *dst = *ctx->pos;
9346 ++ctx->pos;
9347 return UA_STATUSCODE_GOOD;
9348}
9349
9350/* UInt16 */
9351ENCODE_BINARY(UInt16) {
9352 UA_CHECK(ctx->pos + sizeof(u16) <= ctx->end,
9353 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9354#if UA_BINARY_OVERLAYABLE_INTEGER
9355 memcpy(dest: ctx->pos, src: src, n: sizeof(u16));
9356#else
9357 UA_encode16(*src, ctx->pos);
9358#endif
9359 ctx->pos += 2;
9360 return UA_STATUSCODE_GOOD;
9361}
9362
9363DECODE_BINARY(UInt16) {
9364 UA_CHECK(ctx->pos + sizeof(u16) <= ctx->end,
9365 return UA_STATUSCODE_BADDECODINGERROR);
9366#if UA_BINARY_OVERLAYABLE_INTEGER
9367 memcpy(dest: dst, src: ctx->pos, n: sizeof(u16));
9368#else
9369 UA_decode16(ctx->pos, dst);
9370#endif
9371 ctx->pos += 2;
9372 return UA_STATUSCODE_GOOD;
9373}
9374
9375/* UInt32 */
9376ENCODE_BINARY(UInt32) {
9377 UA_CHECK(ctx->pos + sizeof(u32) <= ctx->end,
9378 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9379#if UA_BINARY_OVERLAYABLE_INTEGER
9380 memcpy(dest: ctx->pos, src: src, n: sizeof(u32));
9381#else
9382 UA_encode32(*src, ctx->pos);
9383#endif
9384 ctx->pos += 4;
9385 return UA_STATUSCODE_GOOD;
9386}
9387
9388DECODE_BINARY(UInt32) {
9389 UA_CHECK(ctx->pos + sizeof(u32) <= ctx->end,
9390 return UA_STATUSCODE_BADDECODINGERROR);
9391#if UA_BINARY_OVERLAYABLE_INTEGER
9392 memcpy(dest: dst, src: ctx->pos, n: sizeof(u32));
9393#else
9394 UA_decode32(ctx->pos, dst);
9395#endif
9396 ctx->pos += 4;
9397 return UA_STATUSCODE_GOOD;
9398}
9399
9400/* UInt64 */
9401ENCODE_BINARY(UInt64) {
9402 UA_CHECK(ctx->pos + sizeof(u64) <= ctx->end,
9403 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9404#if UA_BINARY_OVERLAYABLE_INTEGER
9405 memcpy(dest: ctx->pos, src: src, n: sizeof(u64));
9406#else
9407 UA_encode64(*src, ctx->pos);
9408#endif
9409 ctx->pos += 8;
9410 return UA_STATUSCODE_GOOD;
9411}
9412
9413DECODE_BINARY(UInt64) {
9414 UA_CHECK(ctx->pos + sizeof(u64) <= ctx->end,
9415 return UA_STATUSCODE_BADDECODINGERROR);
9416#if UA_BINARY_OVERLAYABLE_INTEGER
9417 memcpy(dest: dst, src: ctx->pos, n: sizeof(u64));
9418#else
9419 UA_decode64(ctx->pos, dst);
9420#endif
9421 ctx->pos += 8;
9422 return UA_STATUSCODE_GOOD;
9423}
9424
9425/************************/
9426/* Floating Point Types */
9427/************************/
9428
9429/* Can we reuse the integer encoding mechanism by casting floating point
9430 * values? */
9431#if (UA_FLOAT_IEEE754 == 1) && (UA_LITTLE_ENDIAN == UA_FLOAT_LITTLE_ENDIAN)
9432# define Float_encodeBinary UInt32_encodeBinary
9433# define Float_decodeBinary UInt32_decodeBinary
9434# define Double_encodeBinary UInt64_encodeBinary
9435# define Double_decodeBinary UInt64_decodeBinary
9436#else
9437
9438#include <math.h>
9439
9440#pragma message "No native IEEE 754 format detected. Use slow generic encoding."
9441
9442/* Handling of IEEE754 floating point values was taken from Beej's Guide to
9443 * Network Programming (http://beej.us/guide/bgnet/) and enhanced to cover the
9444 * edge cases +/-0, +/-inf and nan. */
9445static uint64_t
9446pack754(long double f, unsigned bits, unsigned expbits) {
9447 unsigned significandbits = bits - expbits - 1;
9448 long double fnorm;
9449 long long sign;
9450 if(f < 0) { sign = 1; fnorm = -f; }
9451 else { sign = 0; fnorm = f; }
9452 int shift = 0;
9453 while(fnorm >= 2.0) { fnorm /= 2.0; ++shift; }
9454 while(fnorm < 1.0) { fnorm *= 2.0; --shift; }
9455 fnorm = fnorm - 1.0;
9456 long long significand = (long long)(fnorm * ((float)(1LL<<significandbits) + 0.5f));
9457 long long exponent = shift + ((1<<(expbits-1)) - 1);
9458 return (uint64_t)((sign<<(bits-1)) | (exponent<<(bits-expbits-1)) | significand);
9459}
9460
9461static long double
9462unpack754(uint64_t i, unsigned bits, unsigned expbits) {
9463 unsigned significandbits = bits - expbits - 1;
9464 long double result = (long double)(i&(uint64_t)((1LL<<significandbits)-1));
9465 result /= (long double)(1LL<<significandbits);
9466 result += 1.0f;
9467 unsigned bias = (unsigned)(1<<(expbits-1)) - 1;
9468 long long shift = (long long)((i>>significandbits) & (uint64_t)((1LL<<expbits)-1)) - bias;
9469 while(shift > 0) { result *= 2.0; --shift; }
9470 while(shift < 0) { result /= 2.0; ++shift; }
9471 result *= ((i>>(bits-1))&1)? -1.0: 1.0;
9472 return result;
9473}
9474
9475/* Float */
9476#define FLOAT_NAN 0xffc00000
9477#define FLOAT_INF 0x7f800000
9478#define FLOAT_NEG_INF 0xff800000
9479#define FLOAT_NEG_ZERO 0x80000000
9480
9481ENCODE_BINARY(Float) {
9482 UA_Float f = *src;
9483 u32 encoded;
9484 /* cppcheck-suppress duplicateExpression */
9485 if(f != f) encoded = FLOAT_NAN;
9486 else if(f == 0.0f) encoded = signbit(f) ? FLOAT_NEG_ZERO : 0;
9487 else if(f/f != f/f) encoded = f > 0 ? FLOAT_INF : FLOAT_NEG_INF;
9488 else encoded = (u32)pack754(f, 32, 8);
9489 return ENCODE_DIRECT(&encoded, UInt32);
9490}
9491
9492DECODE_BINARY(Float) {
9493 u32 decoded;
9494 status ret = DECODE_DIRECT(&decoded, UInt32);
9495 if(ret != UA_STATUSCODE_GOOD)
9496 return ret;
9497 if(decoded == 0) *dst = 0.0f;
9498 else if(decoded == FLOAT_NEG_ZERO) *dst = -0.0f;
9499 else if(decoded == FLOAT_INF) *dst = INFINITY;
9500 else if(decoded == FLOAT_NEG_INF) *dst = -INFINITY;
9501 else if((decoded >= 0x7f800001 && decoded <= 0x7fffffff) ||
9502 (decoded >= 0xff800001)) *dst = NAN;
9503 else *dst = (UA_Float)unpack754(decoded, 32, 8);
9504 return UA_STATUSCODE_GOOD;
9505}
9506
9507/* Double */
9508#define DOUBLE_NAN 0xfff8000000000000L
9509#define DOUBLE_INF 0x7ff0000000000000L
9510#define DOUBLE_NEG_INF 0xfff0000000000000L
9511#define DOUBLE_NEG_ZERO 0x8000000000000000L
9512
9513ENCODE_BINARY(Double) {
9514 UA_Double d = *src;
9515 u64 encoded;
9516 /* cppcheck-suppress duplicateExpression */
9517 if(d != d) encoded = DOUBLE_NAN;
9518 else if(d == 0.0) encoded = signbit(d) ? DOUBLE_NEG_ZERO : 0;
9519 else if(d/d != d/d) encoded = d > 0 ? DOUBLE_INF : DOUBLE_NEG_INF;
9520 else encoded = pack754(d, 64, 11);
9521 return ENCODE_DIRECT(&encoded, UInt64);
9522}
9523
9524DECODE_BINARY(Double) {
9525 u64 decoded;
9526 status ret = DECODE_DIRECT(&decoded, UInt64);
9527 UA_CHECK_STATUS(ret, return ret);
9528 if(decoded == 0) *dst = 0.0;
9529 else if(decoded == DOUBLE_NEG_ZERO) *dst = -0.0;
9530 else if(decoded == DOUBLE_INF) *dst = INFINITY;
9531 else if(decoded == DOUBLE_NEG_INF) *dst = -INFINITY;
9532 else if((decoded >= 0x7ff0000000000001L && decoded <= 0x7fffffffffffffffL) ||
9533 (decoded >= 0xfff0000000000001L)) *dst = NAN;
9534 else *dst = (UA_Double)unpack754(decoded, 64, 11);
9535 return UA_STATUSCODE_GOOD;
9536}
9537
9538#endif
9539
9540/******************/
9541/* Array Handling */
9542/******************/
9543
9544static status
9545Array_encodeBinaryOverlayable(uintptr_t ptr, size_t memSize, Ctx *ctx) {
9546 /* Loop as long as more elements remain than fit into the chunk */
9547 while(ctx->end < ctx->pos + memSize) {
9548 size_t possible = ((uintptr_t)ctx->end - (uintptr_t)ctx->pos);
9549 memcpy(dest: ctx->pos, src: (void*)ptr, n: possible);
9550 ctx->pos += possible;
9551 ptr += possible;
9552 status ret = exchangeBuffer(ctx);
9553 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9554 UA_CHECK_STATUS(ret, return ret);
9555 memSize -= possible;
9556 }
9557
9558 /* Encode the remaining elements */
9559 memcpy(dest: ctx->pos, src: (void*)ptr, n: memSize);
9560 ctx->pos += memSize;
9561 return UA_STATUSCODE_GOOD;
9562}
9563
9564static status
9565Array_encodeBinaryComplex(uintptr_t ptr, size_t length,
9566 const UA_DataType *type, Ctx *ctx) {
9567 /* Encode every element */
9568 for(size_t i = 0; i < length; ++i) {
9569 status ret = encodeWithExchangeBuffer(ptr: (const void*)ptr, type, ctx);
9570 ptr += type->memSize;
9571 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9572 UA_CHECK_STATUS(ret, return ret); /* Unrecoverable fail */
9573 }
9574 return UA_STATUSCODE_GOOD;
9575}
9576
9577static status
9578Array_encodeBinary(const void *src, size_t length, const UA_DataType *type, Ctx *ctx) {
9579 /* Check and convert the array length to int32 */
9580 i32 signed_length = -1;
9581 if(length > UA_INT32_MAX)
9582 return UA_STATUSCODE_BADINTERNALERROR;
9583 if(length > 0)
9584 signed_length = (i32)length;
9585 else if(src >= UA_EMPTY_ARRAY_SENTINEL) /* src != NULL */
9586 signed_length = 0;
9587
9588 /* Encode the array length */
9589 status ret = encodeWithExchangeBuffer(ptr: &signed_length, type: &UA_TYPES[UA_TYPES_INT32], ctx);
9590 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9591 UA_CHECK_STATUS(ret, return ret);
9592
9593 /* Encode the content */
9594 if(length > 0) {
9595 if(type->overlayable)
9596 ret = Array_encodeBinaryOverlayable(ptr: (uintptr_t)src, memSize: length * type->memSize, ctx);
9597 else
9598 ret = Array_encodeBinaryComplex(ptr: (uintptr_t)src, length, type, ctx);
9599 }
9600 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9601 return ret;
9602}
9603
9604static status
9605Array_decodeBinary(void *UA_RESTRICT *UA_RESTRICT dst, size_t *out_length,
9606 const UA_DataType *type, Ctx *ctx) {
9607 /* Decode the length */
9608 i32 signed_length;
9609 status ret = DECODE_DIRECT(&signed_length, UInt32); /* Int32 */
9610 UA_CHECK_STATUS(ret, return ret);
9611
9612 /* Return early for empty arrays */
9613 if(signed_length <= 0) {
9614 *out_length = 0;
9615 if(signed_length < 0)
9616 *dst = NULL;
9617 else
9618 *dst = UA_EMPTY_ARRAY_SENTINEL;
9619 return UA_STATUSCODE_GOOD;
9620 }
9621
9622 /* Filter out arrays that can obviously not be decoded, because the message
9623 * is too small for the array length. This prevents the allocation of very
9624 * long arrays for bogus messages.
9625 *
9626 * The worst known case (so far) is UA_DataValue. It has
9627 * sizeof(UA_DataValue) == 80 and an empty DataValue is encoded with just
9628 * one byte. We use 128 as the smallest power of 2 larger than 80. */
9629 size_t length = (size_t)signed_length;
9630 UA_CHECK(ctx->pos + ((type->memSize * length) / 128) <= ctx->end,
9631 return UA_STATUSCODE_BADDECODINGERROR);
9632
9633 /* Allocate memory */
9634 *dst = UA_calloc(nmemb: length, size: type->memSize);
9635 UA_CHECK_MEM(*dst, return UA_STATUSCODE_BADOUTOFMEMORY);
9636
9637 if(type->overlayable) {
9638 /* memcpy overlayable array */
9639 UA_CHECK(ctx->pos + (type->memSize * length) <= ctx->end,
9640 UA_free(*dst); *dst = NULL; return UA_STATUSCODE_BADDECODINGERROR);
9641 memcpy(dest: *dst, src: ctx->pos, n: type->memSize * length);
9642 ctx->pos += type->memSize * length;
9643 } else {
9644 /* Decode array members */
9645 uintptr_t ptr = (uintptr_t)*dst;
9646 for(size_t i = 0; i < length; ++i) {
9647 ret = decodeBinaryJumpTable[type->typeKind]((void*)ptr, type, ctx);
9648 UA_CHECK_STATUS(ret, /* +1 because last element is also already initialized */
9649 UA_Array_delete(*dst, i+1, type); *dst = NULL; return ret);
9650 ptr += type->memSize;
9651 }
9652 }
9653 *out_length = length;
9654 return UA_STATUSCODE_GOOD;
9655}
9656
9657/*****************/
9658/* Builtin Types */
9659/*****************/
9660
9661ENCODE_BINARY(String) {
9662 return Array_encodeBinary(src: src->data, length: src->length, type: &UA_TYPES[UA_TYPES_BYTE], ctx);
9663}
9664
9665DECODE_BINARY(String) {
9666 return Array_decodeBinary(dst: (void**)&dst->data, out_length: &dst->length, type: &UA_TYPES[UA_TYPES_BYTE], ctx);
9667}
9668
9669/* Guid */
9670ENCODE_BINARY(Guid) {
9671 status ret = UA_STATUSCODE_GOOD;
9672 ret |= ENCODE_DIRECT(&src->data1, UInt32);
9673 ret |= ENCODE_DIRECT(&src->data2, UInt16);
9674 ret |= ENCODE_DIRECT(&src->data3, UInt16);
9675 UA_CHECK(ctx->pos + (8*sizeof(u8)) <= ctx->end,
9676 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9677 memcpy(dest: ctx->pos, src: src->data4, n: 8*sizeof(u8));
9678 ctx->pos += 8;
9679 return ret;
9680}
9681
9682DECODE_BINARY(Guid) {
9683 status ret = UA_STATUSCODE_GOOD;
9684 ret |= DECODE_DIRECT(&dst->data1, UInt32);
9685 ret |= DECODE_DIRECT(&dst->data2, UInt16);
9686 ret |= DECODE_DIRECT(&dst->data3, UInt16);
9687 UA_CHECK(ctx->pos + (8*sizeof(u8)) <= ctx->end,
9688 return UA_STATUSCODE_BADDECODINGERROR);
9689 memcpy(dest: dst->data4, src: ctx->pos, n: 8*sizeof(u8));
9690 ctx->pos += 8;
9691 return ret;
9692}
9693
9694/* NodeId */
9695#define UA_NODEIDTYPE_NUMERIC_TWOBYTE 0u
9696#define UA_NODEIDTYPE_NUMERIC_FOURBYTE 1u
9697#define UA_NODEIDTYPE_NUMERIC_COMPLETE 2u
9698
9699#define UA_EXPANDEDNODEID_SERVERINDEX_FLAG 0x40u
9700#define UA_EXPANDEDNODEID_NAMESPACEURI_FLAG 0x80u
9701
9702/* For ExpandedNodeId, we prefill the encoding mask. */
9703static status
9704NodeId_encodeBinaryWithEncodingMask(UA_NodeId const *src, u8 encoding, Ctx *ctx) {
9705 status ret = UA_STATUSCODE_GOOD;
9706 switch(src->identifierType) {
9707 case UA_NODEIDTYPE_NUMERIC:
9708 if(src->identifier.numeric > UA_UINT16_MAX || src->namespaceIndex > UA_BYTE_MAX) {
9709 encoding |= UA_NODEIDTYPE_NUMERIC_COMPLETE;
9710 ret |= ENCODE_DIRECT(&encoding, Byte);
9711 ret |= ENCODE_DIRECT(&src->namespaceIndex, UInt16);
9712 ret |= ENCODE_DIRECT(&src->identifier.numeric, UInt32);
9713 } else if(src->identifier.numeric > UA_BYTE_MAX || src->namespaceIndex > 0) {
9714 encoding |= UA_NODEIDTYPE_NUMERIC_FOURBYTE;
9715 ret |= ENCODE_DIRECT(&encoding, Byte);
9716 u8 nsindex = (u8)src->namespaceIndex;
9717 ret |= ENCODE_DIRECT(&nsindex, Byte);
9718 u16 identifier16 = (u16)src->identifier.numeric;
9719 ret |= ENCODE_DIRECT(&identifier16, UInt16);
9720 } else {
9721 encoding |= UA_NODEIDTYPE_NUMERIC_TWOBYTE;
9722 ret |= ENCODE_DIRECT(&encoding, Byte);
9723 u8 identifier8 = (u8)src->identifier.numeric;
9724 ret |= ENCODE_DIRECT(&identifier8, Byte);
9725 }
9726 break;
9727 case UA_NODEIDTYPE_STRING:
9728 encoding |= (u8)UA_NODEIDTYPE_STRING;
9729 ret |= ENCODE_DIRECT(&encoding, Byte);
9730 ret |= ENCODE_DIRECT(&src->namespaceIndex, UInt16);
9731 UA_CHECK_STATUS(ret, return ret);
9732 /* Can exchange the buffer */
9733 ret = ENCODE_DIRECT(&src->identifier.string, String);
9734 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9735 break;
9736 case UA_NODEIDTYPE_GUID:
9737 encoding |= (u8)UA_NODEIDTYPE_GUID;
9738 ret |= ENCODE_DIRECT(&encoding, Byte);
9739 ret |= ENCODE_DIRECT(&src->namespaceIndex, UInt16);
9740 ret |= ENCODE_DIRECT(&src->identifier.guid, Guid);
9741 break;
9742 case UA_NODEIDTYPE_BYTESTRING:
9743 encoding |= (u8)UA_NODEIDTYPE_BYTESTRING;
9744 ret |= ENCODE_DIRECT(&encoding, Byte);
9745 ret |= ENCODE_DIRECT(&src->namespaceIndex, UInt16);
9746 UA_CHECK_STATUS(ret, return ret);
9747 /* Can exchange the buffer */
9748 ret = ENCODE_DIRECT(&src->identifier.byteString, String); /* ByteString */
9749 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9750 break;
9751 default:
9752 return UA_STATUSCODE_BADINTERNALERROR;
9753 }
9754 return ret;
9755}
9756
9757ENCODE_BINARY(NodeId) {
9758 return NodeId_encodeBinaryWithEncodingMask(src, encoding: 0, ctx);
9759}
9760
9761DECODE_BINARY(NodeId) {
9762 u8 dstByte = 0, encodingByte = 0;
9763 u16 dstUInt16 = 0;
9764
9765 /* Decode the encoding bitfield */
9766 status ret = DECODE_DIRECT(&encodingByte, Byte);
9767 UA_CHECK_STATUS(ret, return ret);
9768
9769 /* Filter out the bits used only for ExpandedNodeIds */
9770 encodingByte &= (u8)~(u8)(UA_EXPANDEDNODEID_SERVERINDEX_FLAG |
9771 UA_EXPANDEDNODEID_NAMESPACEURI_FLAG);
9772
9773 /* Decode the namespace and identifier */
9774 switch(encodingByte) {
9775 case UA_NODEIDTYPE_NUMERIC_TWOBYTE:
9776 dst->identifierType = UA_NODEIDTYPE_NUMERIC;
9777 ret = DECODE_DIRECT(&dstByte, Byte);
9778 dst->identifier.numeric = dstByte;
9779 dst->namespaceIndex = 0;
9780 break;
9781 case UA_NODEIDTYPE_NUMERIC_FOURBYTE:
9782 dst->identifierType = UA_NODEIDTYPE_NUMERIC;
9783 ret |= DECODE_DIRECT(&dstByte, Byte);
9784 dst->namespaceIndex = dstByte;
9785 ret |= DECODE_DIRECT(&dstUInt16, UInt16);
9786 dst->identifier.numeric = dstUInt16;
9787 break;
9788 case UA_NODEIDTYPE_NUMERIC_COMPLETE:
9789 dst->identifierType = UA_NODEIDTYPE_NUMERIC;
9790 ret |= DECODE_DIRECT(&dst->namespaceIndex, UInt16);
9791 ret |= DECODE_DIRECT(&dst->identifier.numeric, UInt32);
9792 break;
9793 case UA_NODEIDTYPE_STRING:
9794 dst->identifierType = UA_NODEIDTYPE_STRING;
9795 ret |= DECODE_DIRECT(&dst->namespaceIndex, UInt16);
9796 ret |= DECODE_DIRECT(&dst->identifier.string, String);
9797 break;
9798 case UA_NODEIDTYPE_GUID:
9799 dst->identifierType = UA_NODEIDTYPE_GUID;
9800 ret |= DECODE_DIRECT(&dst->namespaceIndex, UInt16);
9801 ret |= DECODE_DIRECT(&dst->identifier.guid, Guid);
9802 break;
9803 case UA_NODEIDTYPE_BYTESTRING:
9804 dst->identifierType = UA_NODEIDTYPE_BYTESTRING;
9805 ret |= DECODE_DIRECT(&dst->namespaceIndex, UInt16);
9806 ret |= DECODE_DIRECT(&dst->identifier.byteString, String); /* ByteString */
9807 break;
9808 default:
9809 ret |= UA_STATUSCODE_BADINTERNALERROR;
9810 break;
9811 }
9812 return ret;
9813}
9814
9815/* ExpandedNodeId */
9816ENCODE_BINARY(ExpandedNodeId) {
9817 /* Set up the encoding mask */
9818 u8 encoding = 0;
9819 if((void*)src->namespaceUri.data > UA_EMPTY_ARRAY_SENTINEL)
9820 encoding |= UA_EXPANDEDNODEID_NAMESPACEURI_FLAG;
9821 if(src->serverIndex > 0)
9822 encoding |= UA_EXPANDEDNODEID_SERVERINDEX_FLAG;
9823
9824 /* Encode the NodeId. Can exchange the buffer. */
9825 status ret = NodeId_encodeBinaryWithEncodingMask(src: &src->nodeId, encoding, ctx);
9826 UA_CHECK_STATUS(ret, return ret);
9827
9828 /* Encode the namespace. Internally uses encodeWithExchangeBuffer
9829 * everywhere. So it will never return
9830 * UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED. */
9831 if((void*)src->namespaceUri.data > UA_EMPTY_ARRAY_SENTINEL) {
9832 ret = ENCODE_DIRECT(&src->namespaceUri, String);
9833 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9834 UA_CHECK_STATUS(ret, return ret);
9835 }
9836
9837 /* Encode the serverIndex */
9838 if(src->serverIndex > 0)
9839 ret = encodeWithExchangeBuffer(ptr: &src->serverIndex, type: &UA_TYPES[UA_TYPES_UINT32], ctx);
9840 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9841 return ret;
9842}
9843
9844DECODE_BINARY(ExpandedNodeId) {
9845 /* Decode the encoding mask */
9846 UA_CHECK(ctx->pos + 1 <= ctx->end, return UA_STATUSCODE_BADDECODINGERROR);
9847 u8 encoding = *ctx->pos;
9848
9849 /* Decode the NodeId */
9850 status ret = DECODE_DIRECT(&dst->nodeId, NodeId);
9851
9852 /* Decode the NamespaceUri */
9853 if(encoding & UA_EXPANDEDNODEID_NAMESPACEURI_FLAG) {
9854 dst->nodeId.namespaceIndex = 0;
9855 ret |= DECODE_DIRECT(&dst->namespaceUri, String);
9856 }
9857
9858 /* Decode the ServerIndex */
9859 if(encoding & UA_EXPANDEDNODEID_SERVERINDEX_FLAG)
9860 ret |= DECODE_DIRECT(&dst->serverIndex, UInt32);
9861 return ret;
9862}
9863
9864/* QualifiedName */
9865ENCODE_BINARY(QualifiedName) {
9866 status ret = ENCODE_DIRECT(&src->namespaceIndex, UInt16);
9867 /* Must check here so we can exchange the buffer in the string encoding */
9868 UA_CHECK_STATUS(ret, return ret);
9869 ret |= ENCODE_DIRECT(&src->name, String);
9870 return ret;
9871}
9872
9873DECODE_BINARY(QualifiedName) {
9874 status ret = DECODE_DIRECT(&dst->namespaceIndex, UInt16);
9875 ret |= DECODE_DIRECT(&dst->name, String);
9876 return ret;
9877}
9878
9879/* LocalizedText */
9880#define UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE 0x01u
9881#define UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT 0x02u
9882
9883ENCODE_BINARY(LocalizedText) {
9884 /* Set up the encoding mask */
9885 u8 encoding = 0;
9886 if(src->locale.data)
9887 encoding |= UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE;
9888 if(src->text.data)
9889 encoding |= UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT;
9890
9891 /* Encode the encoding byte */
9892 status ret = ENCODE_DIRECT(&encoding, Byte);
9893 /* Must check here so we can exchange the buffer in the string encoding */
9894 UA_CHECK_STATUS(ret, return ret);
9895
9896 /* Encode the strings */
9897 if(encoding & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE)
9898 ret |= ENCODE_DIRECT(&src->locale, String);
9899 if(encoding & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT)
9900 ret |= ENCODE_DIRECT(&src->text, String);
9901 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9902 return ret;
9903}
9904
9905DECODE_BINARY(LocalizedText) {
9906 /* Decode the encoding mask */
9907 u8 encoding = 0;
9908 status ret = DECODE_DIRECT(&encoding, Byte);
9909
9910 /* Decode the content */
9911 if(encoding & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE)
9912 ret |= DECODE_DIRECT(&dst->locale, String);
9913 if(encoding & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT)
9914 ret |= DECODE_DIRECT(&dst->text, String);
9915 return ret;
9916}
9917
9918/* The binary encoding has a different nodeid from the data type. So it is not
9919 * possible to reuse UA_findDataType */
9920static const UA_DataType *
9921UA_findDataTypeByBinaryInternal(const UA_NodeId *typeId, Ctx *ctx) {
9922 /* Always look in the built-in types first. Assume that only numeric
9923 * identifiers are used for the builtin types. (They may contain data types
9924 * from all namespaces though.) */
9925 if(typeId->identifierType == UA_NODEIDTYPE_NUMERIC) {
9926 for(size_t i = 0; i < UA_TYPES_COUNT; ++i) {
9927 if(UA_TYPES[i].binaryEncodingId.identifier.numeric == typeId->identifier.numeric &&
9928 UA_TYPES[i].binaryEncodingId.namespaceIndex == typeId->namespaceIndex)
9929 return &UA_TYPES[i];
9930 }
9931 }
9932
9933 const UA_DataTypeArray *customTypes = ctx->customTypes;
9934 while(customTypes) {
9935 for(size_t i = 0; i < customTypes->typesSize; ++i) {
9936 if(UA_NodeId_equal(p1: typeId, p2: &customTypes->types[i].binaryEncodingId))
9937 return &customTypes->types[i];
9938 }
9939 customTypes = customTypes->next;
9940 }
9941
9942 return NULL;
9943}
9944
9945const UA_DataType *
9946UA_findDataTypeByBinary(const UA_NodeId *typeId) {
9947 Ctx ctx;
9948 ctx.customTypes = NULL;
9949 return UA_findDataTypeByBinaryInternal(typeId, ctx: &ctx);
9950}
9951
9952/* ExtensionObject */
9953ENCODE_BINARY(ExtensionObject) {
9954 u8 encoding = (u8)src->encoding;
9955
9956 /* No content or already encoded content. */
9957 if(encoding <= UA_EXTENSIONOBJECT_ENCODED_XML) {
9958 /* Can exchange the buffer */
9959 status ret = ENCODE_DIRECT(&src->content.encoded.typeId, NodeId);
9960 UA_CHECK_STATUS(ret, return ret);
9961 ret = encodeWithExchangeBuffer(ptr: &encoding, type: &UA_TYPES[UA_TYPES_BYTE], ctx);
9962 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9963 UA_CHECK_STATUS(ret, return ret);
9964 switch(src->encoding) {
9965 case UA_EXTENSIONOBJECT_ENCODED_NOBODY:
9966 break;
9967 case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
9968 case UA_EXTENSIONOBJECT_ENCODED_XML:
9969 /* ByteString in disguise. Array encoding can exchange the buffer */
9970 ret = ENCODE_DIRECT(&src->content.encoded.body, String);
9971 break;
9972 default:
9973 ret = UA_STATUSCODE_BADINTERNALERROR;
9974 }
9975 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9976 return ret;
9977 }
9978
9979 /* Cannot encode with no data or no type description */
9980 if(!src->content.decoded.type || !src->content.decoded.data)
9981 return UA_STATUSCODE_BADENCODINGERROR;
9982
9983 /* Write the NodeId for the binary encoded type. This could perform a buffer
9984 * exchange, but can also return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED. */
9985 status ret = ENCODE_DIRECT(&src->content.decoded.type->binaryEncodingId, NodeId);
9986 UA_CHECK_STATUS(ret, return ret);
9987
9988 /* Encode the encoding byte */
9989 encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING;
9990 ret = encodeWithExchangeBuffer(ptr: &encoding, type: &UA_TYPES[UA_TYPES_BYTE], ctx);
9991 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
9992 UA_CHECK_STATUS(ret, return ret);
9993
9994 /* Encode the content length */
9995 const UA_DataType *contentType = src->content.decoded.type;
9996 size_t len = UA_calcSizeBinary(p: src->content.decoded.data, type: contentType);
9997 UA_CHECK(len <= UA_INT32_MAX, return UA_STATUSCODE_BADENCODINGERROR);
9998 i32 signed_len = (i32)len;
9999 ret = encodeWithExchangeBuffer(ptr: &signed_len, type: &UA_TYPES[UA_TYPES_INT32], ctx);
10000 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10001 UA_CHECK_STATUS(ret, return ret);
10002
10003 /* Encode the content */
10004 ret = encodeWithExchangeBuffer(ptr: src->content.decoded.data, type: contentType, ctx);
10005 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10006 return ret;
10007}
10008
10009static status
10010ExtensionObject_decodeBinaryContent(UA_ExtensionObject *dst, const UA_NodeId *typeId,
10011 Ctx *ctx) {
10012 /* Lookup the datatype */
10013 const UA_DataType *type = UA_findDataTypeByBinaryInternal(typeId, ctx);
10014
10015 /* Unknown type, just take the binary content */
10016 if(!type) {
10017 dst->encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING;
10018 UA_NodeId_copy(src: typeId, dst: &dst->content.encoded.typeId);
10019 return DECODE_DIRECT(&dst->content.encoded.body, String); /* ByteString */
10020 }
10021
10022 /* Allocate memory */
10023 dst->content.decoded.data = UA_new(type);
10024 UA_CHECK_MEM(dst->content.decoded.data, return UA_STATUSCODE_BADOUTOFMEMORY);
10025
10026 /* Jump over the length field (TODO: check if the decoded length matches) */
10027 ctx->pos += 4;
10028
10029 /* Decode */
10030 dst->encoding = UA_EXTENSIONOBJECT_DECODED;
10031 dst->content.decoded.type = type;
10032 return decodeBinaryJumpTable[type->typeKind](dst->content.decoded.data, type, ctx);
10033}
10034
10035DECODE_BINARY(ExtensionObject) {
10036 u8 encoding = 0;
10037 UA_NodeId binTypeId;
10038 UA_NodeId_init(p: &binTypeId);
10039
10040 status ret = UA_STATUSCODE_GOOD;
10041 ret |= DECODE_DIRECT(&binTypeId, NodeId);
10042 ret |= DECODE_DIRECT(&encoding, Byte);
10043 UA_CHECK_STATUS(ret, UA_NodeId_clear(&binTypeId); return ret);
10044
10045 switch(encoding) {
10046 case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
10047 ret = ExtensionObject_decodeBinaryContent(dst, typeId: &binTypeId, ctx);
10048 UA_NodeId_clear(p: &binTypeId);
10049 break;
10050 case UA_EXTENSIONOBJECT_ENCODED_NOBODY:
10051 dst->encoding = (UA_ExtensionObjectEncoding)encoding;
10052 dst->content.encoded.typeId = binTypeId; /* move to dst */
10053 dst->content.encoded.body = UA_BYTESTRING_NULL;
10054 break;
10055 case UA_EXTENSIONOBJECT_ENCODED_XML:
10056 dst->encoding = (UA_ExtensionObjectEncoding)encoding;
10057 dst->content.encoded.typeId = binTypeId; /* move to dst */
10058 ret = DECODE_DIRECT(&dst->content.encoded.body, String); /* ByteString */
10059 UA_CHECK_STATUS(ret, UA_NodeId_clear(&dst->content.encoded.typeId));
10060 break;
10061 default:
10062 UA_NodeId_clear(p: &binTypeId);
10063 ret = UA_STATUSCODE_BADDECODINGERROR;
10064 break;
10065 }
10066
10067 return ret;
10068}
10069
10070/* Variant */
10071
10072static status
10073Variant_encodeBinaryWrapExtensionObject(const UA_Variant *src,
10074 const UA_Boolean isArray, Ctx *ctx) {
10075 size_t length = 1; /* Default to 1 for a scalar. */
10076
10077 /* Encode the array length if required */
10078 status ret = UA_STATUSCODE_GOOD;
10079 if(isArray) {
10080 UA_CHECK(src->arrayLength <= UA_INT32_MAX, return UA_STATUSCODE_BADENCODINGERROR);
10081 length = src->arrayLength;
10082
10083 i32 encodedLength = (i32)src->arrayLength;
10084 ret = encodeWithExchangeBuffer(ptr: &encodedLength, type: &UA_TYPES[UA_TYPES_INT32], ctx);
10085 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10086 UA_CHECK_STATUS(ret, return ret);
10087 }
10088
10089 /* Set up the ExtensionObject */
10090 UA_ExtensionObject eo;
10091 UA_ExtensionObject_init(p: &eo);
10092 eo.encoding = UA_EXTENSIONOBJECT_DECODED;
10093 eo.content.decoded.type = src->type;
10094 const u16 memSize = src->type->memSize;
10095 uintptr_t ptr = (uintptr_t)src->data;
10096
10097 /* Iterate over the array */
10098 for(size_t i = 0; i < length && ret == UA_STATUSCODE_GOOD; ++i) {
10099 eo.content.decoded.data = (void*)ptr;
10100 ret = encodeWithExchangeBuffer(ptr: &eo, type: &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], ctx);
10101 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10102 ptr += memSize;
10103 }
10104 return ret;
10105}
10106
10107enum UA_VARIANT_ENCODINGMASKTYPE {
10108 UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK = 0x3Fu, /* bits 0:5 */
10109 UA_VARIANT_ENCODINGMASKTYPE_DIMENSIONS = (u8)(0x01u << 6u), /* bit 6 */
10110 UA_VARIANT_ENCODINGMASKTYPE_ARRAY = (u8)(0x01u << 7u) /* bit 7 */
10111};
10112
10113ENCODE_BINARY(Variant) {
10114 /* Quit early for the empty variant */
10115 u8 encoding = 0;
10116 if(!src->type)
10117 return ENCODE_DIRECT(&encoding, Byte);
10118
10119 /* Set the content type in the encoding mask */
10120 const UA_Boolean isBuiltin = (src->type->typeKind <= UA_DATATYPEKIND_DIAGNOSTICINFO);
10121 const UA_Boolean isEnum = (src->type->typeKind == UA_DATATYPEKIND_ENUM);
10122 if(isBuiltin)
10123 encoding = (u8)(encoding | (u8)((u8)UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (u8)(src->type->typeKind + 1u)));
10124 else if(isEnum)
10125 encoding = (u8)(encoding | (u8)((u8)UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (u8)(UA_TYPES_INT32 + 1u)));
10126 else
10127 encoding = (u8)(encoding | (u8)((u8)UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (u8)(UA_TYPES_EXTENSIONOBJECT + 1u)));
10128
10129 /* Set the array type in the encoding mask */
10130 const UA_Boolean isArray = src->arrayLength > 0 || src->data <= UA_EMPTY_ARRAY_SENTINEL;
10131 const UA_Boolean hasDimensions = isArray && src->arrayDimensionsSize > 0;
10132 if(isArray) {
10133 encoding |= (u8)UA_VARIANT_ENCODINGMASKTYPE_ARRAY;
10134 if(hasDimensions) {
10135 encoding |= (u8)UA_VARIANT_ENCODINGMASKTYPE_DIMENSIONS;
10136 size_t totalRequiredSize = 1;
10137 for(size_t i = 0; i < src->arrayDimensionsSize; ++i)
10138 totalRequiredSize *= src->arrayDimensions[i];
10139 if(totalRequiredSize != src->arrayLength) return UA_STATUSCODE_BADENCODINGERROR;
10140 }
10141 }
10142
10143 /* Encode the encoding byte */
10144 status ret = ENCODE_DIRECT(&encoding, Byte);
10145 UA_CHECK_STATUS(ret, return ret);
10146
10147 /* Encode the content. This can exchange the buffer. */
10148 if(!isBuiltin && !isEnum) {
10149 /* This could return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED. But we
10150 * have not exchanged the buffer so far. */
10151 ret = Variant_encodeBinaryWrapExtensionObject(src, isArray, ctx);
10152 } else if(!isArray) {
10153 ret = encodeWithExchangeBuffer(ptr: src->data, type: src->type, ctx);
10154 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10155 } else {
10156 ret = Array_encodeBinary(src: src->data, length: src->arrayLength, type: src->type, ctx);
10157 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10158 }
10159 UA_CHECK_STATUS(ret, return ret);
10160
10161 /* Encode the array dimensions */
10162 if(hasDimensions && ret == UA_STATUSCODE_GOOD)
10163 ret = Array_encodeBinary(src: src->arrayDimensions, length: src->arrayDimensionsSize,
10164 type: &UA_TYPES[UA_TYPES_INT32], ctx);
10165 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10166 return ret;
10167}
10168
10169static status
10170Variant_decodeBinaryUnwrapExtensionObject(UA_Variant *dst, Ctx *ctx) {
10171 /* Save the position in the ByteString. If unwrapping is not possible, start
10172 * from here to decode a normal ExtensionObject. */
10173 u8 *old_pos = ctx->pos;
10174
10175 /* Decode the DataType */
10176 UA_NodeId typeId;
10177 UA_NodeId_init(p: &typeId);
10178 status ret = DECODE_DIRECT(&typeId, NodeId);
10179 UA_CHECK_STATUS(ret, return ret);
10180
10181 /* Decode the EncodingByte */
10182 u8 encoding;
10183 ret = DECODE_DIRECT(&encoding, Byte);
10184 UA_CHECK_STATUS(ret, UA_NodeId_clear(&typeId); return ret);
10185
10186 /* Search for the datatype. Default to ExtensionObject. */
10187 if(encoding == UA_EXTENSIONOBJECT_ENCODED_BYTESTRING &&
10188 (dst->type = UA_findDataTypeByBinaryInternal(typeId: &typeId, ctx)) != NULL) {
10189 /* Jump over the length field (TODO: check if length matches) */
10190 ctx->pos += 4;
10191 } else {
10192 /* Reset and decode as ExtensionObject */
10193 dst->type = &UA_TYPES[UA_TYPES_EXTENSIONOBJECT];
10194 ctx->pos = old_pos;
10195 }
10196 UA_NodeId_clear(p: &typeId);
10197
10198 /* Allocate memory */
10199 dst->data = UA_new(type: dst->type);
10200 UA_CHECK_MEM(dst->data, return UA_STATUSCODE_BADOUTOFMEMORY);
10201
10202 /* Decode the content */
10203 return decodeBinaryJumpTable[dst->type->typeKind](dst->data, dst->type, ctx);
10204}
10205
10206/* Unwraps all ExtensionObjects in an array if they have the same type.
10207 * For that we check whether all ExtensionObjects have the same header. */
10208static status
10209Variant_decodeBinaryUnwrapExtensionObjectArray(void *UA_RESTRICT *UA_RESTRICT dst,
10210 size_t *out_length, const UA_DataType **type,
10211 Ctx *ctx) {
10212 u8 *orig_pos = ctx->pos;
10213
10214 /* Decode the length */
10215 i32 signed_length;
10216 status ret = DECODE_DIRECT(&signed_length, UInt32); /* Int32 */
10217 UA_CHECK_STATUS(ret, return ret);
10218
10219 /* Return early for empty arrays */
10220 if(signed_length <= 0) {
10221 *out_length = 0;
10222 if(signed_length < 0)
10223 *dst = NULL;
10224 else
10225 *dst = UA_EMPTY_ARRAY_SENTINEL;
10226 /* The *type field stays an ExtensionObject, as we did not decode any
10227 * member who's type is known. */
10228 return UA_STATUSCODE_GOOD;
10229 }
10230
10231 /* Protect against memory exhaustion by unrealistic array lengths. An
10232 * ExtensionObject is at least 4 byte long (3 byte NodeId + 1 Byte encoding
10233 * field). */
10234 size_t length = (size_t)signed_length;
10235 UA_CHECK(ctx->pos + ((4 * length) / 32) <= ctx->end,
10236 return UA_STATUSCODE_BADDECODINGERROR);
10237
10238 /* Decode the type NodeId of the first member */
10239 UA_NodeId binTypeId;
10240 UA_NodeId_init(p: &binTypeId);
10241 ret |= DECODE_DIRECT(&binTypeId, NodeId);
10242 UA_CHECK_STATUS(ret, return ret);
10243
10244 /* Lookup the data type */
10245 const UA_DataType *contentType = UA_findDataTypeByBinaryInternal(typeId: &binTypeId, ctx);
10246 UA_NodeId_clear(p: &binTypeId);
10247 if(!contentType) {
10248 /* DataType unknown, decode as ExtensionObject array */
10249 ctx->pos = orig_pos;
10250 return Array_decodeBinary(dst, out_length, type: *type, ctx);
10251 }
10252
10253 /* Check that the encoding is binary */
10254 u8 encoding = 0;
10255 ret |= DECODE_DIRECT(&encoding, Byte);
10256 UA_CHECK_STATUS(ret, return ret);
10257 if(encoding != UA_EXTENSIONOBJECT_ENCODED_BYTESTRING) {
10258 /* Encoding format is not automatically decoded, decode as
10259 * ExtensionObject array */
10260 ctx->pos = orig_pos;
10261 return Array_decodeBinary(dst, out_length, type: *type, ctx);
10262 }
10263
10264 /* Compare the header of all array members if the array can be unwrapped */
10265 UA_ByteString header = {(uintptr_t)ctx->pos - (uintptr_t)orig_pos - 4, &orig_pos[4]};
10266 UA_ByteString compare_header = header;
10267 ctx->pos = &orig_pos[4];
10268
10269 for(size_t i = 0; i < length; i++) {
10270 compare_header.data = ctx->pos;
10271 UA_CHECK(compare_header.data + compare_header.length <= ctx->end,
10272 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10273 if(!UA_ByteString_equal(p1: &header, p2: &compare_header)) {
10274 /* Different member types, decode as ExtensionObject array */
10275 ctx->pos = orig_pos;
10276 return Array_decodeBinary(dst, out_length, type: *type, ctx);
10277 }
10278
10279 /* Decode the length field and jump to the next element */
10280 ctx->pos += header.length;
10281 u32 member_length = 0;
10282 ret = DECODE_DIRECT(&member_length, UInt32);
10283 UA_CHECK_STATUS(ret, return ret);
10284 ctx->pos += member_length;
10285 }
10286
10287 /* Allocate memory for the unwrapped members */
10288 *dst = UA_calloc(nmemb: length, size: contentType->memSize);
10289 UA_CHECK_MEM(*dst, return UA_STATUSCODE_BADOUTOFMEMORY);
10290 *out_length = length;
10291 *type = contentType;
10292
10293 /* Decode unwrapped members */
10294 uintptr_t array_pos = (uintptr_t)*dst;
10295 ctx->pos = &orig_pos[4];
10296 for(size_t i = 0; i < length && ret == UA_STATUSCODE_GOOD; i++) {
10297 ctx->pos += header.length + 4; /* Jump over the header and length field */
10298 ret = decodeBinaryJumpTable[contentType->typeKind]
10299 ((void*)array_pos, contentType, ctx);
10300 array_pos += contentType->memSize;
10301 }
10302 return ret;
10303}
10304
10305/* The resulting variant always has the storagetype UA_VARIANT_DATA. */
10306DECODE_BINARY(Variant) {
10307 /* Decode the encoding byte */
10308 u8 encodingByte;
10309 status ret = DECODE_DIRECT(&encodingByte, Byte);
10310 UA_CHECK_STATUS(ret, return ret);
10311
10312 /* Return early for an empty variant (was already _inited) */
10313 if(encodingByte == 0)
10314 return UA_STATUSCODE_GOOD;
10315
10316 /* Does the variant contain an array? */
10317 const UA_Boolean isArray = (encodingByte & (u8)UA_VARIANT_ENCODINGMASKTYPE_ARRAY) > 0;
10318
10319 /* Get the datatype of the content. The type must be a builtin data type.
10320 * All not-builtin types are wrapped in an ExtensionObject. The "type kind"
10321 * for types up to DiagnsticInfo equals to the index in the encoding
10322 * byte. */
10323 size_t typeKind = (size_t)((encodingByte & (u8)UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK) - 1);
10324 UA_CHECK(typeKind <= UA_DATATYPEKIND_DIAGNOSTICINFO, return UA_STATUSCODE_BADDECODINGERROR);
10325
10326 /* A variant cannot contain a variant. But it can contain an array of
10327 * variants */
10328 UA_CHECK(typeKind != UA_DATATYPEKIND_VARIANT || isArray,
10329 return UA_STATUSCODE_BADDECODINGERROR);
10330
10331 /* Check the recursion limit */
10332 UA_CHECK(ctx->depth <= UA_ENCODING_MAX_RECURSION, return UA_STATUSCODE_BADENCODINGERROR);
10333 ctx->depth++;
10334
10335 /* Decode the content */
10336 dst->type = &UA_TYPES[typeKind];
10337 if(!isArray) {
10338 /* Decode scalar */
10339 if(typeKind != UA_DATATYPEKIND_EXTENSIONOBJECT) {
10340 dst->data = UA_new(type: dst->type);
10341 UA_CHECK_MEM(dst->data, ctx->depth--; return UA_STATUSCODE_BADOUTOFMEMORY);
10342 ret = decodeBinaryJumpTable[typeKind](dst->data, dst->type, ctx);
10343 } else {
10344 ret = Variant_decodeBinaryUnwrapExtensionObject(dst, ctx);
10345 }
10346 } else {
10347 /* Decode array */
10348 if(typeKind != UA_DATATYPEKIND_EXTENSIONOBJECT) {
10349 ret = Array_decodeBinary(dst: &dst->data, out_length: &dst->arrayLength, type: dst->type, ctx);
10350 } else {
10351 ret = Variant_decodeBinaryUnwrapExtensionObjectArray(dst: &dst->data, out_length: &dst->arrayLength,
10352 type: &dst->type, ctx);
10353 }
10354
10355 /* Decode array dimensions */
10356 if((encodingByte & (u8)UA_VARIANT_ENCODINGMASKTYPE_DIMENSIONS) > 0) {
10357 ret |= Array_decodeBinary(dst: (void**)&dst->arrayDimensions, out_length: &dst->arrayDimensionsSize,
10358 type: &UA_TYPES[UA_TYPES_INT32], ctx);
10359 /* Validate array length against array dimensions */
10360 size_t totalSize = 1;
10361 for(size_t i = 0; i < dst->arrayDimensionsSize; ++i) {
10362 if(dst->arrayDimensions[i] == 0)
10363 ret = UA_STATUSCODE_BADDECODINGERROR;
10364 totalSize *= dst->arrayDimensions[i];
10365 }
10366 UA_CHECK(totalSize == dst->arrayLength, ret = UA_STATUSCODE_BADDECODINGERROR);
10367 }
10368 }
10369
10370 ctx->depth--;
10371 return ret;
10372}
10373
10374/* DataValue */
10375ENCODE_BINARY(DataValue) {
10376 /* Set up the encoding mask */
10377 u8 encodingMask = src->hasValue;
10378 encodingMask |= (u8)(src->hasStatus << 1u);
10379 encodingMask |= (u8)(src->hasSourceTimestamp << 2u);
10380 encodingMask |= (u8)(src->hasServerTimestamp << 3u);
10381 encodingMask |= (u8)(src->hasSourcePicoseconds << 4u);
10382 encodingMask |= (u8)(src->hasServerPicoseconds << 5u);
10383
10384 /* Encode the encoding byte */
10385 status ret = ENCODE_DIRECT(&encodingMask, Byte);
10386 UA_CHECK_STATUS(ret, return ret);
10387
10388 /* Encode the variant. */
10389 if(src->hasValue) {
10390 ret = ENCODE_DIRECT(&src->value, Variant);
10391 if(ret != UA_STATUSCODE_GOOD)
10392 return ret;
10393 }
10394
10395 if(src->hasStatus)
10396 ret |= encodeWithExchangeBuffer(ptr: &src->status, type: &UA_TYPES[UA_TYPES_STATUSCODE], ctx);
10397 if(src->hasSourceTimestamp)
10398 ret |= encodeWithExchangeBuffer(ptr: &src->sourceTimestamp, type: &UA_TYPES[UA_TYPES_DATETIME], ctx);
10399 if(src->hasSourcePicoseconds)
10400 ret |= encodeWithExchangeBuffer(ptr: &src->sourcePicoseconds, type: &UA_TYPES[UA_TYPES_UINT16], ctx);
10401 if(src->hasServerTimestamp)
10402 ret |= encodeWithExchangeBuffer(ptr: &src->serverTimestamp, type: &UA_TYPES[UA_TYPES_DATETIME], ctx);
10403 if(src->hasServerPicoseconds)
10404 ret |= encodeWithExchangeBuffer(ptr: &src->serverPicoseconds, type: &UA_TYPES[UA_TYPES_UINT16], ctx);
10405 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10406 return ret;
10407}
10408
10409#define MAX_PICO_SECONDS 9999
10410
10411DECODE_BINARY(DataValue) {
10412 /* Decode the encoding mask */
10413 u8 encodingMask;
10414 status ret = DECODE_DIRECT(&encodingMask, Byte);
10415 UA_CHECK_STATUS(ret, return ret);
10416
10417 /* Check the recursion limit */
10418 UA_CHECK(ctx->depth <= UA_ENCODING_MAX_RECURSION, return UA_STATUSCODE_BADENCODINGERROR);
10419 ctx->depth++;
10420
10421 /* Decode the content */
10422 if(encodingMask & 0x01u) {
10423 dst->hasValue = true;
10424 ret |= DECODE_DIRECT(&dst->value, Variant);
10425 }
10426 if(encodingMask & 0x02u) {
10427 dst->hasStatus = true;
10428 ret |= DECODE_DIRECT(&dst->status, UInt32); /* StatusCode */
10429 }
10430 if(encodingMask & 0x04u) {
10431 dst->hasSourceTimestamp = true;
10432 ret |= DECODE_DIRECT(&dst->sourceTimestamp, UInt64); /* DateTime */
10433 }
10434 if(encodingMask & 0x10u) {
10435 dst->hasSourcePicoseconds = true;
10436 ret |= DECODE_DIRECT(&dst->sourcePicoseconds, UInt16);
10437 if(dst->sourcePicoseconds > MAX_PICO_SECONDS)
10438 dst->sourcePicoseconds = MAX_PICO_SECONDS;
10439 }
10440 if(encodingMask & 0x08u) {
10441 dst->hasServerTimestamp = true;
10442 ret |= DECODE_DIRECT(&dst->serverTimestamp, UInt64); /* DateTime */
10443 }
10444 if(encodingMask & 0x20u) {
10445 dst->hasServerPicoseconds = true;
10446 ret |= DECODE_DIRECT(&dst->serverPicoseconds, UInt16);
10447 if(dst->serverPicoseconds > MAX_PICO_SECONDS)
10448 dst->serverPicoseconds = MAX_PICO_SECONDS;
10449 }
10450
10451 ctx->depth--;
10452 return ret;
10453}
10454
10455/* DiagnosticInfo */
10456ENCODE_BINARY(DiagnosticInfo) {
10457 /* Set up the encoding mask */
10458 u8 encodingMask = src->hasSymbolicId;
10459 encodingMask |= (u8)(src->hasNamespaceUri << 1u);
10460 encodingMask |= (u8)(src->hasLocalizedText << 2u);
10461 encodingMask |= (u8)(src->hasLocale << 3u);
10462 encodingMask |= (u8)(src->hasAdditionalInfo << 4u);
10463 encodingMask |= (u8)(src->hasInnerStatusCode << 5u);
10464 encodingMask |= (u8)(src->hasInnerDiagnosticInfo << 6u);
10465
10466 /* Encode the numeric content */
10467 status ret = ENCODE_DIRECT(&encodingMask, Byte);
10468 if(src->hasSymbolicId)
10469 ret |= ENCODE_DIRECT(&src->symbolicId, UInt32); /* Int32 */
10470 if(src->hasNamespaceUri)
10471 ret |= ENCODE_DIRECT(&src->namespaceUri, UInt32); /* Int32 */
10472 if(src->hasLocale)
10473 ret |= ENCODE_DIRECT(&src->locale, UInt32); /* Int32 */
10474 if(src->hasLocalizedText)
10475 ret |= ENCODE_DIRECT(&src->localizedText, UInt32); /* Int32 */
10476 if(ret != UA_STATUSCODE_GOOD)
10477 return ret;
10478
10479 /* Encode the additional info. Can exchange the buffer. */
10480 if(src->hasAdditionalInfo) {
10481 ret = ENCODE_DIRECT(&src->additionalInfo, String);
10482 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10483 UA_CHECK_STATUS(ret, return ret);
10484 }
10485
10486 /* Encode the inner status code */
10487 if(src->hasInnerStatusCode) {
10488 ret = encodeWithExchangeBuffer(ptr: &src->innerStatusCode, type: &UA_TYPES[UA_TYPES_UINT32], ctx);
10489 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10490 UA_CHECK_STATUS(ret, return ret);
10491 }
10492
10493 /* Encode the inner diagnostic info */
10494 if(src->hasInnerDiagnosticInfo) {
10495 ret = encodeWithExchangeBuffer(ptr: src->innerDiagnosticInfo,
10496 type: &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], ctx);
10497 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10498 }
10499
10500 return ret;
10501}
10502
10503DECODE_BINARY(DiagnosticInfo) {
10504 /* Decode the encoding mask */
10505 u8 encodingMask;
10506 status ret = DECODE_DIRECT(&encodingMask, Byte);
10507 UA_CHECK_STATUS(ret, return ret);
10508
10509 /* Decode the content */
10510 if(encodingMask & 0x01u) {
10511 dst->hasSymbolicId = true;
10512 ret |= DECODE_DIRECT(&dst->symbolicId, UInt32); /* Int32 */
10513 }
10514 if(encodingMask & 0x02u) {
10515 dst->hasNamespaceUri = true;
10516 ret |= DECODE_DIRECT(&dst->namespaceUri, UInt32); /* Int32 */
10517 }
10518 if(encodingMask & 0x08u) {
10519 dst->hasLocale = true;
10520 ret |= DECODE_DIRECT(&dst->locale, UInt32); /* Int32 */
10521 }
10522 if(encodingMask & 0x04u) {
10523 dst->hasLocalizedText = true;
10524 ret |= DECODE_DIRECT(&dst->localizedText, UInt32); /* Int32 */
10525 }
10526 if(encodingMask & 0x10u) {
10527 dst->hasAdditionalInfo = true;
10528 ret |= DECODE_DIRECT(&dst->additionalInfo, String);
10529 }
10530 if(encodingMask & 0x20u) {
10531 dst->hasInnerStatusCode = true;
10532 ret |= DECODE_DIRECT(&dst->innerStatusCode, UInt32); /* StatusCode */
10533 }
10534 if(encodingMask & 0x40u) {
10535 /* innerDiagnosticInfo is allocated on the heap */
10536 dst->innerDiagnosticInfo = (UA_DiagnosticInfo*)
10537 UA_calloc(nmemb: 1, size: sizeof(UA_DiagnosticInfo));
10538 UA_CHECK_MEM(dst->innerDiagnosticInfo, return UA_STATUSCODE_BADOUTOFMEMORY);
10539 dst->hasInnerDiagnosticInfo = true;
10540
10541 /* Check the recursion limit */
10542 UA_CHECK(ctx->depth <= UA_ENCODING_MAX_RECURSION,
10543 return UA_STATUSCODE_BADENCODINGERROR);
10544
10545 ctx->depth++;
10546 ret |= DECODE_DIRECT(dst->innerDiagnosticInfo, DiagnosticInfo);
10547 ctx->depth--;
10548 }
10549 return ret;
10550}
10551
10552/********************/
10553/* Structured Types */
10554/********************/
10555
10556static status
10557encodeBinaryStruct(const void *src, const UA_DataType *type, Ctx *ctx) {
10558 /* Check the recursion limit */
10559 UA_CHECK(ctx->depth <= UA_ENCODING_MAX_RECURSION,
10560 return UA_STATUSCODE_BADENCODINGERROR);
10561 ctx->depth++;
10562
10563 /* Loop over members */
10564 uintptr_t ptr = (uintptr_t)src;
10565 status ret = UA_STATUSCODE_GOOD;
10566 for(size_t i = 0; i < type->membersSize && ret == UA_STATUSCODE_GOOD; ++i) {
10567 const UA_DataTypeMember *m = &type->members[i];
10568 const UA_DataType *mt = m->memberType;
10569 ptr += m->padding;
10570
10571 /* Array. Buffer-exchange is done inside Array_encodeBinary if required. */
10572 if(m->isArray) {
10573 const size_t length = *((const size_t*)ptr);
10574 ptr += sizeof(size_t);
10575 ret = Array_encodeBinary(src: *(void *UA_RESTRICT const *)ptr, length, type: mt, ctx);
10576 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10577 ptr += sizeof(void*);
10578 continue;
10579 }
10580
10581 /* Scalar */
10582 ret = encodeWithExchangeBuffer(ptr: (const void*)ptr, type: mt, ctx);
10583 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10584 ptr += mt->memSize;
10585 }
10586
10587 ctx->depth--;
10588 return ret;
10589}
10590
10591static status
10592encodeBinaryStructWithOptFields(const void *src, const UA_DataType *type, Ctx *ctx) {
10593 /* Check the recursion limit */
10594 if(ctx->depth > UA_ENCODING_MAX_RECURSION)
10595 return UA_STATUSCODE_BADENCODINGERROR;
10596 ctx->depth++;
10597
10598 /* Creating the encoding mask, marking the available optional fields */
10599 uintptr_t ptr = (uintptr_t)src;
10600 size_t optFieldCounter = 0;
10601 UA_UInt32 encodingMask = 0;
10602 for(size_t j = 0; j < type->membersSize; ++j) {
10603 const UA_DataTypeMember *m = &type->members[j];
10604 const UA_DataType *mt = m->memberType;
10605 ptr += m->padding;
10606 if(m->isOptional) {
10607 if(m->isArray)
10608 ptr += sizeof(size_t);
10609 if(*(void* const*)ptr != NULL)
10610 encodingMask |= (UA_UInt32) 1 << optFieldCounter;
10611 ptr += sizeof(void *);
10612 optFieldCounter++;
10613 } else if (m->isArray) {
10614 ptr += sizeof(size_t);
10615 ptr += sizeof(void *);
10616 } else {
10617 ptr += mt->memSize;
10618 }
10619 }
10620
10621 /* Encode the mask */
10622 status ret = ENCODE_DIRECT(&encodingMask, UInt32);
10623 UA_CHECK_STATUS(ret, ctx->depth--; return ret);
10624
10625 /* Loop over members */
10626 ptr = (uintptr_t)src;
10627 for(size_t i = 0, o = 0; i < type->membersSize && UA_LIKELY(ret == UA_STATUSCODE_GOOD); ++i) {
10628 const UA_DataTypeMember *m = &type->members[i];
10629 const UA_DataType *mt = m->memberType;
10630 ptr += m->padding;
10631
10632 if(m->isOptional) {
10633 if(!(encodingMask & (UA_UInt32) ( (UA_UInt32) 1<<(o++)))) {
10634 /* Optional and not contained */
10635 if(m->isArray)
10636 ptr += sizeof(size_t);
10637 } else if(m->isArray) {
10638 /* Optional Array */
10639 const size_t length = *((const size_t *) ptr);
10640 ptr += sizeof(size_t);
10641 ret = Array_encodeBinary(src: *(void *UA_RESTRICT const *) ptr, length, type: mt, ctx);
10642 } else {
10643 /* Optional Scalar */
10644 ret = encodeWithExchangeBuffer(ptr: *(void* const*) ptr, type: mt, ctx);
10645 }
10646 ptr += sizeof(void *);
10647 continue;
10648 }
10649
10650 /* Mandatory Array */
10651 if(m->isArray) {
10652 const size_t length = *((const size_t *) ptr);
10653 ptr += sizeof(size_t);
10654 ret = Array_encodeBinary(src: *(void *UA_RESTRICT const *) ptr, length, type: mt, ctx);
10655 ptr += sizeof(void *);
10656 continue;
10657 }
10658
10659 /* Mandatory Scalar */
10660 ret = encodeWithExchangeBuffer(ptr: (const void*)ptr, type: mt, ctx);
10661 ptr += mt->memSize;
10662 }
10663 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10664
10665 ctx->depth--;
10666 return ret;
10667}
10668
10669static status
10670encodeBinaryUnion(const void *src, const UA_DataType *type, Ctx *ctx) {
10671 /* Check the recursion limit */
10672 UA_CHECK(ctx->depth <= UA_ENCODING_MAX_RECURSION,
10673 return UA_STATUSCODE_BADENCODINGERROR);
10674 ctx->depth++;
10675
10676 /* Encode the selection */
10677 const UA_UInt32 selection = *(const UA_UInt32*)src;
10678 status ret = ENCODE_DIRECT(&selection, UInt32);
10679 if(UA_UNLIKELY(ret != UA_STATUSCODE_GOOD) || selection == 0) {
10680 ctx->depth--;
10681 return ret;
10682 }
10683
10684 /* Select the member */
10685 const UA_DataTypeMember *m = &type->members[selection-1];
10686 const UA_DataType *mt = m->memberType;
10687
10688 /* Encode the member */
10689 uintptr_t ptr = ((uintptr_t)src) + m->padding; /* includes the switchfield length */
10690 if(!m->isArray) {
10691 ret = encodeWithExchangeBuffer(ptr: (const void*)ptr, type: mt, ctx);
10692 } else {
10693 const size_t length = *((const size_t*)ptr);
10694 ptr += sizeof(size_t);
10695 ret = Array_encodeBinary(src: *(void *UA_RESTRICT const *)ptr, length, type: mt, ctx);
10696 }
10697
10698 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10699
10700 ctx->depth--;
10701 return ret;
10702}
10703
10704static status
10705encodeBinaryNotImplemented(const void *src, const UA_DataType *type, Ctx *ctx) {
10706 (void)src, (void)type, (void)ctx;
10707 return UA_STATUSCODE_BADNOTIMPLEMENTED;
10708}
10709
10710const encodeBinarySignature encodeBinaryJumpTable[UA_DATATYPEKINDS] = {
10711 (encodeBinarySignature)Boolean_encodeBinary,
10712 (encodeBinarySignature)Byte_encodeBinary, /* SByte */
10713 (encodeBinarySignature)Byte_encodeBinary,
10714 (encodeBinarySignature)UInt16_encodeBinary, /* Int16 */
10715 (encodeBinarySignature)UInt16_encodeBinary,
10716 (encodeBinarySignature)UInt32_encodeBinary, /* Int32 */
10717 (encodeBinarySignature)UInt32_encodeBinary,
10718 (encodeBinarySignature)UInt64_encodeBinary, /* Int64 */
10719 (encodeBinarySignature)UInt64_encodeBinary,
10720 (encodeBinarySignature)Float_encodeBinary,
10721 (encodeBinarySignature)Double_encodeBinary,
10722 (encodeBinarySignature)String_encodeBinary,
10723 (encodeBinarySignature)UInt64_encodeBinary, /* DateTime */
10724 (encodeBinarySignature)Guid_encodeBinary,
10725 (encodeBinarySignature)String_encodeBinary, /* ByteString */
10726 (encodeBinarySignature)String_encodeBinary, /* XmlElement */
10727 (encodeBinarySignature)NodeId_encodeBinary,
10728 (encodeBinarySignature)ExpandedNodeId_encodeBinary,
10729 (encodeBinarySignature)UInt32_encodeBinary, /* StatusCode */
10730 (encodeBinarySignature)QualifiedName_encodeBinary,
10731 (encodeBinarySignature)LocalizedText_encodeBinary,
10732 (encodeBinarySignature)ExtensionObject_encodeBinary,
10733 (encodeBinarySignature)DataValue_encodeBinary,
10734 (encodeBinarySignature)Variant_encodeBinary,
10735 (encodeBinarySignature)DiagnosticInfo_encodeBinary,
10736 (encodeBinarySignature)encodeBinaryNotImplemented, /* Decimal */
10737 (encodeBinarySignature)UInt32_encodeBinary, /* Enumeration */
10738 (encodeBinarySignature)encodeBinaryStruct,
10739 (encodeBinarySignature)encodeBinaryStructWithOptFields, /* Structure with Optional Fields */
10740 (encodeBinarySignature)encodeBinaryUnion, /* Union */
10741 (encodeBinarySignature)encodeBinaryStruct /* BitfieldCluster */
10742};
10743
10744status
10745UA_encodeBinaryInternal(const void *src, const UA_DataType *type,
10746 u8 **bufPos, const u8 **bufEnd,
10747 UA_exchangeEncodeBuffer exchangeCallback,
10748 void *exchangeHandle) {
10749 if(!type || !src)
10750 return UA_STATUSCODE_BADENCODINGERROR;
10751
10752 /* Set up the context */
10753 Ctx ctx;
10754 ctx.pos = *bufPos;
10755 ctx.end = *bufEnd;
10756 ctx.depth = 0;
10757 ctx.exchangeBufferCallback = exchangeCallback;
10758 ctx.exchangeBufferCallbackHandle = exchangeHandle;
10759
10760 UA_CHECK_MEM(ctx.pos, return UA_STATUSCODE_BADINVALIDARGUMENT);
10761
10762 /* Encode */
10763 status ret = encodeWithExchangeBuffer(ptr: src, type, ctx: &ctx);
10764 UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED);
10765
10766 /* Set the new buffer position for the output. Beware that the buffer might
10767 * have been exchanged internally. */
10768 *bufPos = ctx.pos;
10769 *bufEnd = ctx.end;
10770 return ret;
10771}
10772
10773UA_StatusCode
10774UA_encodeBinary(const void *p, const UA_DataType *type,
10775 UA_ByteString *outBuf) {
10776 /* Allocate buffer */
10777 UA_Boolean allocated = false;
10778 status res = UA_STATUSCODE_GOOD;
10779 if(outBuf->length == 0) {
10780 size_t len = UA_calcSizeBinary(p, type);
10781 res = UA_ByteString_allocBuffer(bs: outBuf, length: len);
10782 if(res != UA_STATUSCODE_GOOD)
10783 return res;
10784 allocated = true;
10785 }
10786
10787 /* Encode */
10788 u8 *pos = outBuf->data;
10789 const u8 *posEnd = &outBuf->data[outBuf->length];
10790 res = UA_encodeBinaryInternal(src: p, type, bufPos: &pos, bufEnd: &posEnd, NULL, NULL);
10791
10792 /* Clean up */
10793 if(res == UA_STATUSCODE_GOOD) {
10794 outBuf->length = (size_t)((uintptr_t)pos - (uintptr_t)outBuf->data);
10795 } else if(allocated) {
10796 UA_ByteString_clear(p: outBuf);
10797 }
10798 return res;
10799}
10800
10801static status
10802decodeBinaryNotImplemented(void *dst, const UA_DataType *type, Ctx *ctx) {
10803 (void)dst, (void)type, (void)ctx;
10804 return UA_STATUSCODE_BADNOTIMPLEMENTED;
10805}
10806
10807static status
10808decodeBinaryStructure(void *dst, const UA_DataType *type, Ctx *ctx) {
10809 /* Check the recursion limit */
10810 UA_CHECK(ctx->depth <= UA_ENCODING_MAX_RECURSION,
10811 return UA_STATUSCODE_BADENCODINGERROR);
10812 ctx->depth++;
10813
10814 uintptr_t ptr = (uintptr_t)dst;
10815 status ret = UA_STATUSCODE_GOOD;
10816 u8 membersSize = type->membersSize;
10817
10818 /* Loop over members */
10819 for(size_t i = 0; i < membersSize && ret == UA_STATUSCODE_GOOD; ++i) {
10820 const UA_DataTypeMember *m = &type->members[i];
10821 const UA_DataType *mt = m->memberType;
10822 ptr += m->padding;
10823
10824 /* Array */
10825 if(m->isArray) {
10826 size_t *length = (size_t*)ptr;
10827 ptr += sizeof(size_t);
10828 ret = Array_decodeBinary(dst: (void *UA_RESTRICT *UA_RESTRICT)ptr, out_length: length, type: mt , ctx);
10829 ptr += sizeof(void*);
10830 continue;
10831 }
10832
10833 /* Scalar */
10834 ret = decodeBinaryJumpTable[mt->typeKind]((void *UA_RESTRICT)ptr, mt, ctx);
10835 ptr += mt->memSize;
10836 }
10837
10838 ctx->depth--;
10839 return ret;
10840}
10841
10842static status
10843decodeBinaryStructureWithOptFields(void *dst, const UA_DataType *type, Ctx *ctx) {
10844 /* Check the recursion limit */
10845 UA_CHECK(ctx->depth <= UA_ENCODING_MAX_RECURSION, return UA_STATUSCODE_BADENCODINGERROR);
10846 ctx->depth++;
10847
10848 uintptr_t ptr = (uintptr_t)dst;
10849 UA_UInt32 encodingMask = 0;
10850 status ret = UInt32_decodeBinary(dst: &encodingMask, type: &UA_TYPES[UA_TYPES_UINT32], ctx);
10851 UA_CHECK_STATUS(ret, ctx->depth--; return ret);
10852
10853 /* Loop over members */
10854 for(size_t i = 0, o = 0; i < type->membersSize && ret == UA_STATUSCODE_GOOD; ++i) {
10855 const UA_DataTypeMember *m = &type->members[i];
10856 const UA_DataType *mt = m->memberType;
10857 ptr += m->padding;
10858 if(m->isOptional) {
10859 if(!(encodingMask & (UA_UInt32) ( (UA_UInt32) 1<<(o++)))) {
10860 /* Optional field is not contained */
10861 if(m->isArray)
10862 ptr += sizeof(size_t);
10863 } else if(m->isArray) {
10864 /* Optional Array */
10865 size_t *length = (size_t*)ptr;
10866 ptr += sizeof(size_t);
10867 ret = Array_decodeBinary(dst: (void *UA_RESTRICT *UA_RESTRICT)ptr, out_length: length, type: mt , ctx);
10868 } else {
10869 /* Optional Scalar */
10870 *(void *UA_RESTRICT *UA_RESTRICT) ptr = UA_calloc(nmemb: 1, size: mt->memSize);
10871 UA_CHECK_MEM(*(void *UA_RESTRICT *UA_RESTRICT) ptr, return UA_STATUSCODE_BADOUTOFMEMORY);
10872 ret = decodeBinaryJumpTable[mt->typeKind](*(void *UA_RESTRICT *UA_RESTRICT) ptr, mt, ctx);
10873 }
10874 ptr += sizeof(void *);
10875 continue;
10876 }
10877
10878 /* Array */
10879 if(m->isArray) {
10880 size_t *length = (size_t *)ptr;
10881 ptr += sizeof(size_t);
10882 ret = Array_decodeBinary(dst: (void *UA_RESTRICT *UA_RESTRICT)ptr, out_length: length, type: mt, ctx);
10883 ptr += sizeof(void *);
10884 continue;
10885 }
10886
10887 /* Scalar */
10888 ret = decodeBinaryJumpTable[mt->typeKind]((void *UA_RESTRICT)ptr, mt, ctx);
10889 ptr += mt->memSize;
10890 }
10891 ctx->depth--;
10892 return ret;
10893}
10894
10895static status
10896decodeBinaryUnion(void *UA_RESTRICT dst, const UA_DataType *type, Ctx *ctx) {
10897 /* Check the recursion limit */
10898 UA_CHECK(ctx->depth <= UA_ENCODING_MAX_RECURSION,
10899 return UA_STATUSCODE_BADENCODINGERROR);
10900
10901 /* Decode the selection directly into the switchfield */
10902 status ret = DECODE_DIRECT(dst, UInt32);
10903 UA_CHECK_STATUS(ret, return ret);
10904
10905 /* No content? */
10906 UA_UInt32 selection = *(UA_UInt32*)dst;
10907 if(selection == 0)
10908 return UA_STATUSCODE_GOOD;
10909
10910 /* Sanity check the selection */
10911 UA_CHECK(selection-1 < type->membersSize,
10912 return UA_STATUSCODE_BADDECODINGERROR);
10913
10914 /* Select the member */
10915 const UA_DataTypeMember *m = &type->members[selection-1];
10916 const UA_DataType *mt = m->memberType;
10917
10918 /* Decode */
10919 ctx->depth++;
10920 uintptr_t ptr = ((uintptr_t)dst) + m->padding; /* includes the switchfield */
10921 if(!m->isArray) {
10922 ret = decodeBinaryJumpTable[mt->typeKind]((void *UA_RESTRICT)ptr, mt, ctx);
10923 } else {
10924 size_t *length = (size_t *)ptr;
10925 ptr += sizeof(size_t);
10926 ret = Array_decodeBinary(dst: (void *UA_RESTRICT *UA_RESTRICT)ptr, out_length: length, type: mt, ctx);
10927 }
10928 ctx->depth--;
10929 return ret;
10930}
10931
10932const decodeBinarySignature decodeBinaryJumpTable[UA_DATATYPEKINDS] = {
10933 (decodeBinarySignature)Boolean_decodeBinary,
10934 (decodeBinarySignature)Byte_decodeBinary, /* SByte */
10935 (decodeBinarySignature)Byte_decodeBinary,
10936 (decodeBinarySignature)UInt16_decodeBinary, /* Int16 */
10937 (decodeBinarySignature)UInt16_decodeBinary,
10938 (decodeBinarySignature)UInt32_decodeBinary, /* Int32 */
10939 (decodeBinarySignature)UInt32_decodeBinary,
10940 (decodeBinarySignature)UInt64_decodeBinary, /* Int64 */
10941 (decodeBinarySignature)UInt64_decodeBinary,
10942 (decodeBinarySignature)Float_decodeBinary,
10943 (decodeBinarySignature)Double_decodeBinary,
10944 (decodeBinarySignature)String_decodeBinary,
10945 (decodeBinarySignature)UInt64_decodeBinary, /* DateTime */
10946 (decodeBinarySignature)Guid_decodeBinary,
10947 (decodeBinarySignature)String_decodeBinary, /* ByteString */
10948 (decodeBinarySignature)String_decodeBinary, /* XmlElement */
10949 (decodeBinarySignature)NodeId_decodeBinary,
10950 (decodeBinarySignature)ExpandedNodeId_decodeBinary,
10951 (decodeBinarySignature)UInt32_decodeBinary, /* StatusCode */
10952 (decodeBinarySignature)QualifiedName_decodeBinary,
10953 (decodeBinarySignature)LocalizedText_decodeBinary,
10954 (decodeBinarySignature)ExtensionObject_decodeBinary,
10955 (decodeBinarySignature)DataValue_decodeBinary,
10956 (decodeBinarySignature)Variant_decodeBinary,
10957 (decodeBinarySignature)DiagnosticInfo_decodeBinary,
10958 (decodeBinarySignature)decodeBinaryNotImplemented, /* Decimal */
10959 (decodeBinarySignature)UInt32_decodeBinary, /* Enumeration */
10960 (decodeBinarySignature)decodeBinaryStructure,
10961 (decodeBinarySignature)decodeBinaryStructureWithOptFields, /* Structure with optional fields */
10962 (decodeBinarySignature)decodeBinaryUnion, /* Union */
10963 (decodeBinarySignature)decodeBinaryNotImplemented /* BitfieldCluster */
10964};
10965
10966status
10967UA_decodeBinaryInternal(const UA_ByteString *src, size_t *offset,
10968 void *dst, const UA_DataType *type,
10969 const UA_DataTypeArray *customTypes) {
10970 /* Set up the context */
10971 Ctx ctx;
10972 ctx.pos = &src->data[*offset];
10973 ctx.end = &src->data[src->length];
10974 ctx.depth = 0;
10975 ctx.customTypes = customTypes;
10976
10977 /* Decode */
10978 memset(s: dst, c: 0, n: type->memSize); /* Initialize the value */
10979 status ret = decodeBinaryJumpTable[type->typeKind](dst, type, &ctx);
10980
10981 if(UA_LIKELY(ret == UA_STATUSCODE_GOOD)) {
10982 /* Set the new offset */
10983 *offset = (size_t)(ctx.pos - src->data) / sizeof(u8);
10984 } else {
10985 /* Clean up */
10986 UA_clear(p: dst, type);
10987 memset(s: dst, c: 0, n: type->memSize);
10988 }
10989 return ret;
10990}
10991
10992UA_StatusCode
10993UA_decodeBinary(const UA_ByteString *inBuf,
10994 void *p, const UA_DataType *type,
10995 const UA_DecodeBinaryOptions *options) {
10996 size_t offset = 0;
10997 const UA_DataTypeArray *customTypes = options ? options->customTypes : NULL;
10998 return UA_decodeBinaryInternal(src: inBuf, offset: &offset, dst: p, type, customTypes);
10999}
11000
11001/**
11002 * Compute the Message Size
11003 * ------------------------
11004 * The following methods are used to compute the length of a datum in binary
11005 * encoding. */
11006
11007static size_t
11008Array_calcSizeBinary(const void *src, size_t length, const UA_DataType *type) {
11009 size_t s = 4; /* length */
11010 if(type->overlayable) {
11011 s += type->memSize * length;
11012 return s;
11013 }
11014 uintptr_t ptr = (uintptr_t)src;
11015 for(size_t i = 0; i < length; ++i) {
11016 s += calcSizeBinaryJumpTable[type->typeKind]((const void*)ptr, type);
11017 ptr += type->memSize;
11018 }
11019 return s;
11020}
11021
11022static size_t calcSizeBinary1(const void *_, const UA_DataType *__) { (void)_, (void)__; return 1; }
11023static size_t calcSizeBinary2(const void *_, const UA_DataType *__) { (void)_, (void)__; return 2; }
11024static size_t calcSizeBinary4(const void *_, const UA_DataType *__) { (void)_, (void)__; return 4; }
11025static size_t calcSizeBinary8(const void *_, const UA_DataType *__) { (void)_, (void)__; return 8; }
11026
11027CALCSIZE_BINARY(String) { return 4 + src->length; }
11028
11029CALCSIZE_BINARY(Guid) { return 16; }
11030
11031CALCSIZE_BINARY(NodeId) {
11032 size_t s = 1; /* Encoding byte */
11033 switch(src->identifierType) {
11034 case UA_NODEIDTYPE_NUMERIC:
11035 if(src->identifier.numeric > UA_UINT16_MAX || src->namespaceIndex > UA_BYTE_MAX) {
11036 s += 6;
11037 } else if(src->identifier.numeric > UA_BYTE_MAX || src->namespaceIndex > 0) {
11038 s += 3;
11039 } else {
11040 s += 1;
11041 }
11042 break;
11043 case UA_NODEIDTYPE_BYTESTRING:
11044 case UA_NODEIDTYPE_STRING:
11045 s += 2;
11046 s += String_calcSizeBinary(src: &src->identifier.string, NULL);
11047 break;
11048 case UA_NODEIDTYPE_GUID:
11049 s += 18;
11050 break;
11051 default:
11052 return 0;
11053 }
11054 return s;
11055}
11056
11057CALCSIZE_BINARY(ExpandedNodeId) {
11058 size_t s = NodeId_calcSizeBinary(src: &src->nodeId, NULL);
11059 if(src->namespaceUri.length > 0)
11060 s += String_calcSizeBinary(src: &src->namespaceUri, NULL);
11061 if(src->serverIndex > 0)
11062 s += 4;
11063 return s;
11064}
11065
11066CALCSIZE_BINARY(QualifiedName) {
11067 return 2 + String_calcSizeBinary(src: &src->name, NULL);
11068}
11069
11070CALCSIZE_BINARY(LocalizedText) {
11071 size_t s = 1; /* Encoding byte */
11072 if(src->locale.data)
11073 s += String_calcSizeBinary(src: &src->locale, NULL);
11074 if(src->text.data)
11075 s += String_calcSizeBinary(src: &src->text, NULL);
11076 return s;
11077}
11078
11079CALCSIZE_BINARY(ExtensionObject) {
11080 size_t s = 1; /* Encoding byte */
11081
11082 /* Encoded content */
11083 if(src->encoding <= UA_EXTENSIONOBJECT_ENCODED_XML) {
11084 s += NodeId_calcSizeBinary(src: &src->content.encoded.typeId, NULL);
11085 switch(src->encoding) {
11086 case UA_EXTENSIONOBJECT_ENCODED_NOBODY:
11087 break;
11088 case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
11089 case UA_EXTENSIONOBJECT_ENCODED_XML:
11090 s += String_calcSizeBinary(src: &src->content.encoded.body, NULL);
11091 break;
11092 default:
11093 return 0;
11094 }
11095 return s;
11096 }
11097
11098 /* Decoded content */
11099 if(!src->content.decoded.type || !src->content.decoded.data)
11100 return 0;
11101 if(src->content.decoded.type->typeId.identifierType != UA_NODEIDTYPE_NUMERIC)
11102 return 0;
11103
11104 s += NodeId_calcSizeBinary(src: &src->content.decoded.type->binaryEncodingId, NULL); /* Type encoding length */
11105 s += 4; /* Encoding length field */
11106 const UA_DataType *type = src->content.decoded.type;
11107 s += calcSizeBinaryJumpTable[type->typeKind](src->content.decoded.data, type); /* Encoding length */
11108 return s;
11109}
11110
11111CALCSIZE_BINARY(Variant) {
11112 size_t s = 1; /* Encoding byte */
11113 if(!src->type)
11114 return s;
11115
11116 const UA_Boolean isArray = src->arrayLength > 0 || src->data <= UA_EMPTY_ARRAY_SENTINEL;
11117 if(isArray)
11118 s += Array_calcSizeBinary(src: src->data, length: src->arrayLength, type: src->type);
11119 else
11120 s += calcSizeBinaryJumpTable[src->type->typeKind](src->data, src->type);
11121
11122 const UA_Boolean isBuiltin = (src->type->typeKind <= UA_DATATYPEKIND_DIAGNOSTICINFO);
11123 const UA_Boolean isEnum = (src->type->typeKind == UA_DATATYPEKIND_ENUM);
11124 if(!isBuiltin && !isEnum) {
11125 /* The type is wrapped inside an extensionobject */
11126 /* (NodeId + encoding byte + extension object length) * array length */
11127 size_t length = isArray ? src->arrayLength : 1;
11128 s += (NodeId_calcSizeBinary(src: &src->type->binaryEncodingId, NULL) + 1 + 4) * length;
11129 }
11130
11131 const UA_Boolean hasDimensions = isArray && src->arrayDimensionsSize > 0;
11132 if(hasDimensions)
11133 s += Array_calcSizeBinary(src: src->arrayDimensions, length: src->arrayDimensionsSize,
11134 type: &UA_TYPES[UA_TYPES_INT32]);
11135 return s;
11136}
11137
11138CALCSIZE_BINARY(DataValue) {
11139 size_t s = 1; /* Encoding byte */
11140 if(src->hasValue)
11141 s += Variant_calcSizeBinary(src: &src->value, NULL);
11142 if(src->hasStatus)
11143 s += 4;
11144 if(src->hasSourceTimestamp)
11145 s += 8;
11146 if(src->hasSourcePicoseconds)
11147 s += 2;
11148 if(src->hasServerTimestamp)
11149 s += 8;
11150 if(src->hasServerPicoseconds)
11151 s += 2;
11152 return s;
11153}
11154
11155CALCSIZE_BINARY(DiagnosticInfo) {
11156 size_t s = 1; /* Encoding byte */
11157 if(src->hasSymbolicId)
11158 s += 4;
11159 if(src->hasNamespaceUri)
11160 s += 4;
11161 if(src->hasLocalizedText)
11162 s += 4;
11163 if(src->hasLocale)
11164 s += 4;
11165 if(src->hasAdditionalInfo)
11166 s += String_calcSizeBinary(src: &src->additionalInfo, NULL);
11167 if(src->hasInnerStatusCode)
11168 s += 4;
11169 if(src->hasInnerDiagnosticInfo)
11170 s += DiagnosticInfo_calcSizeBinary(src: src->innerDiagnosticInfo, NULL);
11171 return s;
11172}
11173
11174static size_t
11175calcSizeBinaryStructure(const void *p, const UA_DataType *type) {
11176 size_t s = 0;
11177 uintptr_t ptr = (uintptr_t)p;
11178 u8 membersSize = type->membersSize;
11179
11180 /* Loop over members */
11181 for(size_t i = 0; i < membersSize; ++i) {
11182 const UA_DataTypeMember *member = &type->members[i];
11183 const UA_DataType *membertype = member->memberType;
11184 ptr += member->padding;
11185
11186 /* Array */
11187 if(member->isArray) {
11188 const size_t length = *((const size_t*)ptr);
11189 ptr += sizeof(size_t);
11190 s += Array_calcSizeBinary(src: *(void *UA_RESTRICT const *)ptr, length, type: membertype);
11191 ptr += sizeof(void*);
11192 continue;
11193 }
11194
11195 /* Scalar */
11196 s += calcSizeBinaryJumpTable[membertype->typeKind]((const void*)ptr, membertype);
11197 ptr += membertype->memSize;
11198 }
11199
11200 return s;
11201}
11202
11203static size_t
11204calcSizeBinaryStructureWithOptFields(const void *p, const UA_DataType *type) {
11205 /* Start with the size of the encoding mask */
11206 size_t s = sizeof(UA_UInt32);
11207
11208 /* Loop over members */
11209 uintptr_t ptr = (uintptr_t)p;
11210 for(size_t i = 0; i < type->membersSize; ++i) {
11211 const UA_DataTypeMember *member = &type->members[i];
11212 const UA_DataType *membertype = member->memberType;
11213 ptr += member->padding;
11214 if(member->isOptional) {
11215 if((member->isArray && ((*(void* const*)(ptr+sizeof(size_t))) == NULL)) ||
11216 (!member->isArray && (*(void* const*)ptr == NULL))) {
11217 /* Optional member not contained */
11218 if(member->isArray)
11219 ptr += sizeof(size_t);
11220 ptr += sizeof(void *);
11221 continue;
11222 }
11223 /* Fallthrough to take the size into account */
11224 }
11225 /* Array */
11226 if(member->isArray) {
11227 const size_t length = *((const size_t*)ptr);
11228 ptr += sizeof(size_t);
11229 s += Array_calcSizeBinary(src: *(void *UA_RESTRICT const *)ptr, length, type: membertype);
11230 ptr += sizeof(void*);
11231 continue;
11232 }
11233 /* Scalar */
11234 if (member->isOptional) {
11235 s += calcSizeBinaryJumpTable[membertype->typeKind](*(void* const*)ptr, membertype);
11236 ptr += sizeof(void *);
11237 } else {
11238 s += calcSizeBinaryJumpTable[membertype->typeKind]((const void*)ptr, membertype);
11239 ptr += membertype->memSize;
11240 }
11241 }
11242 return s;
11243}
11244
11245static size_t
11246calcSizeBinaryUnion(const void *p, const UA_DataType *type) {
11247 size_t s = 4; /* UA_TYPES[UA_TYPES_UINT32].memSize; */
11248 const UA_UInt32 selection = *(const UA_UInt32 *)p;
11249 if(selection == 0)
11250 return s;
11251
11252 const UA_DataTypeMember *m = &type->members[selection-1];
11253 const UA_DataType *mt = m->memberType;
11254
11255 uintptr_t ptr = ((uintptr_t)p) + m->padding; /* includes switchfield length */
11256 if(!m->isArray) {
11257 s += UA_calcSizeBinary(p: (const void*)ptr, type: mt);
11258 } else {
11259 const size_t length = *((const size_t*)ptr);
11260 ptr += sizeof(size_t);
11261 s += Array_calcSizeBinary(src: *(void *UA_RESTRICT const *)ptr, length, type: mt);
11262 }
11263 return s;
11264}
11265
11266static size_t
11267calcSizeBinaryNotImplemented(const void *p, const UA_DataType *type) {
11268 (void)p, (void)type;
11269 return 0;
11270}
11271
11272const calcSizeBinarySignature calcSizeBinaryJumpTable[UA_DATATYPEKINDS] = {
11273 (calcSizeBinarySignature)calcSizeBinary1, /* Boolean */
11274 (calcSizeBinarySignature)calcSizeBinary1, /* SByte */
11275 (calcSizeBinarySignature)calcSizeBinary1, /* Byte */
11276 (calcSizeBinarySignature)calcSizeBinary2, /* Int16 */
11277 (calcSizeBinarySignature)calcSizeBinary2, /* UInt16 */
11278 (calcSizeBinarySignature)calcSizeBinary4, /* Int32 */
11279 (calcSizeBinarySignature)calcSizeBinary4, /* UInt32 */
11280 (calcSizeBinarySignature)calcSizeBinary8, /* Int64 */
11281 (calcSizeBinarySignature)calcSizeBinary8, /* UInt64 */
11282 (calcSizeBinarySignature)calcSizeBinary4, /* Float */
11283 (calcSizeBinarySignature)calcSizeBinary8, /* Double */
11284 (calcSizeBinarySignature)String_calcSizeBinary,
11285 (calcSizeBinarySignature)calcSizeBinary8, /* DateTime */
11286 (calcSizeBinarySignature)Guid_calcSizeBinary,
11287 (calcSizeBinarySignature)String_calcSizeBinary, /* ByteString */
11288 (calcSizeBinarySignature)String_calcSizeBinary, /* XmlElement */
11289 (calcSizeBinarySignature)NodeId_calcSizeBinary,
11290 (calcSizeBinarySignature)ExpandedNodeId_calcSizeBinary,
11291 (calcSizeBinarySignature)calcSizeBinary4, /* StatusCode */
11292 (calcSizeBinarySignature)QualifiedName_calcSizeBinary,
11293 (calcSizeBinarySignature)LocalizedText_calcSizeBinary,
11294 (calcSizeBinarySignature)ExtensionObject_calcSizeBinary,
11295 (calcSizeBinarySignature)DataValue_calcSizeBinary,
11296 (calcSizeBinarySignature)Variant_calcSizeBinary,
11297 (calcSizeBinarySignature)DiagnosticInfo_calcSizeBinary,
11298 (calcSizeBinarySignature)calcSizeBinaryNotImplemented, /* Decimal */
11299 (calcSizeBinarySignature)calcSizeBinary4, /* Enumeration */
11300 (calcSizeBinarySignature)calcSizeBinaryStructure,
11301 (calcSizeBinarySignature)calcSizeBinaryStructureWithOptFields, /* Structure with Optional Fields */
11302 (calcSizeBinarySignature)calcSizeBinaryUnion, /* Union */
11303 (calcSizeBinarySignature)calcSizeBinaryNotImplemented /* BitfieldCluster */
11304};
11305
11306size_t
11307UA_calcSizeBinary(const void *p, const UA_DataType *type) {
11308 return calcSizeBinaryJumpTable[type->typeKind](p, type);
11309}
11310
11311/**** amalgamated original file "/build/src_generated/open62541/types_generated.c" ****/
11312
11313/**********************************
11314 * Autogenerated -- do not modify *
11315 **********************************/
11316
11317
11318/* Boolean */
11319#define Boolean_members NULL
11320
11321/* SByte */
11322#define SByte_members NULL
11323
11324/* Byte */
11325#define Byte_members NULL
11326
11327/* Int16 */
11328#define Int16_members NULL
11329
11330/* UInt16 */
11331#define UInt16_members NULL
11332
11333/* Int32 */
11334#define Int32_members NULL
11335
11336/* UInt32 */
11337#define UInt32_members NULL
11338
11339/* Int64 */
11340#define Int64_members NULL
11341
11342/* UInt64 */
11343#define UInt64_members NULL
11344
11345/* Float */
11346#define Float_members NULL
11347
11348/* Double */
11349#define Double_members NULL
11350
11351/* String */
11352#define String_members NULL
11353
11354/* DateTime */
11355#define DateTime_members NULL
11356
11357/* Guid */
11358#define Guid_members NULL
11359
11360/* ByteString */
11361#define ByteString_members NULL
11362
11363/* XmlElement */
11364#define XmlElement_members NULL
11365
11366/* NodeId */
11367#define NodeId_members NULL
11368
11369/* ExpandedNodeId */
11370#define ExpandedNodeId_members NULL
11371
11372/* StatusCode */
11373#define StatusCode_members NULL
11374
11375/* QualifiedName */
11376#define QualifiedName_members NULL
11377
11378/* LocalizedText */
11379#define LocalizedText_members NULL
11380
11381/* ExtensionObject */
11382#define ExtensionObject_members NULL
11383
11384/* DataValue */
11385#define DataValue_members NULL
11386
11387/* Variant */
11388#define Variant_members NULL
11389
11390/* DiagnosticInfo */
11391#define DiagnosticInfo_members NULL
11392
11393/* NamingRuleType */
11394#define NamingRuleType_members NULL
11395
11396/* Enumeration */
11397#define Enumeration_members NULL
11398
11399/* ImageBMP */
11400#define ImageBMP_members NULL
11401
11402/* ImageGIF */
11403#define ImageGIF_members NULL
11404
11405/* ImageJPG */
11406#define ImageJPG_members NULL
11407
11408/* ImagePNG */
11409#define ImagePNG_members NULL
11410
11411/* AudioDataType */
11412#define AudioDataType_members NULL
11413
11414/* UriString */
11415#define UriString_members NULL
11416
11417/* BitFieldMaskDataType */
11418#define BitFieldMaskDataType_members NULL
11419
11420/* SemanticVersionString */
11421#define SemanticVersionString_members NULL
11422
11423/* KeyValuePair */
11424static UA_DataTypeMember KeyValuePair_members[2] = {
11425{
11426 UA_TYPENAME("Key") /* .memberName */
11427 &UA_TYPES[UA_TYPES_QUALIFIEDNAME], /* .memberType */
11428 0, /* .padding */
11429 false, /* .isArray */
11430 false /* .isOptional */
11431},
11432{
11433 UA_TYPENAME("Value") /* .memberName */
11434 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
11435 offsetof(UA_KeyValuePair, value) - offsetof(UA_KeyValuePair, key) - sizeof(UA_QualifiedName), /* .padding */
11436 false, /* .isArray */
11437 false /* .isOptional */
11438},};
11439
11440/* AdditionalParametersType */
11441static UA_DataTypeMember AdditionalParametersType_members[1] = {
11442{
11443 UA_TYPENAME("Parameters") /* .memberName */
11444 &UA_TYPES[UA_TYPES_KEYVALUEPAIR], /* .memberType */
11445 0, /* .padding */
11446 true, /* .isArray */
11447 false /* .isOptional */
11448},};
11449
11450/* EphemeralKeyType */
11451static UA_DataTypeMember EphemeralKeyType_members[2] = {
11452{
11453 UA_TYPENAME("PublicKey") /* .memberName */
11454 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
11455 0, /* .padding */
11456 false, /* .isArray */
11457 false /* .isOptional */
11458},
11459{
11460 UA_TYPENAME("Signature") /* .memberName */
11461 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
11462 offsetof(UA_EphemeralKeyType, signature) - offsetof(UA_EphemeralKeyType, publicKey) - sizeof(UA_ByteString), /* .padding */
11463 false, /* .isArray */
11464 false /* .isOptional */
11465},};
11466
11467/* RationalNumber */
11468static UA_DataTypeMember RationalNumber_members[2] = {
11469{
11470 UA_TYPENAME("Numerator") /* .memberName */
11471 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
11472 0, /* .padding */
11473 false, /* .isArray */
11474 false /* .isOptional */
11475},
11476{
11477 UA_TYPENAME("Denominator") /* .memberName */
11478 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
11479 offsetof(UA_RationalNumber, denominator) - offsetof(UA_RationalNumber, numerator) - sizeof(UA_Int32), /* .padding */
11480 false, /* .isArray */
11481 false /* .isOptional */
11482},};
11483
11484/* ThreeDVector */
11485static UA_DataTypeMember ThreeDVector_members[3] = {
11486{
11487 UA_TYPENAME("X") /* .memberName */
11488 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
11489 0, /* .padding */
11490 false, /* .isArray */
11491 false /* .isOptional */
11492},
11493{
11494 UA_TYPENAME("Y") /* .memberName */
11495 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
11496 offsetof(UA_ThreeDVector, y) - offsetof(UA_ThreeDVector, x) - sizeof(UA_Double), /* .padding */
11497 false, /* .isArray */
11498 false /* .isOptional */
11499},
11500{
11501 UA_TYPENAME("Z") /* .memberName */
11502 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
11503 offsetof(UA_ThreeDVector, z) - offsetof(UA_ThreeDVector, y) - sizeof(UA_Double), /* .padding */
11504 false, /* .isArray */
11505 false /* .isOptional */
11506},};
11507
11508/* ThreeDCartesianCoordinates */
11509static UA_DataTypeMember ThreeDCartesianCoordinates_members[3] = {
11510{
11511 UA_TYPENAME("X") /* .memberName */
11512 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
11513 0, /* .padding */
11514 false, /* .isArray */
11515 false /* .isOptional */
11516},
11517{
11518 UA_TYPENAME("Y") /* .memberName */
11519 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
11520 offsetof(UA_ThreeDCartesianCoordinates, y) - offsetof(UA_ThreeDCartesianCoordinates, x) - sizeof(UA_Double), /* .padding */
11521 false, /* .isArray */
11522 false /* .isOptional */
11523},
11524{
11525 UA_TYPENAME("Z") /* .memberName */
11526 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
11527 offsetof(UA_ThreeDCartesianCoordinates, z) - offsetof(UA_ThreeDCartesianCoordinates, y) - sizeof(UA_Double), /* .padding */
11528 false, /* .isArray */
11529 false /* .isOptional */
11530},};
11531
11532/* ThreeDOrientation */
11533static UA_DataTypeMember ThreeDOrientation_members[3] = {
11534{
11535 UA_TYPENAME("A") /* .memberName */
11536 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
11537 0, /* .padding */
11538 false, /* .isArray */
11539 false /* .isOptional */
11540},
11541{
11542 UA_TYPENAME("B") /* .memberName */
11543 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
11544 offsetof(UA_ThreeDOrientation, b) - offsetof(UA_ThreeDOrientation, a) - sizeof(UA_Double), /* .padding */
11545 false, /* .isArray */
11546 false /* .isOptional */
11547},
11548{
11549 UA_TYPENAME("C") /* .memberName */
11550 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
11551 offsetof(UA_ThreeDOrientation, c) - offsetof(UA_ThreeDOrientation, b) - sizeof(UA_Double), /* .padding */
11552 false, /* .isArray */
11553 false /* .isOptional */
11554},};
11555
11556/* ThreeDFrame */
11557static UA_DataTypeMember ThreeDFrame_members[2] = {
11558{
11559 UA_TYPENAME("CartesianCoordinates") /* .memberName */
11560 &UA_TYPES[UA_TYPES_THREEDCARTESIANCOORDINATES], /* .memberType */
11561 0, /* .padding */
11562 false, /* .isArray */
11563 false /* .isOptional */
11564},
11565{
11566 UA_TYPENAME("Orientation") /* .memberName */
11567 &UA_TYPES[UA_TYPES_THREEDORIENTATION], /* .memberType */
11568 offsetof(UA_ThreeDFrame, orientation) - offsetof(UA_ThreeDFrame, cartesianCoordinates) - sizeof(UA_ThreeDCartesianCoordinates), /* .padding */
11569 false, /* .isArray */
11570 false /* .isOptional */
11571},};
11572
11573/* OpenFileMode */
11574#define OpenFileMode_members NULL
11575
11576/* IdentityCriteriaType */
11577#define IdentityCriteriaType_members NULL
11578
11579/* IdentityMappingRuleType */
11580static UA_DataTypeMember IdentityMappingRuleType_members[2] = {
11581{
11582 UA_TYPENAME("CriteriaType") /* .memberName */
11583 &UA_TYPES[UA_TYPES_IDENTITYCRITERIATYPE], /* .memberType */
11584 0, /* .padding */
11585 false, /* .isArray */
11586 false /* .isOptional */
11587},
11588{
11589 UA_TYPENAME("Criteria") /* .memberName */
11590 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
11591 offsetof(UA_IdentityMappingRuleType, criteria) - offsetof(UA_IdentityMappingRuleType, criteriaType) - sizeof(UA_IdentityCriteriaType), /* .padding */
11592 false, /* .isArray */
11593 false /* .isOptional */
11594},};
11595
11596/* CurrencyUnitType */
11597static UA_DataTypeMember CurrencyUnitType_members[4] = {
11598{
11599 UA_TYPENAME("NumericCode") /* .memberName */
11600 &UA_TYPES[UA_TYPES_INT16], /* .memberType */
11601 0, /* .padding */
11602 false, /* .isArray */
11603 false /* .isOptional */
11604},
11605{
11606 UA_TYPENAME("Exponent") /* .memberName */
11607 &UA_TYPES[UA_TYPES_SBYTE], /* .memberType */
11608 offsetof(UA_CurrencyUnitType, exponent) - offsetof(UA_CurrencyUnitType, numericCode) - sizeof(UA_Int16), /* .padding */
11609 false, /* .isArray */
11610 false /* .isOptional */
11611},
11612{
11613 UA_TYPENAME("AlphabeticCode") /* .memberName */
11614 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
11615 offsetof(UA_CurrencyUnitType, alphabeticCode) - offsetof(UA_CurrencyUnitType, exponent) - sizeof(UA_SByte), /* .padding */
11616 false, /* .isArray */
11617 false /* .isOptional */
11618},
11619{
11620 UA_TYPENAME("Currency") /* .memberName */
11621 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
11622 offsetof(UA_CurrencyUnitType, currency) - offsetof(UA_CurrencyUnitType, alphabeticCode) - sizeof(UA_String), /* .padding */
11623 false, /* .isArray */
11624 false /* .isOptional */
11625},};
11626
11627/* TrustListMasks */
11628#define TrustListMasks_members NULL
11629
11630/* TrustListDataType */
11631static UA_DataTypeMember TrustListDataType_members[5] = {
11632{
11633 UA_TYPENAME("SpecifiedLists") /* .memberName */
11634 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
11635 0, /* .padding */
11636 false, /* .isArray */
11637 false /* .isOptional */
11638},
11639{
11640 UA_TYPENAME("TrustedCertificates") /* .memberName */
11641 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
11642 offsetof(UA_TrustListDataType, trustedCertificatesSize) - offsetof(UA_TrustListDataType, specifiedLists) - sizeof(UA_UInt32), /* .padding */
11643 true, /* .isArray */
11644 false /* .isOptional */
11645},
11646{
11647 UA_TYPENAME("TrustedCrls") /* .memberName */
11648 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
11649 offsetof(UA_TrustListDataType, trustedCrlsSize) - offsetof(UA_TrustListDataType, trustedCertificates) - sizeof(void *), /* .padding */
11650 true, /* .isArray */
11651 false /* .isOptional */
11652},
11653{
11654 UA_TYPENAME("IssuerCertificates") /* .memberName */
11655 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
11656 offsetof(UA_TrustListDataType, issuerCertificatesSize) - offsetof(UA_TrustListDataType, trustedCrls) - sizeof(void *), /* .padding */
11657 true, /* .isArray */
11658 false /* .isOptional */
11659},
11660{
11661 UA_TYPENAME("IssuerCrls") /* .memberName */
11662 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
11663 offsetof(UA_TrustListDataType, issuerCrlsSize) - offsetof(UA_TrustListDataType, issuerCertificates) - sizeof(void *), /* .padding */
11664 true, /* .isArray */
11665 false /* .isOptional */
11666},};
11667
11668/* DecimalDataType */
11669static UA_DataTypeMember DecimalDataType_members[2] = {
11670{
11671 UA_TYPENAME("Scale") /* .memberName */
11672 &UA_TYPES[UA_TYPES_INT16], /* .memberType */
11673 0, /* .padding */
11674 false, /* .isArray */
11675 false /* .isOptional */
11676},
11677{
11678 UA_TYPENAME("Value") /* .memberName */
11679 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
11680 offsetof(UA_DecimalDataType, value) - offsetof(UA_DecimalDataType, scale) - sizeof(UA_Int16), /* .padding */
11681 false, /* .isArray */
11682 false /* .isOptional */
11683},};
11684
11685/* DataTypeDescription */
11686static UA_DataTypeMember DataTypeDescription_members[2] = {
11687{
11688 UA_TYPENAME("DataTypeId") /* .memberName */
11689 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
11690 0, /* .padding */
11691 false, /* .isArray */
11692 false /* .isOptional */
11693},
11694{
11695 UA_TYPENAME("Name") /* .memberName */
11696 &UA_TYPES[UA_TYPES_QUALIFIEDNAME], /* .memberType */
11697 offsetof(UA_DataTypeDescription, name) - offsetof(UA_DataTypeDescription, dataTypeId) - sizeof(UA_NodeId), /* .padding */
11698 false, /* .isArray */
11699 false /* .isOptional */
11700},};
11701
11702/* SimpleTypeDescription */
11703static UA_DataTypeMember SimpleTypeDescription_members[4] = {
11704{
11705 UA_TYPENAME("DataTypeId") /* .memberName */
11706 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
11707 0, /* .padding */
11708 false, /* .isArray */
11709 false /* .isOptional */
11710},
11711{
11712 UA_TYPENAME("Name") /* .memberName */
11713 &UA_TYPES[UA_TYPES_QUALIFIEDNAME], /* .memberType */
11714 offsetof(UA_SimpleTypeDescription, name) - offsetof(UA_SimpleTypeDescription, dataTypeId) - sizeof(UA_NodeId), /* .padding */
11715 false, /* .isArray */
11716 false /* .isOptional */
11717},
11718{
11719 UA_TYPENAME("BaseDataType") /* .memberName */
11720 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
11721 offsetof(UA_SimpleTypeDescription, baseDataType) - offsetof(UA_SimpleTypeDescription, name) - sizeof(UA_QualifiedName), /* .padding */
11722 false, /* .isArray */
11723 false /* .isOptional */
11724},
11725{
11726 UA_TYPENAME("BuiltInType") /* .memberName */
11727 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
11728 offsetof(UA_SimpleTypeDescription, builtInType) - offsetof(UA_SimpleTypeDescription, baseDataType) - sizeof(UA_NodeId), /* .padding */
11729 false, /* .isArray */
11730 false /* .isOptional */
11731},};
11732
11733/* PortableQualifiedName */
11734static UA_DataTypeMember PortableQualifiedName_members[2] = {
11735{
11736 UA_TYPENAME("NamespaceUri") /* .memberName */
11737 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
11738 0, /* .padding */
11739 false, /* .isArray */
11740 false /* .isOptional */
11741},
11742{
11743 UA_TYPENAME("Name") /* .memberName */
11744 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
11745 offsetof(UA_PortableQualifiedName, name) - offsetof(UA_PortableQualifiedName, namespaceUri) - sizeof(UA_String), /* .padding */
11746 false, /* .isArray */
11747 false /* .isOptional */
11748},};
11749
11750/* PortableNodeId */
11751static UA_DataTypeMember PortableNodeId_members[2] = {
11752{
11753 UA_TYPENAME("NamespaceUri") /* .memberName */
11754 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
11755 0, /* .padding */
11756 false, /* .isArray */
11757 false /* .isOptional */
11758},
11759{
11760 UA_TYPENAME("Identifier") /* .memberName */
11761 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
11762 offsetof(UA_PortableNodeId, identifier) - offsetof(UA_PortableNodeId, namespaceUri) - sizeof(UA_String), /* .padding */
11763 false, /* .isArray */
11764 false /* .isOptional */
11765},};
11766
11767/* UnsignedRationalNumber */
11768static UA_DataTypeMember UnsignedRationalNumber_members[2] = {
11769{
11770 UA_TYPENAME("Numerator") /* .memberName */
11771 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
11772 0, /* .padding */
11773 false, /* .isArray */
11774 false /* .isOptional */
11775},
11776{
11777 UA_TYPENAME("Denominator") /* .memberName */
11778 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
11779 offsetof(UA_UnsignedRationalNumber, denominator) - offsetof(UA_UnsignedRationalNumber, numerator) - sizeof(UA_UInt32), /* .padding */
11780 false, /* .isArray */
11781 false /* .isOptional */
11782},};
11783
11784/* PubSubState */
11785#define PubSubState_members NULL
11786
11787/* DataSetFieldFlags */
11788#define DataSetFieldFlags_members NULL
11789
11790/* ConfigurationVersionDataType */
11791static UA_DataTypeMember ConfigurationVersionDataType_members[2] = {
11792{
11793 UA_TYPENAME("MajorVersion") /* .memberName */
11794 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
11795 0, /* .padding */
11796 false, /* .isArray */
11797 false /* .isOptional */
11798},
11799{
11800 UA_TYPENAME("MinorVersion") /* .memberName */
11801 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
11802 offsetof(UA_ConfigurationVersionDataType, minorVersion) - offsetof(UA_ConfigurationVersionDataType, majorVersion) - sizeof(UA_UInt32), /* .padding */
11803 false, /* .isArray */
11804 false /* .isOptional */
11805},};
11806
11807/* PublishedVariableDataType */
11808static UA_DataTypeMember PublishedVariableDataType_members[8] = {
11809{
11810 UA_TYPENAME("PublishedVariable") /* .memberName */
11811 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
11812 0, /* .padding */
11813 false, /* .isArray */
11814 false /* .isOptional */
11815},
11816{
11817 UA_TYPENAME("AttributeId") /* .memberName */
11818 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
11819 offsetof(UA_PublishedVariableDataType, attributeId) - offsetof(UA_PublishedVariableDataType, publishedVariable) - sizeof(UA_NodeId), /* .padding */
11820 false, /* .isArray */
11821 false /* .isOptional */
11822},
11823{
11824 UA_TYPENAME("SamplingIntervalHint") /* .memberName */
11825 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
11826 offsetof(UA_PublishedVariableDataType, samplingIntervalHint) - offsetof(UA_PublishedVariableDataType, attributeId) - sizeof(UA_UInt32), /* .padding */
11827 false, /* .isArray */
11828 false /* .isOptional */
11829},
11830{
11831 UA_TYPENAME("DeadbandType") /* .memberName */
11832 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
11833 offsetof(UA_PublishedVariableDataType, deadbandType) - offsetof(UA_PublishedVariableDataType, samplingIntervalHint) - sizeof(UA_Double), /* .padding */
11834 false, /* .isArray */
11835 false /* .isOptional */
11836},
11837{
11838 UA_TYPENAME("DeadbandValue") /* .memberName */
11839 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
11840 offsetof(UA_PublishedVariableDataType, deadbandValue) - offsetof(UA_PublishedVariableDataType, deadbandType) - sizeof(UA_UInt32), /* .padding */
11841 false, /* .isArray */
11842 false /* .isOptional */
11843},
11844{
11845 UA_TYPENAME("IndexRange") /* .memberName */
11846 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
11847 offsetof(UA_PublishedVariableDataType, indexRange) - offsetof(UA_PublishedVariableDataType, deadbandValue) - sizeof(UA_Double), /* .padding */
11848 false, /* .isArray */
11849 false /* .isOptional */
11850},
11851{
11852 UA_TYPENAME("SubstituteValue") /* .memberName */
11853 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
11854 offsetof(UA_PublishedVariableDataType, substituteValue) - offsetof(UA_PublishedVariableDataType, indexRange) - sizeof(UA_String), /* .padding */
11855 false, /* .isArray */
11856 false /* .isOptional */
11857},
11858{
11859 UA_TYPENAME("MetaDataProperties") /* .memberName */
11860 &UA_TYPES[UA_TYPES_QUALIFIEDNAME], /* .memberType */
11861 offsetof(UA_PublishedVariableDataType, metaDataPropertiesSize) - offsetof(UA_PublishedVariableDataType, substituteValue) - sizeof(UA_Variant), /* .padding */
11862 true, /* .isArray */
11863 false /* .isOptional */
11864},};
11865
11866/* PublishedDataItemsDataType */
11867static UA_DataTypeMember PublishedDataItemsDataType_members[1] = {
11868{
11869 UA_TYPENAME("PublishedData") /* .memberName */
11870 &UA_TYPES[UA_TYPES_PUBLISHEDVARIABLEDATATYPE], /* .memberType */
11871 0, /* .padding */
11872 true, /* .isArray */
11873 false /* .isOptional */
11874},};
11875
11876/* PublishedDataSetCustomSourceDataType */
11877static UA_DataTypeMember PublishedDataSetCustomSourceDataType_members[1] = {
11878{
11879 UA_TYPENAME("CyclicDataSet") /* .memberName */
11880 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
11881 0, /* .padding */
11882 false, /* .isArray */
11883 false /* .isOptional */
11884},};
11885
11886/* DataSetFieldContentMask */
11887#define DataSetFieldContentMask_members NULL
11888
11889/* DataSetWriterDataType */
11890static UA_DataTypeMember DataSetWriterDataType_members[9] = {
11891{
11892 UA_TYPENAME("Name") /* .memberName */
11893 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
11894 0, /* .padding */
11895 false, /* .isArray */
11896 false /* .isOptional */
11897},
11898{
11899 UA_TYPENAME("Enabled") /* .memberName */
11900 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
11901 offsetof(UA_DataSetWriterDataType, enabled) - offsetof(UA_DataSetWriterDataType, name) - sizeof(UA_String), /* .padding */
11902 false, /* .isArray */
11903 false /* .isOptional */
11904},
11905{
11906 UA_TYPENAME("DataSetWriterId") /* .memberName */
11907 &UA_TYPES[UA_TYPES_UINT16], /* .memberType */
11908 offsetof(UA_DataSetWriterDataType, dataSetWriterId) - offsetof(UA_DataSetWriterDataType, enabled) - sizeof(UA_Boolean), /* .padding */
11909 false, /* .isArray */
11910 false /* .isOptional */
11911},
11912{
11913 UA_TYPENAME("DataSetFieldContentMask") /* .memberName */
11914 &UA_TYPES[UA_TYPES_DATASETFIELDCONTENTMASK], /* .memberType */
11915 offsetof(UA_DataSetWriterDataType, dataSetFieldContentMask) - offsetof(UA_DataSetWriterDataType, dataSetWriterId) - sizeof(UA_UInt16), /* .padding */
11916 false, /* .isArray */
11917 false /* .isOptional */
11918},
11919{
11920 UA_TYPENAME("KeyFrameCount") /* .memberName */
11921 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
11922 offsetof(UA_DataSetWriterDataType, keyFrameCount) - offsetof(UA_DataSetWriterDataType, dataSetFieldContentMask) - sizeof(UA_DataSetFieldContentMask), /* .padding */
11923 false, /* .isArray */
11924 false /* .isOptional */
11925},
11926{
11927 UA_TYPENAME("DataSetName") /* .memberName */
11928 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
11929 offsetof(UA_DataSetWriterDataType, dataSetName) - offsetof(UA_DataSetWriterDataType, keyFrameCount) - sizeof(UA_UInt32), /* .padding */
11930 false, /* .isArray */
11931 false /* .isOptional */
11932},
11933{
11934 UA_TYPENAME("DataSetWriterProperties") /* .memberName */
11935 &UA_TYPES[UA_TYPES_KEYVALUEPAIR], /* .memberType */
11936 offsetof(UA_DataSetWriterDataType, dataSetWriterPropertiesSize) - offsetof(UA_DataSetWriterDataType, dataSetName) - sizeof(UA_String), /* .padding */
11937 true, /* .isArray */
11938 false /* .isOptional */
11939},
11940{
11941 UA_TYPENAME("TransportSettings") /* .memberName */
11942 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
11943 offsetof(UA_DataSetWriterDataType, transportSettings) - offsetof(UA_DataSetWriterDataType, dataSetWriterProperties) - sizeof(void *), /* .padding */
11944 false, /* .isArray */
11945 false /* .isOptional */
11946},
11947{
11948 UA_TYPENAME("MessageSettings") /* .memberName */
11949 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
11950 offsetof(UA_DataSetWriterDataType, messageSettings) - offsetof(UA_DataSetWriterDataType, transportSettings) - sizeof(UA_ExtensionObject), /* .padding */
11951 false, /* .isArray */
11952 false /* .isOptional */
11953},};
11954
11955/* NetworkAddressDataType */
11956static UA_DataTypeMember NetworkAddressDataType_members[1] = {
11957{
11958 UA_TYPENAME("NetworkInterface") /* .memberName */
11959 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
11960 0, /* .padding */
11961 false, /* .isArray */
11962 false /* .isOptional */
11963},};
11964
11965/* NetworkAddressUrlDataType */
11966static UA_DataTypeMember NetworkAddressUrlDataType_members[2] = {
11967{
11968 UA_TYPENAME("NetworkInterface") /* .memberName */
11969 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
11970 0, /* .padding */
11971 false, /* .isArray */
11972 false /* .isOptional */
11973},
11974{
11975 UA_TYPENAME("Url") /* .memberName */
11976 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
11977 offsetof(UA_NetworkAddressUrlDataType, url) - offsetof(UA_NetworkAddressUrlDataType, networkInterface) - sizeof(UA_String), /* .padding */
11978 false, /* .isArray */
11979 false /* .isOptional */
11980},};
11981
11982/* OverrideValueHandling */
11983#define OverrideValueHandling_members NULL
11984
11985/* StandaloneSubscribedDataSetRefDataType */
11986static UA_DataTypeMember StandaloneSubscribedDataSetRefDataType_members[1] = {
11987{
11988 UA_TYPENAME("DataSetName") /* .memberName */
11989 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
11990 0, /* .padding */
11991 false, /* .isArray */
11992 false /* .isOptional */
11993},};
11994
11995/* DataSetOrderingType */
11996#define DataSetOrderingType_members NULL
11997
11998/* UadpNetworkMessageContentMask */
11999#define UadpNetworkMessageContentMask_members NULL
12000
12001/* UadpWriterGroupMessageDataType */
12002static UA_DataTypeMember UadpWriterGroupMessageDataType_members[5] = {
12003{
12004 UA_TYPENAME("GroupVersion") /* .memberName */
12005 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
12006 0, /* .padding */
12007 false, /* .isArray */
12008 false /* .isOptional */
12009},
12010{
12011 UA_TYPENAME("DataSetOrdering") /* .memberName */
12012 &UA_TYPES[UA_TYPES_DATASETORDERINGTYPE], /* .memberType */
12013 offsetof(UA_UadpWriterGroupMessageDataType, dataSetOrdering) - offsetof(UA_UadpWriterGroupMessageDataType, groupVersion) - sizeof(UA_UInt32), /* .padding */
12014 false, /* .isArray */
12015 false /* .isOptional */
12016},
12017{
12018 UA_TYPENAME("NetworkMessageContentMask") /* .memberName */
12019 &UA_TYPES[UA_TYPES_UADPNETWORKMESSAGECONTENTMASK], /* .memberType */
12020 offsetof(UA_UadpWriterGroupMessageDataType, networkMessageContentMask) - offsetof(UA_UadpWriterGroupMessageDataType, dataSetOrdering) - sizeof(UA_DataSetOrderingType), /* .padding */
12021 false, /* .isArray */
12022 false /* .isOptional */
12023},
12024{
12025 UA_TYPENAME("SamplingOffset") /* .memberName */
12026 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
12027 offsetof(UA_UadpWriterGroupMessageDataType, samplingOffset) - offsetof(UA_UadpWriterGroupMessageDataType, networkMessageContentMask) - sizeof(UA_UadpNetworkMessageContentMask), /* .padding */
12028 false, /* .isArray */
12029 false /* .isOptional */
12030},
12031{
12032 UA_TYPENAME("PublishingOffset") /* .memberName */
12033 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
12034 offsetof(UA_UadpWriterGroupMessageDataType, publishingOffsetSize) - offsetof(UA_UadpWriterGroupMessageDataType, samplingOffset) - sizeof(UA_Double), /* .padding */
12035 true, /* .isArray */
12036 false /* .isOptional */
12037},};
12038
12039/* UadpDataSetMessageContentMask */
12040#define UadpDataSetMessageContentMask_members NULL
12041
12042/* UadpDataSetWriterMessageDataType */
12043static UA_DataTypeMember UadpDataSetWriterMessageDataType_members[4] = {
12044{
12045 UA_TYPENAME("DataSetMessageContentMask") /* .memberName */
12046 &UA_TYPES[UA_TYPES_UADPDATASETMESSAGECONTENTMASK], /* .memberType */
12047 0, /* .padding */
12048 false, /* .isArray */
12049 false /* .isOptional */
12050},
12051{
12052 UA_TYPENAME("ConfiguredSize") /* .memberName */
12053 &UA_TYPES[UA_TYPES_UINT16], /* .memberType */
12054 offsetof(UA_UadpDataSetWriterMessageDataType, configuredSize) - offsetof(UA_UadpDataSetWriterMessageDataType, dataSetMessageContentMask) - sizeof(UA_UadpDataSetMessageContentMask), /* .padding */
12055 false, /* .isArray */
12056 false /* .isOptional */
12057},
12058{
12059 UA_TYPENAME("NetworkMessageNumber") /* .memberName */
12060 &UA_TYPES[UA_TYPES_UINT16], /* .memberType */
12061 offsetof(UA_UadpDataSetWriterMessageDataType, networkMessageNumber) - offsetof(UA_UadpDataSetWriterMessageDataType, configuredSize) - sizeof(UA_UInt16), /* .padding */
12062 false, /* .isArray */
12063 false /* .isOptional */
12064},
12065{
12066 UA_TYPENAME("DataSetOffset") /* .memberName */
12067 &UA_TYPES[UA_TYPES_UINT16], /* .memberType */
12068 offsetof(UA_UadpDataSetWriterMessageDataType, dataSetOffset) - offsetof(UA_UadpDataSetWriterMessageDataType, networkMessageNumber) - sizeof(UA_UInt16), /* .padding */
12069 false, /* .isArray */
12070 false /* .isOptional */
12071},};
12072
12073/* UadpDataSetReaderMessageDataType */
12074static UA_DataTypeMember UadpDataSetReaderMessageDataType_members[9] = {
12075{
12076 UA_TYPENAME("GroupVersion") /* .memberName */
12077 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
12078 0, /* .padding */
12079 false, /* .isArray */
12080 false /* .isOptional */
12081},
12082{
12083 UA_TYPENAME("NetworkMessageNumber") /* .memberName */
12084 &UA_TYPES[UA_TYPES_UINT16], /* .memberType */
12085 offsetof(UA_UadpDataSetReaderMessageDataType, networkMessageNumber) - offsetof(UA_UadpDataSetReaderMessageDataType, groupVersion) - sizeof(UA_UInt32), /* .padding */
12086 false, /* .isArray */
12087 false /* .isOptional */
12088},
12089{
12090 UA_TYPENAME("DataSetOffset") /* .memberName */
12091 &UA_TYPES[UA_TYPES_UINT16], /* .memberType */
12092 offsetof(UA_UadpDataSetReaderMessageDataType, dataSetOffset) - offsetof(UA_UadpDataSetReaderMessageDataType, networkMessageNumber) - sizeof(UA_UInt16), /* .padding */
12093 false, /* .isArray */
12094 false /* .isOptional */
12095},
12096{
12097 UA_TYPENAME("DataSetClassId") /* .memberName */
12098 &UA_TYPES[UA_TYPES_GUID], /* .memberType */
12099 offsetof(UA_UadpDataSetReaderMessageDataType, dataSetClassId) - offsetof(UA_UadpDataSetReaderMessageDataType, dataSetOffset) - sizeof(UA_UInt16), /* .padding */
12100 false, /* .isArray */
12101 false /* .isOptional */
12102},
12103{
12104 UA_TYPENAME("NetworkMessageContentMask") /* .memberName */
12105 &UA_TYPES[UA_TYPES_UADPNETWORKMESSAGECONTENTMASK], /* .memberType */
12106 offsetof(UA_UadpDataSetReaderMessageDataType, networkMessageContentMask) - offsetof(UA_UadpDataSetReaderMessageDataType, dataSetClassId) - sizeof(UA_Guid), /* .padding */
12107 false, /* .isArray */
12108 false /* .isOptional */
12109},
12110{
12111 UA_TYPENAME("DataSetMessageContentMask") /* .memberName */
12112 &UA_TYPES[UA_TYPES_UADPDATASETMESSAGECONTENTMASK], /* .memberType */
12113 offsetof(UA_UadpDataSetReaderMessageDataType, dataSetMessageContentMask) - offsetof(UA_UadpDataSetReaderMessageDataType, networkMessageContentMask) - sizeof(UA_UadpNetworkMessageContentMask), /* .padding */
12114 false, /* .isArray */
12115 false /* .isOptional */
12116},
12117{
12118 UA_TYPENAME("PublishingInterval") /* .memberName */
12119 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
12120 offsetof(UA_UadpDataSetReaderMessageDataType, publishingInterval) - offsetof(UA_UadpDataSetReaderMessageDataType, dataSetMessageContentMask) - sizeof(UA_UadpDataSetMessageContentMask), /* .padding */
12121 false, /* .isArray */
12122 false /* .isOptional */
12123},
12124{
12125 UA_TYPENAME("ReceiveOffset") /* .memberName */
12126 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
12127 offsetof(UA_UadpDataSetReaderMessageDataType, receiveOffset) - offsetof(UA_UadpDataSetReaderMessageDataType, publishingInterval) - sizeof(UA_Double), /* .padding */
12128 false, /* .isArray */
12129 false /* .isOptional */
12130},
12131{
12132 UA_TYPENAME("ProcessingOffset") /* .memberName */
12133 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
12134 offsetof(UA_UadpDataSetReaderMessageDataType, processingOffset) - offsetof(UA_UadpDataSetReaderMessageDataType, receiveOffset) - sizeof(UA_Double), /* .padding */
12135 false, /* .isArray */
12136 false /* .isOptional */
12137},};
12138
12139/* JsonNetworkMessageContentMask */
12140#define JsonNetworkMessageContentMask_members NULL
12141
12142/* JsonWriterGroupMessageDataType */
12143static UA_DataTypeMember JsonWriterGroupMessageDataType_members[1] = {
12144{
12145 UA_TYPENAME("NetworkMessageContentMask") /* .memberName */
12146 &UA_TYPES[UA_TYPES_JSONNETWORKMESSAGECONTENTMASK], /* .memberType */
12147 0, /* .padding */
12148 false, /* .isArray */
12149 false /* .isOptional */
12150},};
12151
12152/* JsonDataSetMessageContentMask */
12153#define JsonDataSetMessageContentMask_members NULL
12154
12155/* JsonDataSetWriterMessageDataType */
12156static UA_DataTypeMember JsonDataSetWriterMessageDataType_members[1] = {
12157{
12158 UA_TYPENAME("DataSetMessageContentMask") /* .memberName */
12159 &UA_TYPES[UA_TYPES_JSONDATASETMESSAGECONTENTMASK], /* .memberType */
12160 0, /* .padding */
12161 false, /* .isArray */
12162 false /* .isOptional */
12163},};
12164
12165/* JsonDataSetReaderMessageDataType */
12166static UA_DataTypeMember JsonDataSetReaderMessageDataType_members[2] = {
12167{
12168 UA_TYPENAME("NetworkMessageContentMask") /* .memberName */
12169 &UA_TYPES[UA_TYPES_JSONNETWORKMESSAGECONTENTMASK], /* .memberType */
12170 0, /* .padding */
12171 false, /* .isArray */
12172 false /* .isOptional */
12173},
12174{
12175 UA_TYPENAME("DataSetMessageContentMask") /* .memberName */
12176 &UA_TYPES[UA_TYPES_JSONDATASETMESSAGECONTENTMASK], /* .memberType */
12177 offsetof(UA_JsonDataSetReaderMessageDataType, dataSetMessageContentMask) - offsetof(UA_JsonDataSetReaderMessageDataType, networkMessageContentMask) - sizeof(UA_JsonNetworkMessageContentMask), /* .padding */
12178 false, /* .isArray */
12179 false /* .isOptional */
12180},};
12181
12182/* TransmitQosPriorityDataType */
12183static UA_DataTypeMember TransmitQosPriorityDataType_members[1] = {
12184{
12185 UA_TYPENAME("PriorityLabel") /* .memberName */
12186 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12187 0, /* .padding */
12188 false, /* .isArray */
12189 false /* .isOptional */
12190},};
12191
12192/* ReceiveQosPriorityDataType */
12193static UA_DataTypeMember ReceiveQosPriorityDataType_members[1] = {
12194{
12195 UA_TYPENAME("PriorityLabel") /* .memberName */
12196 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12197 0, /* .padding */
12198 false, /* .isArray */
12199 false /* .isOptional */
12200},};
12201
12202/* DatagramConnectionTransportDataType */
12203static UA_DataTypeMember DatagramConnectionTransportDataType_members[1] = {
12204{
12205 UA_TYPENAME("DiscoveryAddress") /* .memberName */
12206 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
12207 0, /* .padding */
12208 false, /* .isArray */
12209 false /* .isOptional */
12210},};
12211
12212/* DatagramConnectionTransport2DataType */
12213static UA_DataTypeMember DatagramConnectionTransport2DataType_members[5] = {
12214{
12215 UA_TYPENAME("DiscoveryAddress") /* .memberName */
12216 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
12217 0, /* .padding */
12218 false, /* .isArray */
12219 false /* .isOptional */
12220},
12221{
12222 UA_TYPENAME("DiscoveryAnnounceRate") /* .memberName */
12223 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
12224 offsetof(UA_DatagramConnectionTransport2DataType, discoveryAnnounceRate) - offsetof(UA_DatagramConnectionTransport2DataType, discoveryAddress) - sizeof(UA_ExtensionObject), /* .padding */
12225 false, /* .isArray */
12226 false /* .isOptional */
12227},
12228{
12229 UA_TYPENAME("DiscoveryMaxMessageSize") /* .memberName */
12230 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
12231 offsetof(UA_DatagramConnectionTransport2DataType, discoveryMaxMessageSize) - offsetof(UA_DatagramConnectionTransport2DataType, discoveryAnnounceRate) - sizeof(UA_UInt32), /* .padding */
12232 false, /* .isArray */
12233 false /* .isOptional */
12234},
12235{
12236 UA_TYPENAME("QosCategory") /* .memberName */
12237 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12238 offsetof(UA_DatagramConnectionTransport2DataType, qosCategory) - offsetof(UA_DatagramConnectionTransport2DataType, discoveryMaxMessageSize) - sizeof(UA_UInt32), /* .padding */
12239 false, /* .isArray */
12240 false /* .isOptional */
12241},
12242{
12243 UA_TYPENAME("DatagramQos") /* .memberName */
12244 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
12245 offsetof(UA_DatagramConnectionTransport2DataType, datagramQosSize) - offsetof(UA_DatagramConnectionTransport2DataType, qosCategory) - sizeof(UA_String), /* .padding */
12246 true, /* .isArray */
12247 false /* .isOptional */
12248},};
12249
12250/* DatagramWriterGroupTransportDataType */
12251static UA_DataTypeMember DatagramWriterGroupTransportDataType_members[2] = {
12252{
12253 UA_TYPENAME("MessageRepeatCount") /* .memberName */
12254 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
12255 0, /* .padding */
12256 false, /* .isArray */
12257 false /* .isOptional */
12258},
12259{
12260 UA_TYPENAME("MessageRepeatDelay") /* .memberName */
12261 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
12262 offsetof(UA_DatagramWriterGroupTransportDataType, messageRepeatDelay) - offsetof(UA_DatagramWriterGroupTransportDataType, messageRepeatCount) - sizeof(UA_Byte), /* .padding */
12263 false, /* .isArray */
12264 false /* .isOptional */
12265},};
12266
12267/* DatagramWriterGroupTransport2DataType */
12268static UA_DataTypeMember DatagramWriterGroupTransport2DataType_members[7] = {
12269{
12270 UA_TYPENAME("MessageRepeatCount") /* .memberName */
12271 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
12272 0, /* .padding */
12273 false, /* .isArray */
12274 false /* .isOptional */
12275},
12276{
12277 UA_TYPENAME("MessageRepeatDelay") /* .memberName */
12278 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
12279 offsetof(UA_DatagramWriterGroupTransport2DataType, messageRepeatDelay) - offsetof(UA_DatagramWriterGroupTransport2DataType, messageRepeatCount) - sizeof(UA_Byte), /* .padding */
12280 false, /* .isArray */
12281 false /* .isOptional */
12282},
12283{
12284 UA_TYPENAME("Address") /* .memberName */
12285 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
12286 offsetof(UA_DatagramWriterGroupTransport2DataType, address) - offsetof(UA_DatagramWriterGroupTransport2DataType, messageRepeatDelay) - sizeof(UA_Double), /* .padding */
12287 false, /* .isArray */
12288 false /* .isOptional */
12289},
12290{
12291 UA_TYPENAME("QosCategory") /* .memberName */
12292 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12293 offsetof(UA_DatagramWriterGroupTransport2DataType, qosCategory) - offsetof(UA_DatagramWriterGroupTransport2DataType, address) - sizeof(UA_ExtensionObject), /* .padding */
12294 false, /* .isArray */
12295 false /* .isOptional */
12296},
12297{
12298 UA_TYPENAME("DatagramQos") /* .memberName */
12299 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
12300 offsetof(UA_DatagramWriterGroupTransport2DataType, datagramQosSize) - offsetof(UA_DatagramWriterGroupTransport2DataType, qosCategory) - sizeof(UA_String), /* .padding */
12301 true, /* .isArray */
12302 false /* .isOptional */
12303},
12304{
12305 UA_TYPENAME("DiscoveryAnnounceRate") /* .memberName */
12306 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
12307 offsetof(UA_DatagramWriterGroupTransport2DataType, discoveryAnnounceRate) - offsetof(UA_DatagramWriterGroupTransport2DataType, datagramQos) - sizeof(void *), /* .padding */
12308 false, /* .isArray */
12309 false /* .isOptional */
12310},
12311{
12312 UA_TYPENAME("Topic") /* .memberName */
12313 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12314 offsetof(UA_DatagramWriterGroupTransport2DataType, topic) - offsetof(UA_DatagramWriterGroupTransport2DataType, discoveryAnnounceRate) - sizeof(UA_UInt32), /* .padding */
12315 false, /* .isArray */
12316 false /* .isOptional */
12317},};
12318
12319/* DatagramDataSetReaderTransportDataType */
12320static UA_DataTypeMember DatagramDataSetReaderTransportDataType_members[4] = {
12321{
12322 UA_TYPENAME("Address") /* .memberName */
12323 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
12324 0, /* .padding */
12325 false, /* .isArray */
12326 false /* .isOptional */
12327},
12328{
12329 UA_TYPENAME("QosCategory") /* .memberName */
12330 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12331 offsetof(UA_DatagramDataSetReaderTransportDataType, qosCategory) - offsetof(UA_DatagramDataSetReaderTransportDataType, address) - sizeof(UA_ExtensionObject), /* .padding */
12332 false, /* .isArray */
12333 false /* .isOptional */
12334},
12335{
12336 UA_TYPENAME("DatagramQos") /* .memberName */
12337 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
12338 offsetof(UA_DatagramDataSetReaderTransportDataType, datagramQosSize) - offsetof(UA_DatagramDataSetReaderTransportDataType, qosCategory) - sizeof(UA_String), /* .padding */
12339 true, /* .isArray */
12340 false /* .isOptional */
12341},
12342{
12343 UA_TYPENAME("Topic") /* .memberName */
12344 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12345 offsetof(UA_DatagramDataSetReaderTransportDataType, topic) - offsetof(UA_DatagramDataSetReaderTransportDataType, datagramQos) - sizeof(void *), /* .padding */
12346 false, /* .isArray */
12347 false /* .isOptional */
12348},};
12349
12350/* BrokerConnectionTransportDataType */
12351static UA_DataTypeMember BrokerConnectionTransportDataType_members[2] = {
12352{
12353 UA_TYPENAME("ResourceUri") /* .memberName */
12354 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12355 0, /* .padding */
12356 false, /* .isArray */
12357 false /* .isOptional */
12358},
12359{
12360 UA_TYPENAME("AuthenticationProfileUri") /* .memberName */
12361 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12362 offsetof(UA_BrokerConnectionTransportDataType, authenticationProfileUri) - offsetof(UA_BrokerConnectionTransportDataType, resourceUri) - sizeof(UA_String), /* .padding */
12363 false, /* .isArray */
12364 false /* .isOptional */
12365},};
12366
12367/* BrokerTransportQualityOfService */
12368#define BrokerTransportQualityOfService_members NULL
12369
12370/* BrokerWriterGroupTransportDataType */
12371static UA_DataTypeMember BrokerWriterGroupTransportDataType_members[4] = {
12372{
12373 UA_TYPENAME("QueueName") /* .memberName */
12374 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12375 0, /* .padding */
12376 false, /* .isArray */
12377 false /* .isOptional */
12378},
12379{
12380 UA_TYPENAME("ResourceUri") /* .memberName */
12381 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12382 offsetof(UA_BrokerWriterGroupTransportDataType, resourceUri) - offsetof(UA_BrokerWriterGroupTransportDataType, queueName) - sizeof(UA_String), /* .padding */
12383 false, /* .isArray */
12384 false /* .isOptional */
12385},
12386{
12387 UA_TYPENAME("AuthenticationProfileUri") /* .memberName */
12388 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12389 offsetof(UA_BrokerWriterGroupTransportDataType, authenticationProfileUri) - offsetof(UA_BrokerWriterGroupTransportDataType, resourceUri) - sizeof(UA_String), /* .padding */
12390 false, /* .isArray */
12391 false /* .isOptional */
12392},
12393{
12394 UA_TYPENAME("RequestedDeliveryGuarantee") /* .memberName */
12395 &UA_TYPES[UA_TYPES_BROKERTRANSPORTQUALITYOFSERVICE], /* .memberType */
12396 offsetof(UA_BrokerWriterGroupTransportDataType, requestedDeliveryGuarantee) - offsetof(UA_BrokerWriterGroupTransportDataType, authenticationProfileUri) - sizeof(UA_String), /* .padding */
12397 false, /* .isArray */
12398 false /* .isOptional */
12399},};
12400
12401/* BrokerDataSetWriterTransportDataType */
12402static UA_DataTypeMember BrokerDataSetWriterTransportDataType_members[6] = {
12403{
12404 UA_TYPENAME("QueueName") /* .memberName */
12405 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12406 0, /* .padding */
12407 false, /* .isArray */
12408 false /* .isOptional */
12409},
12410{
12411 UA_TYPENAME("ResourceUri") /* .memberName */
12412 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12413 offsetof(UA_BrokerDataSetWriterTransportDataType, resourceUri) - offsetof(UA_BrokerDataSetWriterTransportDataType, queueName) - sizeof(UA_String), /* .padding */
12414 false, /* .isArray */
12415 false /* .isOptional */
12416},
12417{
12418 UA_TYPENAME("AuthenticationProfileUri") /* .memberName */
12419 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12420 offsetof(UA_BrokerDataSetWriterTransportDataType, authenticationProfileUri) - offsetof(UA_BrokerDataSetWriterTransportDataType, resourceUri) - sizeof(UA_String), /* .padding */
12421 false, /* .isArray */
12422 false /* .isOptional */
12423},
12424{
12425 UA_TYPENAME("RequestedDeliveryGuarantee") /* .memberName */
12426 &UA_TYPES[UA_TYPES_BROKERTRANSPORTQUALITYOFSERVICE], /* .memberType */
12427 offsetof(UA_BrokerDataSetWriterTransportDataType, requestedDeliveryGuarantee) - offsetof(UA_BrokerDataSetWriterTransportDataType, authenticationProfileUri) - sizeof(UA_String), /* .padding */
12428 false, /* .isArray */
12429 false /* .isOptional */
12430},
12431{
12432 UA_TYPENAME("MetaDataQueueName") /* .memberName */
12433 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12434 offsetof(UA_BrokerDataSetWriterTransportDataType, metaDataQueueName) - offsetof(UA_BrokerDataSetWriterTransportDataType, requestedDeliveryGuarantee) - sizeof(UA_BrokerTransportQualityOfService), /* .padding */
12435 false, /* .isArray */
12436 false /* .isOptional */
12437},
12438{
12439 UA_TYPENAME("MetaDataUpdateTime") /* .memberName */
12440 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
12441 offsetof(UA_BrokerDataSetWriterTransportDataType, metaDataUpdateTime) - offsetof(UA_BrokerDataSetWriterTransportDataType, metaDataQueueName) - sizeof(UA_String), /* .padding */
12442 false, /* .isArray */
12443 false /* .isOptional */
12444},};
12445
12446/* BrokerDataSetReaderTransportDataType */
12447static UA_DataTypeMember BrokerDataSetReaderTransportDataType_members[5] = {
12448{
12449 UA_TYPENAME("QueueName") /* .memberName */
12450 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12451 0, /* .padding */
12452 false, /* .isArray */
12453 false /* .isOptional */
12454},
12455{
12456 UA_TYPENAME("ResourceUri") /* .memberName */
12457 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12458 offsetof(UA_BrokerDataSetReaderTransportDataType, resourceUri) - offsetof(UA_BrokerDataSetReaderTransportDataType, queueName) - sizeof(UA_String), /* .padding */
12459 false, /* .isArray */
12460 false /* .isOptional */
12461},
12462{
12463 UA_TYPENAME("AuthenticationProfileUri") /* .memberName */
12464 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12465 offsetof(UA_BrokerDataSetReaderTransportDataType, authenticationProfileUri) - offsetof(UA_BrokerDataSetReaderTransportDataType, resourceUri) - sizeof(UA_String), /* .padding */
12466 false, /* .isArray */
12467 false /* .isOptional */
12468},
12469{
12470 UA_TYPENAME("RequestedDeliveryGuarantee") /* .memberName */
12471 &UA_TYPES[UA_TYPES_BROKERTRANSPORTQUALITYOFSERVICE], /* .memberType */
12472 offsetof(UA_BrokerDataSetReaderTransportDataType, requestedDeliveryGuarantee) - offsetof(UA_BrokerDataSetReaderTransportDataType, authenticationProfileUri) - sizeof(UA_String), /* .padding */
12473 false, /* .isArray */
12474 false /* .isOptional */
12475},
12476{
12477 UA_TYPENAME("MetaDataQueueName") /* .memberName */
12478 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12479 offsetof(UA_BrokerDataSetReaderTransportDataType, metaDataQueueName) - offsetof(UA_BrokerDataSetReaderTransportDataType, requestedDeliveryGuarantee) - sizeof(UA_BrokerTransportQualityOfService), /* .padding */
12480 false, /* .isArray */
12481 false /* .isOptional */
12482},};
12483
12484/* PubSubConfigurationRefMask */
12485#define PubSubConfigurationRefMask_members NULL
12486
12487/* PubSubConfigurationRefDataType */
12488static UA_DataTypeMember PubSubConfigurationRefDataType_members[4] = {
12489{
12490 UA_TYPENAME("ConfigurationMask") /* .memberName */
12491 &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFMASK], /* .memberType */
12492 0, /* .padding */
12493 false, /* .isArray */
12494 false /* .isOptional */
12495},
12496{
12497 UA_TYPENAME("ElementIndex") /* .memberName */
12498 &UA_TYPES[UA_TYPES_UINT16], /* .memberType */
12499 offsetof(UA_PubSubConfigurationRefDataType, elementIndex) - offsetof(UA_PubSubConfigurationRefDataType, configurationMask) - sizeof(UA_PubSubConfigurationRefMask), /* .padding */
12500 false, /* .isArray */
12501 false /* .isOptional */
12502},
12503{
12504 UA_TYPENAME("ConnectionIndex") /* .memberName */
12505 &UA_TYPES[UA_TYPES_UINT16], /* .memberType */
12506 offsetof(UA_PubSubConfigurationRefDataType, connectionIndex) - offsetof(UA_PubSubConfigurationRefDataType, elementIndex) - sizeof(UA_UInt16), /* .padding */
12507 false, /* .isArray */
12508 false /* .isOptional */
12509},
12510{
12511 UA_TYPENAME("GroupIndex") /* .memberName */
12512 &UA_TYPES[UA_TYPES_UINT16], /* .memberType */
12513 offsetof(UA_PubSubConfigurationRefDataType, groupIndex) - offsetof(UA_PubSubConfigurationRefDataType, connectionIndex) - sizeof(UA_UInt16), /* .padding */
12514 false, /* .isArray */
12515 false /* .isOptional */
12516},};
12517
12518/* PubSubConfigurationValueDataType */
12519static UA_DataTypeMember PubSubConfigurationValueDataType_members[3] = {
12520{
12521 UA_TYPENAME("ConfigurationElement") /* .memberName */
12522 &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFDATATYPE], /* .memberType */
12523 0, /* .padding */
12524 false, /* .isArray */
12525 false /* .isOptional */
12526},
12527{
12528 UA_TYPENAME("Name") /* .memberName */
12529 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12530 offsetof(UA_PubSubConfigurationValueDataType, name) - offsetof(UA_PubSubConfigurationValueDataType, configurationElement) - sizeof(UA_PubSubConfigurationRefDataType), /* .padding */
12531 false, /* .isArray */
12532 false /* .isOptional */
12533},
12534{
12535 UA_TYPENAME("Identifier") /* .memberName */
12536 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
12537 offsetof(UA_PubSubConfigurationValueDataType, identifier) - offsetof(UA_PubSubConfigurationValueDataType, name) - sizeof(UA_String), /* .padding */
12538 false, /* .isArray */
12539 false /* .isOptional */
12540},};
12541
12542/* DiagnosticsLevel */
12543#define DiagnosticsLevel_members NULL
12544
12545/* PubSubDiagnosticsCounterClassification */
12546#define PubSubDiagnosticsCounterClassification_members NULL
12547
12548/* AliasNameDataType */
12549static UA_DataTypeMember AliasNameDataType_members[2] = {
12550{
12551 UA_TYPENAME("AliasName") /* .memberName */
12552 &UA_TYPES[UA_TYPES_QUALIFIEDNAME], /* .memberType */
12553 0, /* .padding */
12554 false, /* .isArray */
12555 false /* .isOptional */
12556},
12557{
12558 UA_TYPENAME("ReferencedNodes") /* .memberName */
12559 &UA_TYPES[UA_TYPES_EXPANDEDNODEID], /* .memberType */
12560 offsetof(UA_AliasNameDataType, referencedNodesSize) - offsetof(UA_AliasNameDataType, aliasName) - sizeof(UA_QualifiedName), /* .padding */
12561 true, /* .isArray */
12562 false /* .isOptional */
12563},};
12564
12565/* PasswordOptionsMask */
12566#define PasswordOptionsMask_members NULL
12567
12568/* UserConfigurationMask */
12569#define UserConfigurationMask_members NULL
12570
12571/* UserManagementDataType */
12572static UA_DataTypeMember UserManagementDataType_members[3] = {
12573{
12574 UA_TYPENAME("UserName") /* .memberName */
12575 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12576 0, /* .padding */
12577 false, /* .isArray */
12578 false /* .isOptional */
12579},
12580{
12581 UA_TYPENAME("UserConfiguration") /* .memberName */
12582 &UA_TYPES[UA_TYPES_USERCONFIGURATIONMASK], /* .memberType */
12583 offsetof(UA_UserManagementDataType, userConfiguration) - offsetof(UA_UserManagementDataType, userName) - sizeof(UA_String), /* .padding */
12584 false, /* .isArray */
12585 false /* .isOptional */
12586},
12587{
12588 UA_TYPENAME("Description") /* .memberName */
12589 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12590 offsetof(UA_UserManagementDataType, description) - offsetof(UA_UserManagementDataType, userConfiguration) - sizeof(UA_UserConfigurationMask), /* .padding */
12591 false, /* .isArray */
12592 false /* .isOptional */
12593},};
12594
12595/* Duplex */
12596#define Duplex_members NULL
12597
12598/* InterfaceAdminStatus */
12599#define InterfaceAdminStatus_members NULL
12600
12601/* InterfaceOperStatus */
12602#define InterfaceOperStatus_members NULL
12603
12604/* NegotiationStatus */
12605#define NegotiationStatus_members NULL
12606
12607/* TsnFailureCode */
12608#define TsnFailureCode_members NULL
12609
12610/* TsnStreamState */
12611#define TsnStreamState_members NULL
12612
12613/* TsnTalkerStatus */
12614#define TsnTalkerStatus_members NULL
12615
12616/* TsnListenerStatus */
12617#define TsnListenerStatus_members NULL
12618
12619/* PriorityMappingEntryType */
12620static UA_DataTypeMember PriorityMappingEntryType_members[4] = {
12621{
12622 UA_TYPENAME("MappingUri") /* .memberName */
12623 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12624 0, /* .padding */
12625 false, /* .isArray */
12626 false /* .isOptional */
12627},
12628{
12629 UA_TYPENAME("PriorityLabel") /* .memberName */
12630 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12631 offsetof(UA_PriorityMappingEntryType, priorityLabel) - offsetof(UA_PriorityMappingEntryType, mappingUri) - sizeof(UA_String), /* .padding */
12632 false, /* .isArray */
12633 false /* .isOptional */
12634},
12635{
12636 UA_TYPENAME("PriorityValue_PCP") /* .memberName */
12637 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
12638 offsetof(UA_PriorityMappingEntryType, priorityValue_PCP) - offsetof(UA_PriorityMappingEntryType, priorityLabel) - sizeof(UA_String), /* .padding */
12639 false, /* .isArray */
12640 false /* .isOptional */
12641},
12642{
12643 UA_TYPENAME("PriorityValue_DSCP") /* .memberName */
12644 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
12645 offsetof(UA_PriorityMappingEntryType, priorityValue_DSCP) - offsetof(UA_PriorityMappingEntryType, priorityValue_PCP) - sizeof(UA_Byte), /* .padding */
12646 false, /* .isArray */
12647 false /* .isOptional */
12648},};
12649
12650/* IdType */
12651#define IdType_members NULL
12652
12653/* NodeClass */
12654#define NodeClass_members NULL
12655
12656/* PermissionType */
12657#define PermissionType_members NULL
12658
12659/* AccessLevelType */
12660#define AccessLevelType_members NULL
12661
12662/* AccessLevelExType */
12663#define AccessLevelExType_members NULL
12664
12665/* EventNotifierType */
12666#define EventNotifierType_members NULL
12667
12668/* AccessRestrictionType */
12669#define AccessRestrictionType_members NULL
12670
12671/* RolePermissionType */
12672static UA_DataTypeMember RolePermissionType_members[2] = {
12673{
12674 UA_TYPENAME("RoleId") /* .memberName */
12675 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
12676 0, /* .padding */
12677 false, /* .isArray */
12678 false /* .isOptional */
12679},
12680{
12681 UA_TYPENAME("Permissions") /* .memberName */
12682 &UA_TYPES[UA_TYPES_PERMISSIONTYPE], /* .memberType */
12683 offsetof(UA_RolePermissionType, permissions) - offsetof(UA_RolePermissionType, roleId) - sizeof(UA_NodeId), /* .padding */
12684 false, /* .isArray */
12685 false /* .isOptional */
12686},};
12687
12688/* StructureType */
12689#define StructureType_members NULL
12690
12691/* StructureField */
12692static UA_DataTypeMember StructureField_members[7] = {
12693{
12694 UA_TYPENAME("Name") /* .memberName */
12695 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12696 0, /* .padding */
12697 false, /* .isArray */
12698 false /* .isOptional */
12699},
12700{
12701 UA_TYPENAME("Description") /* .memberName */
12702 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
12703 offsetof(UA_StructureField, description) - offsetof(UA_StructureField, name) - sizeof(UA_String), /* .padding */
12704 false, /* .isArray */
12705 false /* .isOptional */
12706},
12707{
12708 UA_TYPENAME("DataType") /* .memberName */
12709 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
12710 offsetof(UA_StructureField, dataType) - offsetof(UA_StructureField, description) - sizeof(UA_LocalizedText), /* .padding */
12711 false, /* .isArray */
12712 false /* .isOptional */
12713},
12714{
12715 UA_TYPENAME("ValueRank") /* .memberName */
12716 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
12717 offsetof(UA_StructureField, valueRank) - offsetof(UA_StructureField, dataType) - sizeof(UA_NodeId), /* .padding */
12718 false, /* .isArray */
12719 false /* .isOptional */
12720},
12721{
12722 UA_TYPENAME("ArrayDimensions") /* .memberName */
12723 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
12724 offsetof(UA_StructureField, arrayDimensionsSize) - offsetof(UA_StructureField, valueRank) - sizeof(UA_Int32), /* .padding */
12725 true, /* .isArray */
12726 false /* .isOptional */
12727},
12728{
12729 UA_TYPENAME("MaxStringLength") /* .memberName */
12730 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
12731 offsetof(UA_StructureField, maxStringLength) - offsetof(UA_StructureField, arrayDimensions) - sizeof(void *), /* .padding */
12732 false, /* .isArray */
12733 false /* .isOptional */
12734},
12735{
12736 UA_TYPENAME("IsOptional") /* .memberName */
12737 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
12738 offsetof(UA_StructureField, isOptional) - offsetof(UA_StructureField, maxStringLength) - sizeof(UA_UInt32), /* .padding */
12739 false, /* .isArray */
12740 false /* .isOptional */
12741},};
12742
12743/* StructureDefinition */
12744static UA_DataTypeMember StructureDefinition_members[4] = {
12745{
12746 UA_TYPENAME("DefaultEncodingId") /* .memberName */
12747 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
12748 0, /* .padding */
12749 false, /* .isArray */
12750 false /* .isOptional */
12751},
12752{
12753 UA_TYPENAME("BaseDataType") /* .memberName */
12754 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
12755 offsetof(UA_StructureDefinition, baseDataType) - offsetof(UA_StructureDefinition, defaultEncodingId) - sizeof(UA_NodeId), /* .padding */
12756 false, /* .isArray */
12757 false /* .isOptional */
12758},
12759{
12760 UA_TYPENAME("StructureType") /* .memberName */
12761 &UA_TYPES[UA_TYPES_STRUCTURETYPE], /* .memberType */
12762 offsetof(UA_StructureDefinition, structureType) - offsetof(UA_StructureDefinition, baseDataType) - sizeof(UA_NodeId), /* .padding */
12763 false, /* .isArray */
12764 false /* .isOptional */
12765},
12766{
12767 UA_TYPENAME("Fields") /* .memberName */
12768 &UA_TYPES[UA_TYPES_STRUCTUREFIELD], /* .memberType */
12769 offsetof(UA_StructureDefinition, fieldsSize) - offsetof(UA_StructureDefinition, structureType) - sizeof(UA_StructureType), /* .padding */
12770 true, /* .isArray */
12771 false /* .isOptional */
12772},};
12773
12774/* ReferenceNode */
12775static UA_DataTypeMember ReferenceNode_members[3] = {
12776{
12777 UA_TYPENAME("ReferenceTypeId") /* .memberName */
12778 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
12779 0, /* .padding */
12780 false, /* .isArray */
12781 false /* .isOptional */
12782},
12783{
12784 UA_TYPENAME("IsInverse") /* .memberName */
12785 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
12786 offsetof(UA_ReferenceNode, isInverse) - offsetof(UA_ReferenceNode, referenceTypeId) - sizeof(UA_NodeId), /* .padding */
12787 false, /* .isArray */
12788 false /* .isOptional */
12789},
12790{
12791 UA_TYPENAME("TargetId") /* .memberName */
12792 &UA_TYPES[UA_TYPES_EXPANDEDNODEID], /* .memberType */
12793 offsetof(UA_ReferenceNode, targetId) - offsetof(UA_ReferenceNode, isInverse) - sizeof(UA_Boolean), /* .padding */
12794 false, /* .isArray */
12795 false /* .isOptional */
12796},};
12797
12798/* Argument */
12799static UA_DataTypeMember Argument_members[5] = {
12800{
12801 UA_TYPENAME("Name") /* .memberName */
12802 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12803 0, /* .padding */
12804 false, /* .isArray */
12805 false /* .isOptional */
12806},
12807{
12808 UA_TYPENAME("DataType") /* .memberName */
12809 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
12810 offsetof(UA_Argument, dataType) - offsetof(UA_Argument, name) - sizeof(UA_String), /* .padding */
12811 false, /* .isArray */
12812 false /* .isOptional */
12813},
12814{
12815 UA_TYPENAME("ValueRank") /* .memberName */
12816 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
12817 offsetof(UA_Argument, valueRank) - offsetof(UA_Argument, dataType) - sizeof(UA_NodeId), /* .padding */
12818 false, /* .isArray */
12819 false /* .isOptional */
12820},
12821{
12822 UA_TYPENAME("ArrayDimensions") /* .memberName */
12823 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
12824 offsetof(UA_Argument, arrayDimensionsSize) - offsetof(UA_Argument, valueRank) - sizeof(UA_Int32), /* .padding */
12825 true, /* .isArray */
12826 false /* .isOptional */
12827},
12828{
12829 UA_TYPENAME("Description") /* .memberName */
12830 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
12831 offsetof(UA_Argument, description) - offsetof(UA_Argument, arrayDimensions) - sizeof(void *), /* .padding */
12832 false, /* .isArray */
12833 false /* .isOptional */
12834},};
12835
12836/* EnumValueType */
12837static UA_DataTypeMember EnumValueType_members[3] = {
12838{
12839 UA_TYPENAME("Value") /* .memberName */
12840 &UA_TYPES[UA_TYPES_INT64], /* .memberType */
12841 0, /* .padding */
12842 false, /* .isArray */
12843 false /* .isOptional */
12844},
12845{
12846 UA_TYPENAME("DisplayName") /* .memberName */
12847 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
12848 offsetof(UA_EnumValueType, displayName) - offsetof(UA_EnumValueType, value) - sizeof(UA_Int64), /* .padding */
12849 false, /* .isArray */
12850 false /* .isOptional */
12851},
12852{
12853 UA_TYPENAME("Description") /* .memberName */
12854 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
12855 offsetof(UA_EnumValueType, description) - offsetof(UA_EnumValueType, displayName) - sizeof(UA_LocalizedText), /* .padding */
12856 false, /* .isArray */
12857 false /* .isOptional */
12858},};
12859
12860/* EnumField */
12861static UA_DataTypeMember EnumField_members[4] = {
12862{
12863 UA_TYPENAME("Value") /* .memberName */
12864 &UA_TYPES[UA_TYPES_INT64], /* .memberType */
12865 0, /* .padding */
12866 false, /* .isArray */
12867 false /* .isOptional */
12868},
12869{
12870 UA_TYPENAME("DisplayName") /* .memberName */
12871 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
12872 offsetof(UA_EnumField, displayName) - offsetof(UA_EnumField, value) - sizeof(UA_Int64), /* .padding */
12873 false, /* .isArray */
12874 false /* .isOptional */
12875},
12876{
12877 UA_TYPENAME("Description") /* .memberName */
12878 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
12879 offsetof(UA_EnumField, description) - offsetof(UA_EnumField, displayName) - sizeof(UA_LocalizedText), /* .padding */
12880 false, /* .isArray */
12881 false /* .isOptional */
12882},
12883{
12884 UA_TYPENAME("Name") /* .memberName */
12885 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12886 offsetof(UA_EnumField, name) - offsetof(UA_EnumField, description) - sizeof(UA_LocalizedText), /* .padding */
12887 false, /* .isArray */
12888 false /* .isOptional */
12889},};
12890
12891/* OptionSet */
12892static UA_DataTypeMember OptionSet_members[2] = {
12893{
12894 UA_TYPENAME("Value") /* .memberName */
12895 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
12896 0, /* .padding */
12897 false, /* .isArray */
12898 false /* .isOptional */
12899},
12900{
12901 UA_TYPENAME("ValidBits") /* .memberName */
12902 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
12903 offsetof(UA_OptionSet, validBits) - offsetof(UA_OptionSet, value) - sizeof(UA_ByteString), /* .padding */
12904 false, /* .isArray */
12905 false /* .isOptional */
12906},};
12907
12908/* NormalizedString */
12909#define NormalizedString_members NULL
12910
12911/* DecimalString */
12912#define DecimalString_members NULL
12913
12914/* DurationString */
12915#define DurationString_members NULL
12916
12917/* TimeString */
12918#define TimeString_members NULL
12919
12920/* DateString */
12921#define DateString_members NULL
12922
12923/* Duration */
12924#define Duration_members NULL
12925
12926/* UtcTime */
12927#define UtcTime_members NULL
12928
12929/* LocaleId */
12930#define LocaleId_members NULL
12931
12932/* TimeZoneDataType */
12933static UA_DataTypeMember TimeZoneDataType_members[2] = {
12934{
12935 UA_TYPENAME("Offset") /* .memberName */
12936 &UA_TYPES[UA_TYPES_INT16], /* .memberType */
12937 0, /* .padding */
12938 false, /* .isArray */
12939 false /* .isOptional */
12940},
12941{
12942 UA_TYPENAME("DaylightSavingInOffset") /* .memberName */
12943 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
12944 offsetof(UA_TimeZoneDataType, daylightSavingInOffset) - offsetof(UA_TimeZoneDataType, offset) - sizeof(UA_Int16), /* .padding */
12945 false, /* .isArray */
12946 false /* .isOptional */
12947},};
12948
12949/* Index */
12950#define Index_members NULL
12951
12952/* IntegerId */
12953#define IntegerId_members NULL
12954
12955/* ApplicationType */
12956#define ApplicationType_members NULL
12957
12958/* ApplicationDescription */
12959static UA_DataTypeMember ApplicationDescription_members[7] = {
12960{
12961 UA_TYPENAME("ApplicationUri") /* .memberName */
12962 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12963 0, /* .padding */
12964 false, /* .isArray */
12965 false /* .isOptional */
12966},
12967{
12968 UA_TYPENAME("ProductUri") /* .memberName */
12969 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12970 offsetof(UA_ApplicationDescription, productUri) - offsetof(UA_ApplicationDescription, applicationUri) - sizeof(UA_String), /* .padding */
12971 false, /* .isArray */
12972 false /* .isOptional */
12973},
12974{
12975 UA_TYPENAME("ApplicationName") /* .memberName */
12976 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
12977 offsetof(UA_ApplicationDescription, applicationName) - offsetof(UA_ApplicationDescription, productUri) - sizeof(UA_String), /* .padding */
12978 false, /* .isArray */
12979 false /* .isOptional */
12980},
12981{
12982 UA_TYPENAME("ApplicationType") /* .memberName */
12983 &UA_TYPES[UA_TYPES_APPLICATIONTYPE], /* .memberType */
12984 offsetof(UA_ApplicationDescription, applicationType) - offsetof(UA_ApplicationDescription, applicationName) - sizeof(UA_LocalizedText), /* .padding */
12985 false, /* .isArray */
12986 false /* .isOptional */
12987},
12988{
12989 UA_TYPENAME("GatewayServerUri") /* .memberName */
12990 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12991 offsetof(UA_ApplicationDescription, gatewayServerUri) - offsetof(UA_ApplicationDescription, applicationType) - sizeof(UA_ApplicationType), /* .padding */
12992 false, /* .isArray */
12993 false /* .isOptional */
12994},
12995{
12996 UA_TYPENAME("DiscoveryProfileUri") /* .memberName */
12997 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
12998 offsetof(UA_ApplicationDescription, discoveryProfileUri) - offsetof(UA_ApplicationDescription, gatewayServerUri) - sizeof(UA_String), /* .padding */
12999 false, /* .isArray */
13000 false /* .isOptional */
13001},
13002{
13003 UA_TYPENAME("DiscoveryUrls") /* .memberName */
13004 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13005 offsetof(UA_ApplicationDescription, discoveryUrlsSize) - offsetof(UA_ApplicationDescription, discoveryProfileUri) - sizeof(UA_String), /* .padding */
13006 true, /* .isArray */
13007 false /* .isOptional */
13008},};
13009
13010/* RequestHeader */
13011static UA_DataTypeMember RequestHeader_members[7] = {
13012{
13013 UA_TYPENAME("AuthenticationToken") /* .memberName */
13014 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
13015 0, /* .padding */
13016 false, /* .isArray */
13017 false /* .isOptional */
13018},
13019{
13020 UA_TYPENAME("Timestamp") /* .memberName */
13021 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
13022 offsetof(UA_RequestHeader, timestamp) - offsetof(UA_RequestHeader, authenticationToken) - sizeof(UA_NodeId), /* .padding */
13023 false, /* .isArray */
13024 false /* .isOptional */
13025},
13026{
13027 UA_TYPENAME("RequestHandle") /* .memberName */
13028 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13029 offsetof(UA_RequestHeader, requestHandle) - offsetof(UA_RequestHeader, timestamp) - sizeof(UA_DateTime), /* .padding */
13030 false, /* .isArray */
13031 false /* .isOptional */
13032},
13033{
13034 UA_TYPENAME("ReturnDiagnostics") /* .memberName */
13035 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13036 offsetof(UA_RequestHeader, returnDiagnostics) - offsetof(UA_RequestHeader, requestHandle) - sizeof(UA_UInt32), /* .padding */
13037 false, /* .isArray */
13038 false /* .isOptional */
13039},
13040{
13041 UA_TYPENAME("AuditEntryId") /* .memberName */
13042 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13043 offsetof(UA_RequestHeader, auditEntryId) - offsetof(UA_RequestHeader, returnDiagnostics) - sizeof(UA_UInt32), /* .padding */
13044 false, /* .isArray */
13045 false /* .isOptional */
13046},
13047{
13048 UA_TYPENAME("TimeoutHint") /* .memberName */
13049 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13050 offsetof(UA_RequestHeader, timeoutHint) - offsetof(UA_RequestHeader, auditEntryId) - sizeof(UA_String), /* .padding */
13051 false, /* .isArray */
13052 false /* .isOptional */
13053},
13054{
13055 UA_TYPENAME("AdditionalHeader") /* .memberName */
13056 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
13057 offsetof(UA_RequestHeader, additionalHeader) - offsetof(UA_RequestHeader, timeoutHint) - sizeof(UA_UInt32), /* .padding */
13058 false, /* .isArray */
13059 false /* .isOptional */
13060},};
13061
13062/* ResponseHeader */
13063static UA_DataTypeMember ResponseHeader_members[6] = {
13064{
13065 UA_TYPENAME("Timestamp") /* .memberName */
13066 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
13067 0, /* .padding */
13068 false, /* .isArray */
13069 false /* .isOptional */
13070},
13071{
13072 UA_TYPENAME("RequestHandle") /* .memberName */
13073 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13074 offsetof(UA_ResponseHeader, requestHandle) - offsetof(UA_ResponseHeader, timestamp) - sizeof(UA_DateTime), /* .padding */
13075 false, /* .isArray */
13076 false /* .isOptional */
13077},
13078{
13079 UA_TYPENAME("ServiceResult") /* .memberName */
13080 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
13081 offsetof(UA_ResponseHeader, serviceResult) - offsetof(UA_ResponseHeader, requestHandle) - sizeof(UA_UInt32), /* .padding */
13082 false, /* .isArray */
13083 false /* .isOptional */
13084},
13085{
13086 UA_TYPENAME("ServiceDiagnostics") /* .memberName */
13087 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
13088 offsetof(UA_ResponseHeader, serviceDiagnostics) - offsetof(UA_ResponseHeader, serviceResult) - sizeof(UA_StatusCode), /* .padding */
13089 false, /* .isArray */
13090 false /* .isOptional */
13091},
13092{
13093 UA_TYPENAME("StringTable") /* .memberName */
13094 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13095 offsetof(UA_ResponseHeader, stringTableSize) - offsetof(UA_ResponseHeader, serviceDiagnostics) - sizeof(UA_DiagnosticInfo), /* .padding */
13096 true, /* .isArray */
13097 false /* .isOptional */
13098},
13099{
13100 UA_TYPENAME("AdditionalHeader") /* .memberName */
13101 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
13102 offsetof(UA_ResponseHeader, additionalHeader) - offsetof(UA_ResponseHeader, stringTable) - sizeof(void *), /* .padding */
13103 false, /* .isArray */
13104 false /* .isOptional */
13105},};
13106
13107/* VersionTime */
13108#define VersionTime_members NULL
13109
13110/* ServiceFault */
13111static UA_DataTypeMember ServiceFault_members[1] = {
13112{
13113 UA_TYPENAME("ResponseHeader") /* .memberName */
13114 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
13115 0, /* .padding */
13116 false, /* .isArray */
13117 false /* .isOptional */
13118},};
13119
13120/* SessionlessInvokeRequestType */
13121static UA_DataTypeMember SessionlessInvokeRequestType_members[5] = {
13122{
13123 UA_TYPENAME("UrisVersion") /* .memberName */
13124 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13125 0, /* .padding */
13126 false, /* .isArray */
13127 false /* .isOptional */
13128},
13129{
13130 UA_TYPENAME("NamespaceUris") /* .memberName */
13131 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13132 offsetof(UA_SessionlessInvokeRequestType, namespaceUrisSize) - offsetof(UA_SessionlessInvokeRequestType, urisVersion) - sizeof(UA_UInt32), /* .padding */
13133 true, /* .isArray */
13134 false /* .isOptional */
13135},
13136{
13137 UA_TYPENAME("ServerUris") /* .memberName */
13138 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13139 offsetof(UA_SessionlessInvokeRequestType, serverUrisSize) - offsetof(UA_SessionlessInvokeRequestType, namespaceUris) - sizeof(void *), /* .padding */
13140 true, /* .isArray */
13141 false /* .isOptional */
13142},
13143{
13144 UA_TYPENAME("LocaleIds") /* .memberName */
13145 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13146 offsetof(UA_SessionlessInvokeRequestType, localeIdsSize) - offsetof(UA_SessionlessInvokeRequestType, serverUris) - sizeof(void *), /* .padding */
13147 true, /* .isArray */
13148 false /* .isOptional */
13149},
13150{
13151 UA_TYPENAME("ServiceId") /* .memberName */
13152 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13153 offsetof(UA_SessionlessInvokeRequestType, serviceId) - offsetof(UA_SessionlessInvokeRequestType, localeIds) - sizeof(void *), /* .padding */
13154 false, /* .isArray */
13155 false /* .isOptional */
13156},};
13157
13158/* SessionlessInvokeResponseType */
13159static UA_DataTypeMember SessionlessInvokeResponseType_members[3] = {
13160{
13161 UA_TYPENAME("NamespaceUris") /* .memberName */
13162 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13163 0, /* .padding */
13164 true, /* .isArray */
13165 false /* .isOptional */
13166},
13167{
13168 UA_TYPENAME("ServerUris") /* .memberName */
13169 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13170 offsetof(UA_SessionlessInvokeResponseType, serverUrisSize) - offsetof(UA_SessionlessInvokeResponseType, namespaceUris) - sizeof(void *), /* .padding */
13171 true, /* .isArray */
13172 false /* .isOptional */
13173},
13174{
13175 UA_TYPENAME("ServiceId") /* .memberName */
13176 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13177 offsetof(UA_SessionlessInvokeResponseType, serviceId) - offsetof(UA_SessionlessInvokeResponseType, serverUris) - sizeof(void *), /* .padding */
13178 false, /* .isArray */
13179 false /* .isOptional */
13180},};
13181
13182/* FindServersRequest */
13183static UA_DataTypeMember FindServersRequest_members[4] = {
13184{
13185 UA_TYPENAME("RequestHeader") /* .memberName */
13186 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
13187 0, /* .padding */
13188 false, /* .isArray */
13189 false /* .isOptional */
13190},
13191{
13192 UA_TYPENAME("EndpointUrl") /* .memberName */
13193 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13194 offsetof(UA_FindServersRequest, endpointUrl) - offsetof(UA_FindServersRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
13195 false, /* .isArray */
13196 false /* .isOptional */
13197},
13198{
13199 UA_TYPENAME("LocaleIds") /* .memberName */
13200 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13201 offsetof(UA_FindServersRequest, localeIdsSize) - offsetof(UA_FindServersRequest, endpointUrl) - sizeof(UA_String), /* .padding */
13202 true, /* .isArray */
13203 false /* .isOptional */
13204},
13205{
13206 UA_TYPENAME("ServerUris") /* .memberName */
13207 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13208 offsetof(UA_FindServersRequest, serverUrisSize) - offsetof(UA_FindServersRequest, localeIds) - sizeof(void *), /* .padding */
13209 true, /* .isArray */
13210 false /* .isOptional */
13211},};
13212
13213/* FindServersResponse */
13214static UA_DataTypeMember FindServersResponse_members[2] = {
13215{
13216 UA_TYPENAME("ResponseHeader") /* .memberName */
13217 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
13218 0, /* .padding */
13219 false, /* .isArray */
13220 false /* .isOptional */
13221},
13222{
13223 UA_TYPENAME("Servers") /* .memberName */
13224 &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION], /* .memberType */
13225 offsetof(UA_FindServersResponse, serversSize) - offsetof(UA_FindServersResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
13226 true, /* .isArray */
13227 false /* .isOptional */
13228},};
13229
13230/* ServerOnNetwork */
13231static UA_DataTypeMember ServerOnNetwork_members[4] = {
13232{
13233 UA_TYPENAME("RecordId") /* .memberName */
13234 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13235 0, /* .padding */
13236 false, /* .isArray */
13237 false /* .isOptional */
13238},
13239{
13240 UA_TYPENAME("ServerName") /* .memberName */
13241 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13242 offsetof(UA_ServerOnNetwork, serverName) - offsetof(UA_ServerOnNetwork, recordId) - sizeof(UA_UInt32), /* .padding */
13243 false, /* .isArray */
13244 false /* .isOptional */
13245},
13246{
13247 UA_TYPENAME("DiscoveryUrl") /* .memberName */
13248 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13249 offsetof(UA_ServerOnNetwork, discoveryUrl) - offsetof(UA_ServerOnNetwork, serverName) - sizeof(UA_String), /* .padding */
13250 false, /* .isArray */
13251 false /* .isOptional */
13252},
13253{
13254 UA_TYPENAME("ServerCapabilities") /* .memberName */
13255 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13256 offsetof(UA_ServerOnNetwork, serverCapabilitiesSize) - offsetof(UA_ServerOnNetwork, discoveryUrl) - sizeof(UA_String), /* .padding */
13257 true, /* .isArray */
13258 false /* .isOptional */
13259},};
13260
13261/* FindServersOnNetworkRequest */
13262static UA_DataTypeMember FindServersOnNetworkRequest_members[4] = {
13263{
13264 UA_TYPENAME("RequestHeader") /* .memberName */
13265 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
13266 0, /* .padding */
13267 false, /* .isArray */
13268 false /* .isOptional */
13269},
13270{
13271 UA_TYPENAME("StartingRecordId") /* .memberName */
13272 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13273 offsetof(UA_FindServersOnNetworkRequest, startingRecordId) - offsetof(UA_FindServersOnNetworkRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
13274 false, /* .isArray */
13275 false /* .isOptional */
13276},
13277{
13278 UA_TYPENAME("MaxRecordsToReturn") /* .memberName */
13279 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13280 offsetof(UA_FindServersOnNetworkRequest, maxRecordsToReturn) - offsetof(UA_FindServersOnNetworkRequest, startingRecordId) - sizeof(UA_UInt32), /* .padding */
13281 false, /* .isArray */
13282 false /* .isOptional */
13283},
13284{
13285 UA_TYPENAME("ServerCapabilityFilter") /* .memberName */
13286 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13287 offsetof(UA_FindServersOnNetworkRequest, serverCapabilityFilterSize) - offsetof(UA_FindServersOnNetworkRequest, maxRecordsToReturn) - sizeof(UA_UInt32), /* .padding */
13288 true, /* .isArray */
13289 false /* .isOptional */
13290},};
13291
13292/* FindServersOnNetworkResponse */
13293static UA_DataTypeMember FindServersOnNetworkResponse_members[3] = {
13294{
13295 UA_TYPENAME("ResponseHeader") /* .memberName */
13296 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
13297 0, /* .padding */
13298 false, /* .isArray */
13299 false /* .isOptional */
13300},
13301{
13302 UA_TYPENAME("LastCounterResetTime") /* .memberName */
13303 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
13304 offsetof(UA_FindServersOnNetworkResponse, lastCounterResetTime) - offsetof(UA_FindServersOnNetworkResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
13305 false, /* .isArray */
13306 false /* .isOptional */
13307},
13308{
13309 UA_TYPENAME("Servers") /* .memberName */
13310 &UA_TYPES[UA_TYPES_SERVERONNETWORK], /* .memberType */
13311 offsetof(UA_FindServersOnNetworkResponse, serversSize) - offsetof(UA_FindServersOnNetworkResponse, lastCounterResetTime) - sizeof(UA_DateTime), /* .padding */
13312 true, /* .isArray */
13313 false /* .isOptional */
13314},};
13315
13316/* ApplicationInstanceCertificate */
13317#define ApplicationInstanceCertificate_members NULL
13318
13319/* MessageSecurityMode */
13320#define MessageSecurityMode_members NULL
13321
13322/* UserTokenType */
13323#define UserTokenType_members NULL
13324
13325/* UserTokenPolicy */
13326static UA_DataTypeMember UserTokenPolicy_members[5] = {
13327{
13328 UA_TYPENAME("PolicyId") /* .memberName */
13329 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13330 0, /* .padding */
13331 false, /* .isArray */
13332 false /* .isOptional */
13333},
13334{
13335 UA_TYPENAME("TokenType") /* .memberName */
13336 &UA_TYPES[UA_TYPES_USERTOKENTYPE], /* .memberType */
13337 offsetof(UA_UserTokenPolicy, tokenType) - offsetof(UA_UserTokenPolicy, policyId) - sizeof(UA_String), /* .padding */
13338 false, /* .isArray */
13339 false /* .isOptional */
13340},
13341{
13342 UA_TYPENAME("IssuedTokenType") /* .memberName */
13343 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13344 offsetof(UA_UserTokenPolicy, issuedTokenType) - offsetof(UA_UserTokenPolicy, tokenType) - sizeof(UA_UserTokenType), /* .padding */
13345 false, /* .isArray */
13346 false /* .isOptional */
13347},
13348{
13349 UA_TYPENAME("IssuerEndpointUrl") /* .memberName */
13350 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13351 offsetof(UA_UserTokenPolicy, issuerEndpointUrl) - offsetof(UA_UserTokenPolicy, issuedTokenType) - sizeof(UA_String), /* .padding */
13352 false, /* .isArray */
13353 false /* .isOptional */
13354},
13355{
13356 UA_TYPENAME("SecurityPolicyUri") /* .memberName */
13357 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13358 offsetof(UA_UserTokenPolicy, securityPolicyUri) - offsetof(UA_UserTokenPolicy, issuerEndpointUrl) - sizeof(UA_String), /* .padding */
13359 false, /* .isArray */
13360 false /* .isOptional */
13361},};
13362
13363/* EndpointDescription */
13364static UA_DataTypeMember EndpointDescription_members[8] = {
13365{
13366 UA_TYPENAME("EndpointUrl") /* .memberName */
13367 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13368 0, /* .padding */
13369 false, /* .isArray */
13370 false /* .isOptional */
13371},
13372{
13373 UA_TYPENAME("Server") /* .memberName */
13374 &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION], /* .memberType */
13375 offsetof(UA_EndpointDescription, server) - offsetof(UA_EndpointDescription, endpointUrl) - sizeof(UA_String), /* .padding */
13376 false, /* .isArray */
13377 false /* .isOptional */
13378},
13379{
13380 UA_TYPENAME("ServerCertificate") /* .memberName */
13381 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
13382 offsetof(UA_EndpointDescription, serverCertificate) - offsetof(UA_EndpointDescription, server) - sizeof(UA_ApplicationDescription), /* .padding */
13383 false, /* .isArray */
13384 false /* .isOptional */
13385},
13386{
13387 UA_TYPENAME("SecurityMode") /* .memberName */
13388 &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE], /* .memberType */
13389 offsetof(UA_EndpointDescription, securityMode) - offsetof(UA_EndpointDescription, serverCertificate) - sizeof(UA_ByteString), /* .padding */
13390 false, /* .isArray */
13391 false /* .isOptional */
13392},
13393{
13394 UA_TYPENAME("SecurityPolicyUri") /* .memberName */
13395 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13396 offsetof(UA_EndpointDescription, securityPolicyUri) - offsetof(UA_EndpointDescription, securityMode) - sizeof(UA_MessageSecurityMode), /* .padding */
13397 false, /* .isArray */
13398 false /* .isOptional */
13399},
13400{
13401 UA_TYPENAME("UserIdentityTokens") /* .memberName */
13402 &UA_TYPES[UA_TYPES_USERTOKENPOLICY], /* .memberType */
13403 offsetof(UA_EndpointDescription, userIdentityTokensSize) - offsetof(UA_EndpointDescription, securityPolicyUri) - sizeof(UA_String), /* .padding */
13404 true, /* .isArray */
13405 false /* .isOptional */
13406},
13407{
13408 UA_TYPENAME("TransportProfileUri") /* .memberName */
13409 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13410 offsetof(UA_EndpointDescription, transportProfileUri) - offsetof(UA_EndpointDescription, userIdentityTokens) - sizeof(void *), /* .padding */
13411 false, /* .isArray */
13412 false /* .isOptional */
13413},
13414{
13415 UA_TYPENAME("SecurityLevel") /* .memberName */
13416 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
13417 offsetof(UA_EndpointDescription, securityLevel) - offsetof(UA_EndpointDescription, transportProfileUri) - sizeof(UA_String), /* .padding */
13418 false, /* .isArray */
13419 false /* .isOptional */
13420},};
13421
13422/* GetEndpointsRequest */
13423static UA_DataTypeMember GetEndpointsRequest_members[4] = {
13424{
13425 UA_TYPENAME("RequestHeader") /* .memberName */
13426 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
13427 0, /* .padding */
13428 false, /* .isArray */
13429 false /* .isOptional */
13430},
13431{
13432 UA_TYPENAME("EndpointUrl") /* .memberName */
13433 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13434 offsetof(UA_GetEndpointsRequest, endpointUrl) - offsetof(UA_GetEndpointsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
13435 false, /* .isArray */
13436 false /* .isOptional */
13437},
13438{
13439 UA_TYPENAME("LocaleIds") /* .memberName */
13440 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13441 offsetof(UA_GetEndpointsRequest, localeIdsSize) - offsetof(UA_GetEndpointsRequest, endpointUrl) - sizeof(UA_String), /* .padding */
13442 true, /* .isArray */
13443 false /* .isOptional */
13444},
13445{
13446 UA_TYPENAME("ProfileUris") /* .memberName */
13447 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13448 offsetof(UA_GetEndpointsRequest, profileUrisSize) - offsetof(UA_GetEndpointsRequest, localeIds) - sizeof(void *), /* .padding */
13449 true, /* .isArray */
13450 false /* .isOptional */
13451},};
13452
13453/* GetEndpointsResponse */
13454static UA_DataTypeMember GetEndpointsResponse_members[2] = {
13455{
13456 UA_TYPENAME("ResponseHeader") /* .memberName */
13457 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
13458 0, /* .padding */
13459 false, /* .isArray */
13460 false /* .isOptional */
13461},
13462{
13463 UA_TYPENAME("Endpoints") /* .memberName */
13464 &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION], /* .memberType */
13465 offsetof(UA_GetEndpointsResponse, endpointsSize) - offsetof(UA_GetEndpointsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
13466 true, /* .isArray */
13467 false /* .isOptional */
13468},};
13469
13470/* RegisteredServer */
13471static UA_DataTypeMember RegisteredServer_members[8] = {
13472{
13473 UA_TYPENAME("ServerUri") /* .memberName */
13474 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13475 0, /* .padding */
13476 false, /* .isArray */
13477 false /* .isOptional */
13478},
13479{
13480 UA_TYPENAME("ProductUri") /* .memberName */
13481 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13482 offsetof(UA_RegisteredServer, productUri) - offsetof(UA_RegisteredServer, serverUri) - sizeof(UA_String), /* .padding */
13483 false, /* .isArray */
13484 false /* .isOptional */
13485},
13486{
13487 UA_TYPENAME("ServerNames") /* .memberName */
13488 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
13489 offsetof(UA_RegisteredServer, serverNamesSize) - offsetof(UA_RegisteredServer, productUri) - sizeof(UA_String), /* .padding */
13490 true, /* .isArray */
13491 false /* .isOptional */
13492},
13493{
13494 UA_TYPENAME("ServerType") /* .memberName */
13495 &UA_TYPES[UA_TYPES_APPLICATIONTYPE], /* .memberType */
13496 offsetof(UA_RegisteredServer, serverType) - offsetof(UA_RegisteredServer, serverNames) - sizeof(void *), /* .padding */
13497 false, /* .isArray */
13498 false /* .isOptional */
13499},
13500{
13501 UA_TYPENAME("GatewayServerUri") /* .memberName */
13502 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13503 offsetof(UA_RegisteredServer, gatewayServerUri) - offsetof(UA_RegisteredServer, serverType) - sizeof(UA_ApplicationType), /* .padding */
13504 false, /* .isArray */
13505 false /* .isOptional */
13506},
13507{
13508 UA_TYPENAME("DiscoveryUrls") /* .memberName */
13509 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13510 offsetof(UA_RegisteredServer, discoveryUrlsSize) - offsetof(UA_RegisteredServer, gatewayServerUri) - sizeof(UA_String), /* .padding */
13511 true, /* .isArray */
13512 false /* .isOptional */
13513},
13514{
13515 UA_TYPENAME("SemaphoreFilePath") /* .memberName */
13516 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13517 offsetof(UA_RegisteredServer, semaphoreFilePath) - offsetof(UA_RegisteredServer, discoveryUrls) - sizeof(void *), /* .padding */
13518 false, /* .isArray */
13519 false /* .isOptional */
13520},
13521{
13522 UA_TYPENAME("IsOnline") /* .memberName */
13523 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
13524 offsetof(UA_RegisteredServer, isOnline) - offsetof(UA_RegisteredServer, semaphoreFilePath) - sizeof(UA_String), /* .padding */
13525 false, /* .isArray */
13526 false /* .isOptional */
13527},};
13528
13529/* RegisterServerRequest */
13530static UA_DataTypeMember RegisterServerRequest_members[2] = {
13531{
13532 UA_TYPENAME("RequestHeader") /* .memberName */
13533 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
13534 0, /* .padding */
13535 false, /* .isArray */
13536 false /* .isOptional */
13537},
13538{
13539 UA_TYPENAME("Server") /* .memberName */
13540 &UA_TYPES[UA_TYPES_REGISTEREDSERVER], /* .memberType */
13541 offsetof(UA_RegisterServerRequest, server) - offsetof(UA_RegisterServerRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
13542 false, /* .isArray */
13543 false /* .isOptional */
13544},};
13545
13546/* RegisterServerResponse */
13547static UA_DataTypeMember RegisterServerResponse_members[1] = {
13548{
13549 UA_TYPENAME("ResponseHeader") /* .memberName */
13550 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
13551 0, /* .padding */
13552 false, /* .isArray */
13553 false /* .isOptional */
13554},};
13555
13556/* MdnsDiscoveryConfiguration */
13557static UA_DataTypeMember MdnsDiscoveryConfiguration_members[2] = {
13558{
13559 UA_TYPENAME("MdnsServerName") /* .memberName */
13560 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13561 0, /* .padding */
13562 false, /* .isArray */
13563 false /* .isOptional */
13564},
13565{
13566 UA_TYPENAME("ServerCapabilities") /* .memberName */
13567 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13568 offsetof(UA_MdnsDiscoveryConfiguration, serverCapabilitiesSize) - offsetof(UA_MdnsDiscoveryConfiguration, mdnsServerName) - sizeof(UA_String), /* .padding */
13569 true, /* .isArray */
13570 false /* .isOptional */
13571},};
13572
13573/* RegisterServer2Request */
13574static UA_DataTypeMember RegisterServer2Request_members[3] = {
13575{
13576 UA_TYPENAME("RequestHeader") /* .memberName */
13577 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
13578 0, /* .padding */
13579 false, /* .isArray */
13580 false /* .isOptional */
13581},
13582{
13583 UA_TYPENAME("Server") /* .memberName */
13584 &UA_TYPES[UA_TYPES_REGISTEREDSERVER], /* .memberType */
13585 offsetof(UA_RegisterServer2Request, server) - offsetof(UA_RegisterServer2Request, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
13586 false, /* .isArray */
13587 false /* .isOptional */
13588},
13589{
13590 UA_TYPENAME("DiscoveryConfiguration") /* .memberName */
13591 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
13592 offsetof(UA_RegisterServer2Request, discoveryConfigurationSize) - offsetof(UA_RegisterServer2Request, server) - sizeof(UA_RegisteredServer), /* .padding */
13593 true, /* .isArray */
13594 false /* .isOptional */
13595},};
13596
13597/* RegisterServer2Response */
13598static UA_DataTypeMember RegisterServer2Response_members[3] = {
13599{
13600 UA_TYPENAME("ResponseHeader") /* .memberName */
13601 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
13602 0, /* .padding */
13603 false, /* .isArray */
13604 false /* .isOptional */
13605},
13606{
13607 UA_TYPENAME("ConfigurationResults") /* .memberName */
13608 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
13609 offsetof(UA_RegisterServer2Response, configurationResultsSize) - offsetof(UA_RegisterServer2Response, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
13610 true, /* .isArray */
13611 false /* .isOptional */
13612},
13613{
13614 UA_TYPENAME("DiagnosticInfos") /* .memberName */
13615 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
13616 offsetof(UA_RegisterServer2Response, diagnosticInfosSize) - offsetof(UA_RegisterServer2Response, configurationResults) - sizeof(void *), /* .padding */
13617 true, /* .isArray */
13618 false /* .isOptional */
13619},};
13620
13621/* SecurityTokenRequestType */
13622#define SecurityTokenRequestType_members NULL
13623
13624/* ChannelSecurityToken */
13625static UA_DataTypeMember ChannelSecurityToken_members[4] = {
13626{
13627 UA_TYPENAME("ChannelId") /* .memberName */
13628 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13629 0, /* .padding */
13630 false, /* .isArray */
13631 false /* .isOptional */
13632},
13633{
13634 UA_TYPENAME("TokenId") /* .memberName */
13635 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13636 offsetof(UA_ChannelSecurityToken, tokenId) - offsetof(UA_ChannelSecurityToken, channelId) - sizeof(UA_UInt32), /* .padding */
13637 false, /* .isArray */
13638 false /* .isOptional */
13639},
13640{
13641 UA_TYPENAME("CreatedAt") /* .memberName */
13642 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
13643 offsetof(UA_ChannelSecurityToken, createdAt) - offsetof(UA_ChannelSecurityToken, tokenId) - sizeof(UA_UInt32), /* .padding */
13644 false, /* .isArray */
13645 false /* .isOptional */
13646},
13647{
13648 UA_TYPENAME("RevisedLifetime") /* .memberName */
13649 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13650 offsetof(UA_ChannelSecurityToken, revisedLifetime) - offsetof(UA_ChannelSecurityToken, createdAt) - sizeof(UA_DateTime), /* .padding */
13651 false, /* .isArray */
13652 false /* .isOptional */
13653},};
13654
13655/* OpenSecureChannelRequest */
13656static UA_DataTypeMember OpenSecureChannelRequest_members[6] = {
13657{
13658 UA_TYPENAME("RequestHeader") /* .memberName */
13659 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
13660 0, /* .padding */
13661 false, /* .isArray */
13662 false /* .isOptional */
13663},
13664{
13665 UA_TYPENAME("ClientProtocolVersion") /* .memberName */
13666 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13667 offsetof(UA_OpenSecureChannelRequest, clientProtocolVersion) - offsetof(UA_OpenSecureChannelRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
13668 false, /* .isArray */
13669 false /* .isOptional */
13670},
13671{
13672 UA_TYPENAME("RequestType") /* .memberName */
13673 &UA_TYPES[UA_TYPES_SECURITYTOKENREQUESTTYPE], /* .memberType */
13674 offsetof(UA_OpenSecureChannelRequest, requestType) - offsetof(UA_OpenSecureChannelRequest, clientProtocolVersion) - sizeof(UA_UInt32), /* .padding */
13675 false, /* .isArray */
13676 false /* .isOptional */
13677},
13678{
13679 UA_TYPENAME("SecurityMode") /* .memberName */
13680 &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE], /* .memberType */
13681 offsetof(UA_OpenSecureChannelRequest, securityMode) - offsetof(UA_OpenSecureChannelRequest, requestType) - sizeof(UA_SecurityTokenRequestType), /* .padding */
13682 false, /* .isArray */
13683 false /* .isOptional */
13684},
13685{
13686 UA_TYPENAME("ClientNonce") /* .memberName */
13687 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
13688 offsetof(UA_OpenSecureChannelRequest, clientNonce) - offsetof(UA_OpenSecureChannelRequest, securityMode) - sizeof(UA_MessageSecurityMode), /* .padding */
13689 false, /* .isArray */
13690 false /* .isOptional */
13691},
13692{
13693 UA_TYPENAME("RequestedLifetime") /* .memberName */
13694 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13695 offsetof(UA_OpenSecureChannelRequest, requestedLifetime) - offsetof(UA_OpenSecureChannelRequest, clientNonce) - sizeof(UA_ByteString), /* .padding */
13696 false, /* .isArray */
13697 false /* .isOptional */
13698},};
13699
13700/* OpenSecureChannelResponse */
13701static UA_DataTypeMember OpenSecureChannelResponse_members[4] = {
13702{
13703 UA_TYPENAME("ResponseHeader") /* .memberName */
13704 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
13705 0, /* .padding */
13706 false, /* .isArray */
13707 false /* .isOptional */
13708},
13709{
13710 UA_TYPENAME("ServerProtocolVersion") /* .memberName */
13711 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13712 offsetof(UA_OpenSecureChannelResponse, serverProtocolVersion) - offsetof(UA_OpenSecureChannelResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
13713 false, /* .isArray */
13714 false /* .isOptional */
13715},
13716{
13717 UA_TYPENAME("SecurityToken") /* .memberName */
13718 &UA_TYPES[UA_TYPES_CHANNELSECURITYTOKEN], /* .memberType */
13719 offsetof(UA_OpenSecureChannelResponse, securityToken) - offsetof(UA_OpenSecureChannelResponse, serverProtocolVersion) - sizeof(UA_UInt32), /* .padding */
13720 false, /* .isArray */
13721 false /* .isOptional */
13722},
13723{
13724 UA_TYPENAME("ServerNonce") /* .memberName */
13725 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
13726 offsetof(UA_OpenSecureChannelResponse, serverNonce) - offsetof(UA_OpenSecureChannelResponse, securityToken) - sizeof(UA_ChannelSecurityToken), /* .padding */
13727 false, /* .isArray */
13728 false /* .isOptional */
13729},};
13730
13731/* CloseSecureChannelRequest */
13732static UA_DataTypeMember CloseSecureChannelRequest_members[1] = {
13733{
13734 UA_TYPENAME("RequestHeader") /* .memberName */
13735 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
13736 0, /* .padding */
13737 false, /* .isArray */
13738 false /* .isOptional */
13739},};
13740
13741/* CloseSecureChannelResponse */
13742static UA_DataTypeMember CloseSecureChannelResponse_members[1] = {
13743{
13744 UA_TYPENAME("ResponseHeader") /* .memberName */
13745 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
13746 0, /* .padding */
13747 false, /* .isArray */
13748 false /* .isOptional */
13749},};
13750
13751/* SignedSoftwareCertificate */
13752static UA_DataTypeMember SignedSoftwareCertificate_members[2] = {
13753{
13754 UA_TYPENAME("CertificateData") /* .memberName */
13755 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
13756 0, /* .padding */
13757 false, /* .isArray */
13758 false /* .isOptional */
13759},
13760{
13761 UA_TYPENAME("Signature") /* .memberName */
13762 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
13763 offsetof(UA_SignedSoftwareCertificate, signature) - offsetof(UA_SignedSoftwareCertificate, certificateData) - sizeof(UA_ByteString), /* .padding */
13764 false, /* .isArray */
13765 false /* .isOptional */
13766},};
13767
13768/* SessionAuthenticationToken */
13769#define SessionAuthenticationToken_members NULL
13770
13771/* SignatureData */
13772static UA_DataTypeMember SignatureData_members[2] = {
13773{
13774 UA_TYPENAME("Algorithm") /* .memberName */
13775 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13776 0, /* .padding */
13777 false, /* .isArray */
13778 false /* .isOptional */
13779},
13780{
13781 UA_TYPENAME("Signature") /* .memberName */
13782 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
13783 offsetof(UA_SignatureData, signature) - offsetof(UA_SignatureData, algorithm) - sizeof(UA_String), /* .padding */
13784 false, /* .isArray */
13785 false /* .isOptional */
13786},};
13787
13788/* CreateSessionRequest */
13789static UA_DataTypeMember CreateSessionRequest_members[9] = {
13790{
13791 UA_TYPENAME("RequestHeader") /* .memberName */
13792 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
13793 0, /* .padding */
13794 false, /* .isArray */
13795 false /* .isOptional */
13796},
13797{
13798 UA_TYPENAME("ClientDescription") /* .memberName */
13799 &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION], /* .memberType */
13800 offsetof(UA_CreateSessionRequest, clientDescription) - offsetof(UA_CreateSessionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
13801 false, /* .isArray */
13802 false /* .isOptional */
13803},
13804{
13805 UA_TYPENAME("ServerUri") /* .memberName */
13806 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13807 offsetof(UA_CreateSessionRequest, serverUri) - offsetof(UA_CreateSessionRequest, clientDescription) - sizeof(UA_ApplicationDescription), /* .padding */
13808 false, /* .isArray */
13809 false /* .isOptional */
13810},
13811{
13812 UA_TYPENAME("EndpointUrl") /* .memberName */
13813 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13814 offsetof(UA_CreateSessionRequest, endpointUrl) - offsetof(UA_CreateSessionRequest, serverUri) - sizeof(UA_String), /* .padding */
13815 false, /* .isArray */
13816 false /* .isOptional */
13817},
13818{
13819 UA_TYPENAME("SessionName") /* .memberName */
13820 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13821 offsetof(UA_CreateSessionRequest, sessionName) - offsetof(UA_CreateSessionRequest, endpointUrl) - sizeof(UA_String), /* .padding */
13822 false, /* .isArray */
13823 false /* .isOptional */
13824},
13825{
13826 UA_TYPENAME("ClientNonce") /* .memberName */
13827 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
13828 offsetof(UA_CreateSessionRequest, clientNonce) - offsetof(UA_CreateSessionRequest, sessionName) - sizeof(UA_String), /* .padding */
13829 false, /* .isArray */
13830 false /* .isOptional */
13831},
13832{
13833 UA_TYPENAME("ClientCertificate") /* .memberName */
13834 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
13835 offsetof(UA_CreateSessionRequest, clientCertificate) - offsetof(UA_CreateSessionRequest, clientNonce) - sizeof(UA_ByteString), /* .padding */
13836 false, /* .isArray */
13837 false /* .isOptional */
13838},
13839{
13840 UA_TYPENAME("RequestedSessionTimeout") /* .memberName */
13841 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
13842 offsetof(UA_CreateSessionRequest, requestedSessionTimeout) - offsetof(UA_CreateSessionRequest, clientCertificate) - sizeof(UA_ByteString), /* .padding */
13843 false, /* .isArray */
13844 false /* .isOptional */
13845},
13846{
13847 UA_TYPENAME("MaxResponseMessageSize") /* .memberName */
13848 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13849 offsetof(UA_CreateSessionRequest, maxResponseMessageSize) - offsetof(UA_CreateSessionRequest, requestedSessionTimeout) - sizeof(UA_Double), /* .padding */
13850 false, /* .isArray */
13851 false /* .isOptional */
13852},};
13853
13854/* CreateSessionResponse */
13855static UA_DataTypeMember CreateSessionResponse_members[10] = {
13856{
13857 UA_TYPENAME("ResponseHeader") /* .memberName */
13858 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
13859 0, /* .padding */
13860 false, /* .isArray */
13861 false /* .isOptional */
13862},
13863{
13864 UA_TYPENAME("SessionId") /* .memberName */
13865 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
13866 offsetof(UA_CreateSessionResponse, sessionId) - offsetof(UA_CreateSessionResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
13867 false, /* .isArray */
13868 false /* .isOptional */
13869},
13870{
13871 UA_TYPENAME("AuthenticationToken") /* .memberName */
13872 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
13873 offsetof(UA_CreateSessionResponse, authenticationToken) - offsetof(UA_CreateSessionResponse, sessionId) - sizeof(UA_NodeId), /* .padding */
13874 false, /* .isArray */
13875 false /* .isOptional */
13876},
13877{
13878 UA_TYPENAME("RevisedSessionTimeout") /* .memberName */
13879 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
13880 offsetof(UA_CreateSessionResponse, revisedSessionTimeout) - offsetof(UA_CreateSessionResponse, authenticationToken) - sizeof(UA_NodeId), /* .padding */
13881 false, /* .isArray */
13882 false /* .isOptional */
13883},
13884{
13885 UA_TYPENAME("ServerNonce") /* .memberName */
13886 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
13887 offsetof(UA_CreateSessionResponse, serverNonce) - offsetof(UA_CreateSessionResponse, revisedSessionTimeout) - sizeof(UA_Double), /* .padding */
13888 false, /* .isArray */
13889 false /* .isOptional */
13890},
13891{
13892 UA_TYPENAME("ServerCertificate") /* .memberName */
13893 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
13894 offsetof(UA_CreateSessionResponse, serverCertificate) - offsetof(UA_CreateSessionResponse, serverNonce) - sizeof(UA_ByteString), /* .padding */
13895 false, /* .isArray */
13896 false /* .isOptional */
13897},
13898{
13899 UA_TYPENAME("ServerEndpoints") /* .memberName */
13900 &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION], /* .memberType */
13901 offsetof(UA_CreateSessionResponse, serverEndpointsSize) - offsetof(UA_CreateSessionResponse, serverCertificate) - sizeof(UA_ByteString), /* .padding */
13902 true, /* .isArray */
13903 false /* .isOptional */
13904},
13905{
13906 UA_TYPENAME("ServerSoftwareCertificates") /* .memberName */
13907 &UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE], /* .memberType */
13908 offsetof(UA_CreateSessionResponse, serverSoftwareCertificatesSize) - offsetof(UA_CreateSessionResponse, serverEndpoints) - sizeof(void *), /* .padding */
13909 true, /* .isArray */
13910 false /* .isOptional */
13911},
13912{
13913 UA_TYPENAME("ServerSignature") /* .memberName */
13914 &UA_TYPES[UA_TYPES_SIGNATUREDATA], /* .memberType */
13915 offsetof(UA_CreateSessionResponse, serverSignature) - offsetof(UA_CreateSessionResponse, serverSoftwareCertificates) - sizeof(void *), /* .padding */
13916 false, /* .isArray */
13917 false /* .isOptional */
13918},
13919{
13920 UA_TYPENAME("MaxRequestMessageSize") /* .memberName */
13921 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
13922 offsetof(UA_CreateSessionResponse, maxRequestMessageSize) - offsetof(UA_CreateSessionResponse, serverSignature) - sizeof(UA_SignatureData), /* .padding */
13923 false, /* .isArray */
13924 false /* .isOptional */
13925},};
13926
13927/* UserIdentityToken */
13928static UA_DataTypeMember UserIdentityToken_members[1] = {
13929{
13930 UA_TYPENAME("PolicyId") /* .memberName */
13931 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13932 0, /* .padding */
13933 false, /* .isArray */
13934 false /* .isOptional */
13935},};
13936
13937/* AnonymousIdentityToken */
13938static UA_DataTypeMember AnonymousIdentityToken_members[1] = {
13939{
13940 UA_TYPENAME("PolicyId") /* .memberName */
13941 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13942 0, /* .padding */
13943 false, /* .isArray */
13944 false /* .isOptional */
13945},};
13946
13947/* UserNameIdentityToken */
13948static UA_DataTypeMember UserNameIdentityToken_members[4] = {
13949{
13950 UA_TYPENAME("PolicyId") /* .memberName */
13951 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13952 0, /* .padding */
13953 false, /* .isArray */
13954 false /* .isOptional */
13955},
13956{
13957 UA_TYPENAME("UserName") /* .memberName */
13958 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13959 offsetof(UA_UserNameIdentityToken, userName) - offsetof(UA_UserNameIdentityToken, policyId) - sizeof(UA_String), /* .padding */
13960 false, /* .isArray */
13961 false /* .isOptional */
13962},
13963{
13964 UA_TYPENAME("Password") /* .memberName */
13965 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
13966 offsetof(UA_UserNameIdentityToken, password) - offsetof(UA_UserNameIdentityToken, userName) - sizeof(UA_String), /* .padding */
13967 false, /* .isArray */
13968 false /* .isOptional */
13969},
13970{
13971 UA_TYPENAME("EncryptionAlgorithm") /* .memberName */
13972 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13973 offsetof(UA_UserNameIdentityToken, encryptionAlgorithm) - offsetof(UA_UserNameIdentityToken, password) - sizeof(UA_ByteString), /* .padding */
13974 false, /* .isArray */
13975 false /* .isOptional */
13976},};
13977
13978/* X509IdentityToken */
13979static UA_DataTypeMember X509IdentityToken_members[2] = {
13980{
13981 UA_TYPENAME("PolicyId") /* .memberName */
13982 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
13983 0, /* .padding */
13984 false, /* .isArray */
13985 false /* .isOptional */
13986},
13987{
13988 UA_TYPENAME("CertificateData") /* .memberName */
13989 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
13990 offsetof(UA_X509IdentityToken, certificateData) - offsetof(UA_X509IdentityToken, policyId) - sizeof(UA_String), /* .padding */
13991 false, /* .isArray */
13992 false /* .isOptional */
13993},};
13994
13995/* IssuedIdentityToken */
13996static UA_DataTypeMember IssuedIdentityToken_members[3] = {
13997{
13998 UA_TYPENAME("PolicyId") /* .memberName */
13999 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
14000 0, /* .padding */
14001 false, /* .isArray */
14002 false /* .isOptional */
14003},
14004{
14005 UA_TYPENAME("TokenData") /* .memberName */
14006 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
14007 offsetof(UA_IssuedIdentityToken, tokenData) - offsetof(UA_IssuedIdentityToken, policyId) - sizeof(UA_String), /* .padding */
14008 false, /* .isArray */
14009 false /* .isOptional */
14010},
14011{
14012 UA_TYPENAME("EncryptionAlgorithm") /* .memberName */
14013 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
14014 offsetof(UA_IssuedIdentityToken, encryptionAlgorithm) - offsetof(UA_IssuedIdentityToken, tokenData) - sizeof(UA_ByteString), /* .padding */
14015 false, /* .isArray */
14016 false /* .isOptional */
14017},};
14018
14019/* RsaEncryptedSecret */
14020#define RsaEncryptedSecret_members NULL
14021
14022/* EccEncryptedSecret */
14023#define EccEncryptedSecret_members NULL
14024
14025/* ActivateSessionRequest */
14026static UA_DataTypeMember ActivateSessionRequest_members[6] = {
14027{
14028 UA_TYPENAME("RequestHeader") /* .memberName */
14029 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
14030 0, /* .padding */
14031 false, /* .isArray */
14032 false /* .isOptional */
14033},
14034{
14035 UA_TYPENAME("ClientSignature") /* .memberName */
14036 &UA_TYPES[UA_TYPES_SIGNATUREDATA], /* .memberType */
14037 offsetof(UA_ActivateSessionRequest, clientSignature) - offsetof(UA_ActivateSessionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
14038 false, /* .isArray */
14039 false /* .isOptional */
14040},
14041{
14042 UA_TYPENAME("ClientSoftwareCertificates") /* .memberName */
14043 &UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE], /* .memberType */
14044 offsetof(UA_ActivateSessionRequest, clientSoftwareCertificatesSize) - offsetof(UA_ActivateSessionRequest, clientSignature) - sizeof(UA_SignatureData), /* .padding */
14045 true, /* .isArray */
14046 false /* .isOptional */
14047},
14048{
14049 UA_TYPENAME("LocaleIds") /* .memberName */
14050 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
14051 offsetof(UA_ActivateSessionRequest, localeIdsSize) - offsetof(UA_ActivateSessionRequest, clientSoftwareCertificates) - sizeof(void *), /* .padding */
14052 true, /* .isArray */
14053 false /* .isOptional */
14054},
14055{
14056 UA_TYPENAME("UserIdentityToken") /* .memberName */
14057 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
14058 offsetof(UA_ActivateSessionRequest, userIdentityToken) - offsetof(UA_ActivateSessionRequest, localeIds) - sizeof(void *), /* .padding */
14059 false, /* .isArray */
14060 false /* .isOptional */
14061},
14062{
14063 UA_TYPENAME("UserTokenSignature") /* .memberName */
14064 &UA_TYPES[UA_TYPES_SIGNATUREDATA], /* .memberType */
14065 offsetof(UA_ActivateSessionRequest, userTokenSignature) - offsetof(UA_ActivateSessionRequest, userIdentityToken) - sizeof(UA_ExtensionObject), /* .padding */
14066 false, /* .isArray */
14067 false /* .isOptional */
14068},};
14069
14070/* ActivateSessionResponse */
14071static UA_DataTypeMember ActivateSessionResponse_members[4] = {
14072{
14073 UA_TYPENAME("ResponseHeader") /* .memberName */
14074 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
14075 0, /* .padding */
14076 false, /* .isArray */
14077 false /* .isOptional */
14078},
14079{
14080 UA_TYPENAME("ServerNonce") /* .memberName */
14081 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
14082 offsetof(UA_ActivateSessionResponse, serverNonce) - offsetof(UA_ActivateSessionResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
14083 false, /* .isArray */
14084 false /* .isOptional */
14085},
14086{
14087 UA_TYPENAME("Results") /* .memberName */
14088 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
14089 offsetof(UA_ActivateSessionResponse, resultsSize) - offsetof(UA_ActivateSessionResponse, serverNonce) - sizeof(UA_ByteString), /* .padding */
14090 true, /* .isArray */
14091 false /* .isOptional */
14092},
14093{
14094 UA_TYPENAME("DiagnosticInfos") /* .memberName */
14095 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
14096 offsetof(UA_ActivateSessionResponse, diagnosticInfosSize) - offsetof(UA_ActivateSessionResponse, results) - sizeof(void *), /* .padding */
14097 true, /* .isArray */
14098 false /* .isOptional */
14099},};
14100
14101/* CloseSessionRequest */
14102static UA_DataTypeMember CloseSessionRequest_members[2] = {
14103{
14104 UA_TYPENAME("RequestHeader") /* .memberName */
14105 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
14106 0, /* .padding */
14107 false, /* .isArray */
14108 false /* .isOptional */
14109},
14110{
14111 UA_TYPENAME("DeleteSubscriptions") /* .memberName */
14112 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
14113 offsetof(UA_CloseSessionRequest, deleteSubscriptions) - offsetof(UA_CloseSessionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
14114 false, /* .isArray */
14115 false /* .isOptional */
14116},};
14117
14118/* CloseSessionResponse */
14119static UA_DataTypeMember CloseSessionResponse_members[1] = {
14120{
14121 UA_TYPENAME("ResponseHeader") /* .memberName */
14122 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
14123 0, /* .padding */
14124 false, /* .isArray */
14125 false /* .isOptional */
14126},};
14127
14128/* CancelRequest */
14129static UA_DataTypeMember CancelRequest_members[2] = {
14130{
14131 UA_TYPENAME("RequestHeader") /* .memberName */
14132 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
14133 0, /* .padding */
14134 false, /* .isArray */
14135 false /* .isOptional */
14136},
14137{
14138 UA_TYPENAME("RequestHandle") /* .memberName */
14139 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14140 offsetof(UA_CancelRequest, requestHandle) - offsetof(UA_CancelRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
14141 false, /* .isArray */
14142 false /* .isOptional */
14143},};
14144
14145/* CancelResponse */
14146static UA_DataTypeMember CancelResponse_members[2] = {
14147{
14148 UA_TYPENAME("ResponseHeader") /* .memberName */
14149 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
14150 0, /* .padding */
14151 false, /* .isArray */
14152 false /* .isOptional */
14153},
14154{
14155 UA_TYPENAME("CancelCount") /* .memberName */
14156 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14157 offsetof(UA_CancelResponse, cancelCount) - offsetof(UA_CancelResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
14158 false, /* .isArray */
14159 false /* .isOptional */
14160},};
14161
14162/* NodeAttributesMask */
14163#define NodeAttributesMask_members NULL
14164
14165/* NodeAttributes */
14166static UA_DataTypeMember NodeAttributes_members[5] = {
14167{
14168 UA_TYPENAME("SpecifiedAttributes") /* .memberName */
14169 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14170 0, /* .padding */
14171 false, /* .isArray */
14172 false /* .isOptional */
14173},
14174{
14175 UA_TYPENAME("DisplayName") /* .memberName */
14176 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14177 offsetof(UA_NodeAttributes, displayName) - offsetof(UA_NodeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */
14178 false, /* .isArray */
14179 false /* .isOptional */
14180},
14181{
14182 UA_TYPENAME("Description") /* .memberName */
14183 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14184 offsetof(UA_NodeAttributes, description) - offsetof(UA_NodeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */
14185 false, /* .isArray */
14186 false /* .isOptional */
14187},
14188{
14189 UA_TYPENAME("WriteMask") /* .memberName */
14190 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14191 offsetof(UA_NodeAttributes, writeMask) - offsetof(UA_NodeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */
14192 false, /* .isArray */
14193 false /* .isOptional */
14194},
14195{
14196 UA_TYPENAME("UserWriteMask") /* .memberName */
14197 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14198 offsetof(UA_NodeAttributes, userWriteMask) - offsetof(UA_NodeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */
14199 false, /* .isArray */
14200 false /* .isOptional */
14201},};
14202
14203/* ObjectAttributes */
14204static UA_DataTypeMember ObjectAttributes_members[6] = {
14205{
14206 UA_TYPENAME("SpecifiedAttributes") /* .memberName */
14207 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14208 0, /* .padding */
14209 false, /* .isArray */
14210 false /* .isOptional */
14211},
14212{
14213 UA_TYPENAME("DisplayName") /* .memberName */
14214 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14215 offsetof(UA_ObjectAttributes, displayName) - offsetof(UA_ObjectAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */
14216 false, /* .isArray */
14217 false /* .isOptional */
14218},
14219{
14220 UA_TYPENAME("Description") /* .memberName */
14221 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14222 offsetof(UA_ObjectAttributes, description) - offsetof(UA_ObjectAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */
14223 false, /* .isArray */
14224 false /* .isOptional */
14225},
14226{
14227 UA_TYPENAME("WriteMask") /* .memberName */
14228 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14229 offsetof(UA_ObjectAttributes, writeMask) - offsetof(UA_ObjectAttributes, description) - sizeof(UA_LocalizedText), /* .padding */
14230 false, /* .isArray */
14231 false /* .isOptional */
14232},
14233{
14234 UA_TYPENAME("UserWriteMask") /* .memberName */
14235 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14236 offsetof(UA_ObjectAttributes, userWriteMask) - offsetof(UA_ObjectAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */
14237 false, /* .isArray */
14238 false /* .isOptional */
14239},
14240{
14241 UA_TYPENAME("EventNotifier") /* .memberName */
14242 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
14243 offsetof(UA_ObjectAttributes, eventNotifier) - offsetof(UA_ObjectAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */
14244 false, /* .isArray */
14245 false /* .isOptional */
14246},};
14247
14248/* VariableAttributes */
14249static UA_DataTypeMember VariableAttributes_members[13] = {
14250{
14251 UA_TYPENAME("SpecifiedAttributes") /* .memberName */
14252 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14253 0, /* .padding */
14254 false, /* .isArray */
14255 false /* .isOptional */
14256},
14257{
14258 UA_TYPENAME("DisplayName") /* .memberName */
14259 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14260 offsetof(UA_VariableAttributes, displayName) - offsetof(UA_VariableAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */
14261 false, /* .isArray */
14262 false /* .isOptional */
14263},
14264{
14265 UA_TYPENAME("Description") /* .memberName */
14266 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14267 offsetof(UA_VariableAttributes, description) - offsetof(UA_VariableAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */
14268 false, /* .isArray */
14269 false /* .isOptional */
14270},
14271{
14272 UA_TYPENAME("WriteMask") /* .memberName */
14273 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14274 offsetof(UA_VariableAttributes, writeMask) - offsetof(UA_VariableAttributes, description) - sizeof(UA_LocalizedText), /* .padding */
14275 false, /* .isArray */
14276 false /* .isOptional */
14277},
14278{
14279 UA_TYPENAME("UserWriteMask") /* .memberName */
14280 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14281 offsetof(UA_VariableAttributes, userWriteMask) - offsetof(UA_VariableAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */
14282 false, /* .isArray */
14283 false /* .isOptional */
14284},
14285{
14286 UA_TYPENAME("Value") /* .memberName */
14287 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
14288 offsetof(UA_VariableAttributes, value) - offsetof(UA_VariableAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */
14289 false, /* .isArray */
14290 false /* .isOptional */
14291},
14292{
14293 UA_TYPENAME("DataType") /* .memberName */
14294 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
14295 offsetof(UA_VariableAttributes, dataType) - offsetof(UA_VariableAttributes, value) - sizeof(UA_Variant), /* .padding */
14296 false, /* .isArray */
14297 false /* .isOptional */
14298},
14299{
14300 UA_TYPENAME("ValueRank") /* .memberName */
14301 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
14302 offsetof(UA_VariableAttributes, valueRank) - offsetof(UA_VariableAttributes, dataType) - sizeof(UA_NodeId), /* .padding */
14303 false, /* .isArray */
14304 false /* .isOptional */
14305},
14306{
14307 UA_TYPENAME("ArrayDimensions") /* .memberName */
14308 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14309 offsetof(UA_VariableAttributes, arrayDimensionsSize) - offsetof(UA_VariableAttributes, valueRank) - sizeof(UA_Int32), /* .padding */
14310 true, /* .isArray */
14311 false /* .isOptional */
14312},
14313{
14314 UA_TYPENAME("AccessLevel") /* .memberName */
14315 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
14316 offsetof(UA_VariableAttributes, accessLevel) - offsetof(UA_VariableAttributes, arrayDimensions) - sizeof(void *), /* .padding */
14317 false, /* .isArray */
14318 false /* .isOptional */
14319},
14320{
14321 UA_TYPENAME("UserAccessLevel") /* .memberName */
14322 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
14323 offsetof(UA_VariableAttributes, userAccessLevel) - offsetof(UA_VariableAttributes, accessLevel) - sizeof(UA_Byte), /* .padding */
14324 false, /* .isArray */
14325 false /* .isOptional */
14326},
14327{
14328 UA_TYPENAME("MinimumSamplingInterval") /* .memberName */
14329 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
14330 offsetof(UA_VariableAttributes, minimumSamplingInterval) - offsetof(UA_VariableAttributes, userAccessLevel) - sizeof(UA_Byte), /* .padding */
14331 false, /* .isArray */
14332 false /* .isOptional */
14333},
14334{
14335 UA_TYPENAME("Historizing") /* .memberName */
14336 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
14337 offsetof(UA_VariableAttributes, historizing) - offsetof(UA_VariableAttributes, minimumSamplingInterval) - sizeof(UA_Double), /* .padding */
14338 false, /* .isArray */
14339 false /* .isOptional */
14340},};
14341
14342/* MethodAttributes */
14343static UA_DataTypeMember MethodAttributes_members[7] = {
14344{
14345 UA_TYPENAME("SpecifiedAttributes") /* .memberName */
14346 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14347 0, /* .padding */
14348 false, /* .isArray */
14349 false /* .isOptional */
14350},
14351{
14352 UA_TYPENAME("DisplayName") /* .memberName */
14353 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14354 offsetof(UA_MethodAttributes, displayName) - offsetof(UA_MethodAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */
14355 false, /* .isArray */
14356 false /* .isOptional */
14357},
14358{
14359 UA_TYPENAME("Description") /* .memberName */
14360 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14361 offsetof(UA_MethodAttributes, description) - offsetof(UA_MethodAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */
14362 false, /* .isArray */
14363 false /* .isOptional */
14364},
14365{
14366 UA_TYPENAME("WriteMask") /* .memberName */
14367 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14368 offsetof(UA_MethodAttributes, writeMask) - offsetof(UA_MethodAttributes, description) - sizeof(UA_LocalizedText), /* .padding */
14369 false, /* .isArray */
14370 false /* .isOptional */
14371},
14372{
14373 UA_TYPENAME("UserWriteMask") /* .memberName */
14374 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14375 offsetof(UA_MethodAttributes, userWriteMask) - offsetof(UA_MethodAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */
14376 false, /* .isArray */
14377 false /* .isOptional */
14378},
14379{
14380 UA_TYPENAME("Executable") /* .memberName */
14381 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
14382 offsetof(UA_MethodAttributes, executable) - offsetof(UA_MethodAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */
14383 false, /* .isArray */
14384 false /* .isOptional */
14385},
14386{
14387 UA_TYPENAME("UserExecutable") /* .memberName */
14388 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
14389 offsetof(UA_MethodAttributes, userExecutable) - offsetof(UA_MethodAttributes, executable) - sizeof(UA_Boolean), /* .padding */
14390 false, /* .isArray */
14391 false /* .isOptional */
14392},};
14393
14394/* ObjectTypeAttributes */
14395static UA_DataTypeMember ObjectTypeAttributes_members[6] = {
14396{
14397 UA_TYPENAME("SpecifiedAttributes") /* .memberName */
14398 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14399 0, /* .padding */
14400 false, /* .isArray */
14401 false /* .isOptional */
14402},
14403{
14404 UA_TYPENAME("DisplayName") /* .memberName */
14405 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14406 offsetof(UA_ObjectTypeAttributes, displayName) - offsetof(UA_ObjectTypeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */
14407 false, /* .isArray */
14408 false /* .isOptional */
14409},
14410{
14411 UA_TYPENAME("Description") /* .memberName */
14412 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14413 offsetof(UA_ObjectTypeAttributes, description) - offsetof(UA_ObjectTypeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */
14414 false, /* .isArray */
14415 false /* .isOptional */
14416},
14417{
14418 UA_TYPENAME("WriteMask") /* .memberName */
14419 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14420 offsetof(UA_ObjectTypeAttributes, writeMask) - offsetof(UA_ObjectTypeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */
14421 false, /* .isArray */
14422 false /* .isOptional */
14423},
14424{
14425 UA_TYPENAME("UserWriteMask") /* .memberName */
14426 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14427 offsetof(UA_ObjectTypeAttributes, userWriteMask) - offsetof(UA_ObjectTypeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */
14428 false, /* .isArray */
14429 false /* .isOptional */
14430},
14431{
14432 UA_TYPENAME("IsAbstract") /* .memberName */
14433 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
14434 offsetof(UA_ObjectTypeAttributes, isAbstract) - offsetof(UA_ObjectTypeAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */
14435 false, /* .isArray */
14436 false /* .isOptional */
14437},};
14438
14439/* VariableTypeAttributes */
14440static UA_DataTypeMember VariableTypeAttributes_members[10] = {
14441{
14442 UA_TYPENAME("SpecifiedAttributes") /* .memberName */
14443 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14444 0, /* .padding */
14445 false, /* .isArray */
14446 false /* .isOptional */
14447},
14448{
14449 UA_TYPENAME("DisplayName") /* .memberName */
14450 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14451 offsetof(UA_VariableTypeAttributes, displayName) - offsetof(UA_VariableTypeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */
14452 false, /* .isArray */
14453 false /* .isOptional */
14454},
14455{
14456 UA_TYPENAME("Description") /* .memberName */
14457 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14458 offsetof(UA_VariableTypeAttributes, description) - offsetof(UA_VariableTypeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */
14459 false, /* .isArray */
14460 false /* .isOptional */
14461},
14462{
14463 UA_TYPENAME("WriteMask") /* .memberName */
14464 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14465 offsetof(UA_VariableTypeAttributes, writeMask) - offsetof(UA_VariableTypeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */
14466 false, /* .isArray */
14467 false /* .isOptional */
14468},
14469{
14470 UA_TYPENAME("UserWriteMask") /* .memberName */
14471 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14472 offsetof(UA_VariableTypeAttributes, userWriteMask) - offsetof(UA_VariableTypeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */
14473 false, /* .isArray */
14474 false /* .isOptional */
14475},
14476{
14477 UA_TYPENAME("Value") /* .memberName */
14478 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
14479 offsetof(UA_VariableTypeAttributes, value) - offsetof(UA_VariableTypeAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */
14480 false, /* .isArray */
14481 false /* .isOptional */
14482},
14483{
14484 UA_TYPENAME("DataType") /* .memberName */
14485 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
14486 offsetof(UA_VariableTypeAttributes, dataType) - offsetof(UA_VariableTypeAttributes, value) - sizeof(UA_Variant), /* .padding */
14487 false, /* .isArray */
14488 false /* .isOptional */
14489},
14490{
14491 UA_TYPENAME("ValueRank") /* .memberName */
14492 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
14493 offsetof(UA_VariableTypeAttributes, valueRank) - offsetof(UA_VariableTypeAttributes, dataType) - sizeof(UA_NodeId), /* .padding */
14494 false, /* .isArray */
14495 false /* .isOptional */
14496},
14497{
14498 UA_TYPENAME("ArrayDimensions") /* .memberName */
14499 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14500 offsetof(UA_VariableTypeAttributes, arrayDimensionsSize) - offsetof(UA_VariableTypeAttributes, valueRank) - sizeof(UA_Int32), /* .padding */
14501 true, /* .isArray */
14502 false /* .isOptional */
14503},
14504{
14505 UA_TYPENAME("IsAbstract") /* .memberName */
14506 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
14507 offsetof(UA_VariableTypeAttributes, isAbstract) - offsetof(UA_VariableTypeAttributes, arrayDimensions) - sizeof(void *), /* .padding */
14508 false, /* .isArray */
14509 false /* .isOptional */
14510},};
14511
14512/* ReferenceTypeAttributes */
14513static UA_DataTypeMember ReferenceTypeAttributes_members[8] = {
14514{
14515 UA_TYPENAME("SpecifiedAttributes") /* .memberName */
14516 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14517 0, /* .padding */
14518 false, /* .isArray */
14519 false /* .isOptional */
14520},
14521{
14522 UA_TYPENAME("DisplayName") /* .memberName */
14523 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14524 offsetof(UA_ReferenceTypeAttributes, displayName) - offsetof(UA_ReferenceTypeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */
14525 false, /* .isArray */
14526 false /* .isOptional */
14527},
14528{
14529 UA_TYPENAME("Description") /* .memberName */
14530 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14531 offsetof(UA_ReferenceTypeAttributes, description) - offsetof(UA_ReferenceTypeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */
14532 false, /* .isArray */
14533 false /* .isOptional */
14534},
14535{
14536 UA_TYPENAME("WriteMask") /* .memberName */
14537 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14538 offsetof(UA_ReferenceTypeAttributes, writeMask) - offsetof(UA_ReferenceTypeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */
14539 false, /* .isArray */
14540 false /* .isOptional */
14541},
14542{
14543 UA_TYPENAME("UserWriteMask") /* .memberName */
14544 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14545 offsetof(UA_ReferenceTypeAttributes, userWriteMask) - offsetof(UA_ReferenceTypeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */
14546 false, /* .isArray */
14547 false /* .isOptional */
14548},
14549{
14550 UA_TYPENAME("IsAbstract") /* .memberName */
14551 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
14552 offsetof(UA_ReferenceTypeAttributes, isAbstract) - offsetof(UA_ReferenceTypeAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */
14553 false, /* .isArray */
14554 false /* .isOptional */
14555},
14556{
14557 UA_TYPENAME("Symmetric") /* .memberName */
14558 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
14559 offsetof(UA_ReferenceTypeAttributes, symmetric) - offsetof(UA_ReferenceTypeAttributes, isAbstract) - sizeof(UA_Boolean), /* .padding */
14560 false, /* .isArray */
14561 false /* .isOptional */
14562},
14563{
14564 UA_TYPENAME("InverseName") /* .memberName */
14565 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14566 offsetof(UA_ReferenceTypeAttributes, inverseName) - offsetof(UA_ReferenceTypeAttributes, symmetric) - sizeof(UA_Boolean), /* .padding */
14567 false, /* .isArray */
14568 false /* .isOptional */
14569},};
14570
14571/* DataTypeAttributes */
14572static UA_DataTypeMember DataTypeAttributes_members[6] = {
14573{
14574 UA_TYPENAME("SpecifiedAttributes") /* .memberName */
14575 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14576 0, /* .padding */
14577 false, /* .isArray */
14578 false /* .isOptional */
14579},
14580{
14581 UA_TYPENAME("DisplayName") /* .memberName */
14582 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14583 offsetof(UA_DataTypeAttributes, displayName) - offsetof(UA_DataTypeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */
14584 false, /* .isArray */
14585 false /* .isOptional */
14586},
14587{
14588 UA_TYPENAME("Description") /* .memberName */
14589 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14590 offsetof(UA_DataTypeAttributes, description) - offsetof(UA_DataTypeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */
14591 false, /* .isArray */
14592 false /* .isOptional */
14593},
14594{
14595 UA_TYPENAME("WriteMask") /* .memberName */
14596 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14597 offsetof(UA_DataTypeAttributes, writeMask) - offsetof(UA_DataTypeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */
14598 false, /* .isArray */
14599 false /* .isOptional */
14600},
14601{
14602 UA_TYPENAME("UserWriteMask") /* .memberName */
14603 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14604 offsetof(UA_DataTypeAttributes, userWriteMask) - offsetof(UA_DataTypeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */
14605 false, /* .isArray */
14606 false /* .isOptional */
14607},
14608{
14609 UA_TYPENAME("IsAbstract") /* .memberName */
14610 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
14611 offsetof(UA_DataTypeAttributes, isAbstract) - offsetof(UA_DataTypeAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */
14612 false, /* .isArray */
14613 false /* .isOptional */
14614},};
14615
14616/* ViewAttributes */
14617static UA_DataTypeMember ViewAttributes_members[7] = {
14618{
14619 UA_TYPENAME("SpecifiedAttributes") /* .memberName */
14620 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14621 0, /* .padding */
14622 false, /* .isArray */
14623 false /* .isOptional */
14624},
14625{
14626 UA_TYPENAME("DisplayName") /* .memberName */
14627 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14628 offsetof(UA_ViewAttributes, displayName) - offsetof(UA_ViewAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */
14629 false, /* .isArray */
14630 false /* .isOptional */
14631},
14632{
14633 UA_TYPENAME("Description") /* .memberName */
14634 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14635 offsetof(UA_ViewAttributes, description) - offsetof(UA_ViewAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */
14636 false, /* .isArray */
14637 false /* .isOptional */
14638},
14639{
14640 UA_TYPENAME("WriteMask") /* .memberName */
14641 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14642 offsetof(UA_ViewAttributes, writeMask) - offsetof(UA_ViewAttributes, description) - sizeof(UA_LocalizedText), /* .padding */
14643 false, /* .isArray */
14644 false /* .isOptional */
14645},
14646{
14647 UA_TYPENAME("UserWriteMask") /* .memberName */
14648 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14649 offsetof(UA_ViewAttributes, userWriteMask) - offsetof(UA_ViewAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */
14650 false, /* .isArray */
14651 false /* .isOptional */
14652},
14653{
14654 UA_TYPENAME("ContainsNoLoops") /* .memberName */
14655 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
14656 offsetof(UA_ViewAttributes, containsNoLoops) - offsetof(UA_ViewAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */
14657 false, /* .isArray */
14658 false /* .isOptional */
14659},
14660{
14661 UA_TYPENAME("EventNotifier") /* .memberName */
14662 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
14663 offsetof(UA_ViewAttributes, eventNotifier) - offsetof(UA_ViewAttributes, containsNoLoops) - sizeof(UA_Boolean), /* .padding */
14664 false, /* .isArray */
14665 false /* .isOptional */
14666},};
14667
14668/* GenericAttributeValue */
14669static UA_DataTypeMember GenericAttributeValue_members[2] = {
14670{
14671 UA_TYPENAME("AttributeId") /* .memberName */
14672 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14673 0, /* .padding */
14674 false, /* .isArray */
14675 false /* .isOptional */
14676},
14677{
14678 UA_TYPENAME("Value") /* .memberName */
14679 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
14680 offsetof(UA_GenericAttributeValue, value) - offsetof(UA_GenericAttributeValue, attributeId) - sizeof(UA_UInt32), /* .padding */
14681 false, /* .isArray */
14682 false /* .isOptional */
14683},};
14684
14685/* GenericAttributes */
14686static UA_DataTypeMember GenericAttributes_members[6] = {
14687{
14688 UA_TYPENAME("SpecifiedAttributes") /* .memberName */
14689 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14690 0, /* .padding */
14691 false, /* .isArray */
14692 false /* .isOptional */
14693},
14694{
14695 UA_TYPENAME("DisplayName") /* .memberName */
14696 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14697 offsetof(UA_GenericAttributes, displayName) - offsetof(UA_GenericAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */
14698 false, /* .isArray */
14699 false /* .isOptional */
14700},
14701{
14702 UA_TYPENAME("Description") /* .memberName */
14703 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
14704 offsetof(UA_GenericAttributes, description) - offsetof(UA_GenericAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */
14705 false, /* .isArray */
14706 false /* .isOptional */
14707},
14708{
14709 UA_TYPENAME("WriteMask") /* .memberName */
14710 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14711 offsetof(UA_GenericAttributes, writeMask) - offsetof(UA_GenericAttributes, description) - sizeof(UA_LocalizedText), /* .padding */
14712 false, /* .isArray */
14713 false /* .isOptional */
14714},
14715{
14716 UA_TYPENAME("UserWriteMask") /* .memberName */
14717 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
14718 offsetof(UA_GenericAttributes, userWriteMask) - offsetof(UA_GenericAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */
14719 false, /* .isArray */
14720 false /* .isOptional */
14721},
14722{
14723 UA_TYPENAME("AttributeValues") /* .memberName */
14724 &UA_TYPES[UA_TYPES_GENERICATTRIBUTEVALUE], /* .memberType */
14725 offsetof(UA_GenericAttributes, attributeValuesSize) - offsetof(UA_GenericAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */
14726 true, /* .isArray */
14727 false /* .isOptional */
14728},};
14729
14730/* AddNodesItem */
14731static UA_DataTypeMember AddNodesItem_members[7] = {
14732{
14733 UA_TYPENAME("ParentNodeId") /* .memberName */
14734 &UA_TYPES[UA_TYPES_EXPANDEDNODEID], /* .memberType */
14735 0, /* .padding */
14736 false, /* .isArray */
14737 false /* .isOptional */
14738},
14739{
14740 UA_TYPENAME("ReferenceTypeId") /* .memberName */
14741 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
14742 offsetof(UA_AddNodesItem, referenceTypeId) - offsetof(UA_AddNodesItem, parentNodeId) - sizeof(UA_ExpandedNodeId), /* .padding */
14743 false, /* .isArray */
14744 false /* .isOptional */
14745},
14746{
14747 UA_TYPENAME("RequestedNewNodeId") /* .memberName */
14748 &UA_TYPES[UA_TYPES_EXPANDEDNODEID], /* .memberType */
14749 offsetof(UA_AddNodesItem, requestedNewNodeId) - offsetof(UA_AddNodesItem, referenceTypeId) - sizeof(UA_NodeId), /* .padding */
14750 false, /* .isArray */
14751 false /* .isOptional */
14752},
14753{
14754 UA_TYPENAME("BrowseName") /* .memberName */
14755 &UA_TYPES[UA_TYPES_QUALIFIEDNAME], /* .memberType */
14756 offsetof(UA_AddNodesItem, browseName) - offsetof(UA_AddNodesItem, requestedNewNodeId) - sizeof(UA_ExpandedNodeId), /* .padding */
14757 false, /* .isArray */
14758 false /* .isOptional */
14759},
14760{
14761 UA_TYPENAME("NodeClass") /* .memberName */
14762 &UA_TYPES[UA_TYPES_NODECLASS], /* .memberType */
14763 offsetof(UA_AddNodesItem, nodeClass) - offsetof(UA_AddNodesItem, browseName) - sizeof(UA_QualifiedName), /* .padding */
14764 false, /* .isArray */
14765 false /* .isOptional */
14766},
14767{
14768 UA_TYPENAME("NodeAttributes") /* .memberName */
14769 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
14770 offsetof(UA_AddNodesItem, nodeAttributes) - offsetof(UA_AddNodesItem, nodeClass) - sizeof(UA_NodeClass), /* .padding */
14771 false, /* .isArray */
14772 false /* .isOptional */
14773},
14774{
14775 UA_TYPENAME("TypeDefinition") /* .memberName */
14776 &UA_TYPES[UA_TYPES_EXPANDEDNODEID], /* .memberType */
14777 offsetof(UA_AddNodesItem, typeDefinition) - offsetof(UA_AddNodesItem, nodeAttributes) - sizeof(UA_ExtensionObject), /* .padding */
14778 false, /* .isArray */
14779 false /* .isOptional */
14780},};
14781
14782/* AddNodesResult */
14783static UA_DataTypeMember AddNodesResult_members[2] = {
14784{
14785 UA_TYPENAME("StatusCode") /* .memberName */
14786 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
14787 0, /* .padding */
14788 false, /* .isArray */
14789 false /* .isOptional */
14790},
14791{
14792 UA_TYPENAME("AddedNodeId") /* .memberName */
14793 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
14794 offsetof(UA_AddNodesResult, addedNodeId) - offsetof(UA_AddNodesResult, statusCode) - sizeof(UA_StatusCode), /* .padding */
14795 false, /* .isArray */
14796 false /* .isOptional */
14797},};
14798
14799/* AddNodesRequest */
14800static UA_DataTypeMember AddNodesRequest_members[2] = {
14801{
14802 UA_TYPENAME("RequestHeader") /* .memberName */
14803 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
14804 0, /* .padding */
14805 false, /* .isArray */
14806 false /* .isOptional */
14807},
14808{
14809 UA_TYPENAME("NodesToAdd") /* .memberName */
14810 &UA_TYPES[UA_TYPES_ADDNODESITEM], /* .memberType */
14811 offsetof(UA_AddNodesRequest, nodesToAddSize) - offsetof(UA_AddNodesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
14812 true, /* .isArray */
14813 false /* .isOptional */
14814},};
14815
14816/* AddNodesResponse */
14817static UA_DataTypeMember AddNodesResponse_members[3] = {
14818{
14819 UA_TYPENAME("ResponseHeader") /* .memberName */
14820 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
14821 0, /* .padding */
14822 false, /* .isArray */
14823 false /* .isOptional */
14824},
14825{
14826 UA_TYPENAME("Results") /* .memberName */
14827 &UA_TYPES[UA_TYPES_ADDNODESRESULT], /* .memberType */
14828 offsetof(UA_AddNodesResponse, resultsSize) - offsetof(UA_AddNodesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
14829 true, /* .isArray */
14830 false /* .isOptional */
14831},
14832{
14833 UA_TYPENAME("DiagnosticInfos") /* .memberName */
14834 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
14835 offsetof(UA_AddNodesResponse, diagnosticInfosSize) - offsetof(UA_AddNodesResponse, results) - sizeof(void *), /* .padding */
14836 true, /* .isArray */
14837 false /* .isOptional */
14838},};
14839
14840/* AddReferencesItem */
14841static UA_DataTypeMember AddReferencesItem_members[6] = {
14842{
14843 UA_TYPENAME("SourceNodeId") /* .memberName */
14844 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
14845 0, /* .padding */
14846 false, /* .isArray */
14847 false /* .isOptional */
14848},
14849{
14850 UA_TYPENAME("ReferenceTypeId") /* .memberName */
14851 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
14852 offsetof(UA_AddReferencesItem, referenceTypeId) - offsetof(UA_AddReferencesItem, sourceNodeId) - sizeof(UA_NodeId), /* .padding */
14853 false, /* .isArray */
14854 false /* .isOptional */
14855},
14856{
14857 UA_TYPENAME("IsForward") /* .memberName */
14858 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
14859 offsetof(UA_AddReferencesItem, isForward) - offsetof(UA_AddReferencesItem, referenceTypeId) - sizeof(UA_NodeId), /* .padding */
14860 false, /* .isArray */
14861 false /* .isOptional */
14862},
14863{
14864 UA_TYPENAME("TargetServerUri") /* .memberName */
14865 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
14866 offsetof(UA_AddReferencesItem, targetServerUri) - offsetof(UA_AddReferencesItem, isForward) - sizeof(UA_Boolean), /* .padding */
14867 false, /* .isArray */
14868 false /* .isOptional */
14869},
14870{
14871 UA_TYPENAME("TargetNodeId") /* .memberName */
14872 &UA_TYPES[UA_TYPES_EXPANDEDNODEID], /* .memberType */
14873 offsetof(UA_AddReferencesItem, targetNodeId) - offsetof(UA_AddReferencesItem, targetServerUri) - sizeof(UA_String), /* .padding */
14874 false, /* .isArray */
14875 false /* .isOptional */
14876},
14877{
14878 UA_TYPENAME("TargetNodeClass") /* .memberName */
14879 &UA_TYPES[UA_TYPES_NODECLASS], /* .memberType */
14880 offsetof(UA_AddReferencesItem, targetNodeClass) - offsetof(UA_AddReferencesItem, targetNodeId) - sizeof(UA_ExpandedNodeId), /* .padding */
14881 false, /* .isArray */
14882 false /* .isOptional */
14883},};
14884
14885/* AddReferencesRequest */
14886static UA_DataTypeMember AddReferencesRequest_members[2] = {
14887{
14888 UA_TYPENAME("RequestHeader") /* .memberName */
14889 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
14890 0, /* .padding */
14891 false, /* .isArray */
14892 false /* .isOptional */
14893},
14894{
14895 UA_TYPENAME("ReferencesToAdd") /* .memberName */
14896 &UA_TYPES[UA_TYPES_ADDREFERENCESITEM], /* .memberType */
14897 offsetof(UA_AddReferencesRequest, referencesToAddSize) - offsetof(UA_AddReferencesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
14898 true, /* .isArray */
14899 false /* .isOptional */
14900},};
14901
14902/* AddReferencesResponse */
14903static UA_DataTypeMember AddReferencesResponse_members[3] = {
14904{
14905 UA_TYPENAME("ResponseHeader") /* .memberName */
14906 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
14907 0, /* .padding */
14908 false, /* .isArray */
14909 false /* .isOptional */
14910},
14911{
14912 UA_TYPENAME("Results") /* .memberName */
14913 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
14914 offsetof(UA_AddReferencesResponse, resultsSize) - offsetof(UA_AddReferencesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
14915 true, /* .isArray */
14916 false /* .isOptional */
14917},
14918{
14919 UA_TYPENAME("DiagnosticInfos") /* .memberName */
14920 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
14921 offsetof(UA_AddReferencesResponse, diagnosticInfosSize) - offsetof(UA_AddReferencesResponse, results) - sizeof(void *), /* .padding */
14922 true, /* .isArray */
14923 false /* .isOptional */
14924},};
14925
14926/* DeleteNodesItem */
14927static UA_DataTypeMember DeleteNodesItem_members[2] = {
14928{
14929 UA_TYPENAME("NodeId") /* .memberName */
14930 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
14931 0, /* .padding */
14932 false, /* .isArray */
14933 false /* .isOptional */
14934},
14935{
14936 UA_TYPENAME("DeleteTargetReferences") /* .memberName */
14937 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
14938 offsetof(UA_DeleteNodesItem, deleteTargetReferences) - offsetof(UA_DeleteNodesItem, nodeId) - sizeof(UA_NodeId), /* .padding */
14939 false, /* .isArray */
14940 false /* .isOptional */
14941},};
14942
14943/* DeleteNodesRequest */
14944static UA_DataTypeMember DeleteNodesRequest_members[2] = {
14945{
14946 UA_TYPENAME("RequestHeader") /* .memberName */
14947 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
14948 0, /* .padding */
14949 false, /* .isArray */
14950 false /* .isOptional */
14951},
14952{
14953 UA_TYPENAME("NodesToDelete") /* .memberName */
14954 &UA_TYPES[UA_TYPES_DELETENODESITEM], /* .memberType */
14955 offsetof(UA_DeleteNodesRequest, nodesToDeleteSize) - offsetof(UA_DeleteNodesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
14956 true, /* .isArray */
14957 false /* .isOptional */
14958},};
14959
14960/* DeleteNodesResponse */
14961static UA_DataTypeMember DeleteNodesResponse_members[3] = {
14962{
14963 UA_TYPENAME("ResponseHeader") /* .memberName */
14964 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
14965 0, /* .padding */
14966 false, /* .isArray */
14967 false /* .isOptional */
14968},
14969{
14970 UA_TYPENAME("Results") /* .memberName */
14971 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
14972 offsetof(UA_DeleteNodesResponse, resultsSize) - offsetof(UA_DeleteNodesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
14973 true, /* .isArray */
14974 false /* .isOptional */
14975},
14976{
14977 UA_TYPENAME("DiagnosticInfos") /* .memberName */
14978 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
14979 offsetof(UA_DeleteNodesResponse, diagnosticInfosSize) - offsetof(UA_DeleteNodesResponse, results) - sizeof(void *), /* .padding */
14980 true, /* .isArray */
14981 false /* .isOptional */
14982},};
14983
14984/* DeleteReferencesItem */
14985static UA_DataTypeMember DeleteReferencesItem_members[5] = {
14986{
14987 UA_TYPENAME("SourceNodeId") /* .memberName */
14988 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
14989 0, /* .padding */
14990 false, /* .isArray */
14991 false /* .isOptional */
14992},
14993{
14994 UA_TYPENAME("ReferenceTypeId") /* .memberName */
14995 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
14996 offsetof(UA_DeleteReferencesItem, referenceTypeId) - offsetof(UA_DeleteReferencesItem, sourceNodeId) - sizeof(UA_NodeId), /* .padding */
14997 false, /* .isArray */
14998 false /* .isOptional */
14999},
15000{
15001 UA_TYPENAME("IsForward") /* .memberName */
15002 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
15003 offsetof(UA_DeleteReferencesItem, isForward) - offsetof(UA_DeleteReferencesItem, referenceTypeId) - sizeof(UA_NodeId), /* .padding */
15004 false, /* .isArray */
15005 false /* .isOptional */
15006},
15007{
15008 UA_TYPENAME("TargetNodeId") /* .memberName */
15009 &UA_TYPES[UA_TYPES_EXPANDEDNODEID], /* .memberType */
15010 offsetof(UA_DeleteReferencesItem, targetNodeId) - offsetof(UA_DeleteReferencesItem, isForward) - sizeof(UA_Boolean), /* .padding */
15011 false, /* .isArray */
15012 false /* .isOptional */
15013},
15014{
15015 UA_TYPENAME("DeleteBidirectional") /* .memberName */
15016 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
15017 offsetof(UA_DeleteReferencesItem, deleteBidirectional) - offsetof(UA_DeleteReferencesItem, targetNodeId) - sizeof(UA_ExpandedNodeId), /* .padding */
15018 false, /* .isArray */
15019 false /* .isOptional */
15020},};
15021
15022/* DeleteReferencesRequest */
15023static UA_DataTypeMember DeleteReferencesRequest_members[2] = {
15024{
15025 UA_TYPENAME("RequestHeader") /* .memberName */
15026 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
15027 0, /* .padding */
15028 false, /* .isArray */
15029 false /* .isOptional */
15030},
15031{
15032 UA_TYPENAME("ReferencesToDelete") /* .memberName */
15033 &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM], /* .memberType */
15034 offsetof(UA_DeleteReferencesRequest, referencesToDeleteSize) - offsetof(UA_DeleteReferencesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
15035 true, /* .isArray */
15036 false /* .isOptional */
15037},};
15038
15039/* DeleteReferencesResponse */
15040static UA_DataTypeMember DeleteReferencesResponse_members[3] = {
15041{
15042 UA_TYPENAME("ResponseHeader") /* .memberName */
15043 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
15044 0, /* .padding */
15045 false, /* .isArray */
15046 false /* .isOptional */
15047},
15048{
15049 UA_TYPENAME("Results") /* .memberName */
15050 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
15051 offsetof(UA_DeleteReferencesResponse, resultsSize) - offsetof(UA_DeleteReferencesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
15052 true, /* .isArray */
15053 false /* .isOptional */
15054},
15055{
15056 UA_TYPENAME("DiagnosticInfos") /* .memberName */
15057 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
15058 offsetof(UA_DeleteReferencesResponse, diagnosticInfosSize) - offsetof(UA_DeleteReferencesResponse, results) - sizeof(void *), /* .padding */
15059 true, /* .isArray */
15060 false /* .isOptional */
15061},};
15062
15063/* AttributeWriteMask */
15064#define AttributeWriteMask_members NULL
15065
15066/* BrowseDirection */
15067#define BrowseDirection_members NULL
15068
15069/* ViewDescription */
15070static UA_DataTypeMember ViewDescription_members[3] = {
15071{
15072 UA_TYPENAME("ViewId") /* .memberName */
15073 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15074 0, /* .padding */
15075 false, /* .isArray */
15076 false /* .isOptional */
15077},
15078{
15079 UA_TYPENAME("Timestamp") /* .memberName */
15080 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
15081 offsetof(UA_ViewDescription, timestamp) - offsetof(UA_ViewDescription, viewId) - sizeof(UA_NodeId), /* .padding */
15082 false, /* .isArray */
15083 false /* .isOptional */
15084},
15085{
15086 UA_TYPENAME("ViewVersion") /* .memberName */
15087 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
15088 offsetof(UA_ViewDescription, viewVersion) - offsetof(UA_ViewDescription, timestamp) - sizeof(UA_DateTime), /* .padding */
15089 false, /* .isArray */
15090 false /* .isOptional */
15091},};
15092
15093/* BrowseDescription */
15094static UA_DataTypeMember BrowseDescription_members[6] = {
15095{
15096 UA_TYPENAME("NodeId") /* .memberName */
15097 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15098 0, /* .padding */
15099 false, /* .isArray */
15100 false /* .isOptional */
15101},
15102{
15103 UA_TYPENAME("BrowseDirection") /* .memberName */
15104 &UA_TYPES[UA_TYPES_BROWSEDIRECTION], /* .memberType */
15105 offsetof(UA_BrowseDescription, browseDirection) - offsetof(UA_BrowseDescription, nodeId) - sizeof(UA_NodeId), /* .padding */
15106 false, /* .isArray */
15107 false /* .isOptional */
15108},
15109{
15110 UA_TYPENAME("ReferenceTypeId") /* .memberName */
15111 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15112 offsetof(UA_BrowseDescription, referenceTypeId) - offsetof(UA_BrowseDescription, browseDirection) - sizeof(UA_BrowseDirection), /* .padding */
15113 false, /* .isArray */
15114 false /* .isOptional */
15115},
15116{
15117 UA_TYPENAME("IncludeSubtypes") /* .memberName */
15118 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
15119 offsetof(UA_BrowseDescription, includeSubtypes) - offsetof(UA_BrowseDescription, referenceTypeId) - sizeof(UA_NodeId), /* .padding */
15120 false, /* .isArray */
15121 false /* .isOptional */
15122},
15123{
15124 UA_TYPENAME("NodeClassMask") /* .memberName */
15125 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
15126 offsetof(UA_BrowseDescription, nodeClassMask) - offsetof(UA_BrowseDescription, includeSubtypes) - sizeof(UA_Boolean), /* .padding */
15127 false, /* .isArray */
15128 false /* .isOptional */
15129},
15130{
15131 UA_TYPENAME("ResultMask") /* .memberName */
15132 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
15133 offsetof(UA_BrowseDescription, resultMask) - offsetof(UA_BrowseDescription, nodeClassMask) - sizeof(UA_UInt32), /* .padding */
15134 false, /* .isArray */
15135 false /* .isOptional */
15136},};
15137
15138/* BrowseResultMask */
15139#define BrowseResultMask_members NULL
15140
15141/* ReferenceDescription */
15142static UA_DataTypeMember ReferenceDescription_members[7] = {
15143{
15144 UA_TYPENAME("ReferenceTypeId") /* .memberName */
15145 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15146 0, /* .padding */
15147 false, /* .isArray */
15148 false /* .isOptional */
15149},
15150{
15151 UA_TYPENAME("IsForward") /* .memberName */
15152 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
15153 offsetof(UA_ReferenceDescription, isForward) - offsetof(UA_ReferenceDescription, referenceTypeId) - sizeof(UA_NodeId), /* .padding */
15154 false, /* .isArray */
15155 false /* .isOptional */
15156},
15157{
15158 UA_TYPENAME("NodeId") /* .memberName */
15159 &UA_TYPES[UA_TYPES_EXPANDEDNODEID], /* .memberType */
15160 offsetof(UA_ReferenceDescription, nodeId) - offsetof(UA_ReferenceDescription, isForward) - sizeof(UA_Boolean), /* .padding */
15161 false, /* .isArray */
15162 false /* .isOptional */
15163},
15164{
15165 UA_TYPENAME("BrowseName") /* .memberName */
15166 &UA_TYPES[UA_TYPES_QUALIFIEDNAME], /* .memberType */
15167 offsetof(UA_ReferenceDescription, browseName) - offsetof(UA_ReferenceDescription, nodeId) - sizeof(UA_ExpandedNodeId), /* .padding */
15168 false, /* .isArray */
15169 false /* .isOptional */
15170},
15171{
15172 UA_TYPENAME("DisplayName") /* .memberName */
15173 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
15174 offsetof(UA_ReferenceDescription, displayName) - offsetof(UA_ReferenceDescription, browseName) - sizeof(UA_QualifiedName), /* .padding */
15175 false, /* .isArray */
15176 false /* .isOptional */
15177},
15178{
15179 UA_TYPENAME("NodeClass") /* .memberName */
15180 &UA_TYPES[UA_TYPES_NODECLASS], /* .memberType */
15181 offsetof(UA_ReferenceDescription, nodeClass) - offsetof(UA_ReferenceDescription, displayName) - sizeof(UA_LocalizedText), /* .padding */
15182 false, /* .isArray */
15183 false /* .isOptional */
15184},
15185{
15186 UA_TYPENAME("TypeDefinition") /* .memberName */
15187 &UA_TYPES[UA_TYPES_EXPANDEDNODEID], /* .memberType */
15188 offsetof(UA_ReferenceDescription, typeDefinition) - offsetof(UA_ReferenceDescription, nodeClass) - sizeof(UA_NodeClass), /* .padding */
15189 false, /* .isArray */
15190 false /* .isOptional */
15191},};
15192
15193/* ContinuationPoint */
15194#define ContinuationPoint_members NULL
15195
15196/* BrowseResult */
15197static UA_DataTypeMember BrowseResult_members[3] = {
15198{
15199 UA_TYPENAME("StatusCode") /* .memberName */
15200 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
15201 0, /* .padding */
15202 false, /* .isArray */
15203 false /* .isOptional */
15204},
15205{
15206 UA_TYPENAME("ContinuationPoint") /* .memberName */
15207 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
15208 offsetof(UA_BrowseResult, continuationPoint) - offsetof(UA_BrowseResult, statusCode) - sizeof(UA_StatusCode), /* .padding */
15209 false, /* .isArray */
15210 false /* .isOptional */
15211},
15212{
15213 UA_TYPENAME("References") /* .memberName */
15214 &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION], /* .memberType */
15215 offsetof(UA_BrowseResult, referencesSize) - offsetof(UA_BrowseResult, continuationPoint) - sizeof(UA_ByteString), /* .padding */
15216 true, /* .isArray */
15217 false /* .isOptional */
15218},};
15219
15220/* BrowseRequest */
15221static UA_DataTypeMember BrowseRequest_members[4] = {
15222{
15223 UA_TYPENAME("RequestHeader") /* .memberName */
15224 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
15225 0, /* .padding */
15226 false, /* .isArray */
15227 false /* .isOptional */
15228},
15229{
15230 UA_TYPENAME("View") /* .memberName */
15231 &UA_TYPES[UA_TYPES_VIEWDESCRIPTION], /* .memberType */
15232 offsetof(UA_BrowseRequest, view) - offsetof(UA_BrowseRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
15233 false, /* .isArray */
15234 false /* .isOptional */
15235},
15236{
15237 UA_TYPENAME("RequestedMaxReferencesPerNode") /* .memberName */
15238 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
15239 offsetof(UA_BrowseRequest, requestedMaxReferencesPerNode) - offsetof(UA_BrowseRequest, view) - sizeof(UA_ViewDescription), /* .padding */
15240 false, /* .isArray */
15241 false /* .isOptional */
15242},
15243{
15244 UA_TYPENAME("NodesToBrowse") /* .memberName */
15245 &UA_TYPES[UA_TYPES_BROWSEDESCRIPTION], /* .memberType */
15246 offsetof(UA_BrowseRequest, nodesToBrowseSize) - offsetof(UA_BrowseRequest, requestedMaxReferencesPerNode) - sizeof(UA_UInt32), /* .padding */
15247 true, /* .isArray */
15248 false /* .isOptional */
15249},};
15250
15251/* BrowseResponse */
15252static UA_DataTypeMember BrowseResponse_members[3] = {
15253{
15254 UA_TYPENAME("ResponseHeader") /* .memberName */
15255 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
15256 0, /* .padding */
15257 false, /* .isArray */
15258 false /* .isOptional */
15259},
15260{
15261 UA_TYPENAME("Results") /* .memberName */
15262 &UA_TYPES[UA_TYPES_BROWSERESULT], /* .memberType */
15263 offsetof(UA_BrowseResponse, resultsSize) - offsetof(UA_BrowseResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
15264 true, /* .isArray */
15265 false /* .isOptional */
15266},
15267{
15268 UA_TYPENAME("DiagnosticInfos") /* .memberName */
15269 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
15270 offsetof(UA_BrowseResponse, diagnosticInfosSize) - offsetof(UA_BrowseResponse, results) - sizeof(void *), /* .padding */
15271 true, /* .isArray */
15272 false /* .isOptional */
15273},};
15274
15275/* BrowseNextRequest */
15276static UA_DataTypeMember BrowseNextRequest_members[3] = {
15277{
15278 UA_TYPENAME("RequestHeader") /* .memberName */
15279 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
15280 0, /* .padding */
15281 false, /* .isArray */
15282 false /* .isOptional */
15283},
15284{
15285 UA_TYPENAME("ReleaseContinuationPoints") /* .memberName */
15286 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
15287 offsetof(UA_BrowseNextRequest, releaseContinuationPoints) - offsetof(UA_BrowseNextRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
15288 false, /* .isArray */
15289 false /* .isOptional */
15290},
15291{
15292 UA_TYPENAME("ContinuationPoints") /* .memberName */
15293 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
15294 offsetof(UA_BrowseNextRequest, continuationPointsSize) - offsetof(UA_BrowseNextRequest, releaseContinuationPoints) - sizeof(UA_Boolean), /* .padding */
15295 true, /* .isArray */
15296 false /* .isOptional */
15297},};
15298
15299/* BrowseNextResponse */
15300static UA_DataTypeMember BrowseNextResponse_members[3] = {
15301{
15302 UA_TYPENAME("ResponseHeader") /* .memberName */
15303 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
15304 0, /* .padding */
15305 false, /* .isArray */
15306 false /* .isOptional */
15307},
15308{
15309 UA_TYPENAME("Results") /* .memberName */
15310 &UA_TYPES[UA_TYPES_BROWSERESULT], /* .memberType */
15311 offsetof(UA_BrowseNextResponse, resultsSize) - offsetof(UA_BrowseNextResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
15312 true, /* .isArray */
15313 false /* .isOptional */
15314},
15315{
15316 UA_TYPENAME("DiagnosticInfos") /* .memberName */
15317 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
15318 offsetof(UA_BrowseNextResponse, diagnosticInfosSize) - offsetof(UA_BrowseNextResponse, results) - sizeof(void *), /* .padding */
15319 true, /* .isArray */
15320 false /* .isOptional */
15321},};
15322
15323/* RelativePathElement */
15324static UA_DataTypeMember RelativePathElement_members[4] = {
15325{
15326 UA_TYPENAME("ReferenceTypeId") /* .memberName */
15327 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15328 0, /* .padding */
15329 false, /* .isArray */
15330 false /* .isOptional */
15331},
15332{
15333 UA_TYPENAME("IsInverse") /* .memberName */
15334 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
15335 offsetof(UA_RelativePathElement, isInverse) - offsetof(UA_RelativePathElement, referenceTypeId) - sizeof(UA_NodeId), /* .padding */
15336 false, /* .isArray */
15337 false /* .isOptional */
15338},
15339{
15340 UA_TYPENAME("IncludeSubtypes") /* .memberName */
15341 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
15342 offsetof(UA_RelativePathElement, includeSubtypes) - offsetof(UA_RelativePathElement, isInverse) - sizeof(UA_Boolean), /* .padding */
15343 false, /* .isArray */
15344 false /* .isOptional */
15345},
15346{
15347 UA_TYPENAME("TargetName") /* .memberName */
15348 &UA_TYPES[UA_TYPES_QUALIFIEDNAME], /* .memberType */
15349 offsetof(UA_RelativePathElement, targetName) - offsetof(UA_RelativePathElement, includeSubtypes) - sizeof(UA_Boolean), /* .padding */
15350 false, /* .isArray */
15351 false /* .isOptional */
15352},};
15353
15354/* RelativePath */
15355static UA_DataTypeMember RelativePath_members[1] = {
15356{
15357 UA_TYPENAME("Elements") /* .memberName */
15358 &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT], /* .memberType */
15359 0, /* .padding */
15360 true, /* .isArray */
15361 false /* .isOptional */
15362},};
15363
15364/* BrowsePath */
15365static UA_DataTypeMember BrowsePath_members[2] = {
15366{
15367 UA_TYPENAME("StartingNode") /* .memberName */
15368 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15369 0, /* .padding */
15370 false, /* .isArray */
15371 false /* .isOptional */
15372},
15373{
15374 UA_TYPENAME("RelativePath") /* .memberName */
15375 &UA_TYPES[UA_TYPES_RELATIVEPATH], /* .memberType */
15376 offsetof(UA_BrowsePath, relativePath) - offsetof(UA_BrowsePath, startingNode) - sizeof(UA_NodeId), /* .padding */
15377 false, /* .isArray */
15378 false /* .isOptional */
15379},};
15380
15381/* BrowsePathTarget */
15382static UA_DataTypeMember BrowsePathTarget_members[2] = {
15383{
15384 UA_TYPENAME("TargetId") /* .memberName */
15385 &UA_TYPES[UA_TYPES_EXPANDEDNODEID], /* .memberType */
15386 0, /* .padding */
15387 false, /* .isArray */
15388 false /* .isOptional */
15389},
15390{
15391 UA_TYPENAME("RemainingPathIndex") /* .memberName */
15392 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
15393 offsetof(UA_BrowsePathTarget, remainingPathIndex) - offsetof(UA_BrowsePathTarget, targetId) - sizeof(UA_ExpandedNodeId), /* .padding */
15394 false, /* .isArray */
15395 false /* .isOptional */
15396},};
15397
15398/* BrowsePathResult */
15399static UA_DataTypeMember BrowsePathResult_members[2] = {
15400{
15401 UA_TYPENAME("StatusCode") /* .memberName */
15402 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
15403 0, /* .padding */
15404 false, /* .isArray */
15405 false /* .isOptional */
15406},
15407{
15408 UA_TYPENAME("Targets") /* .memberName */
15409 &UA_TYPES[UA_TYPES_BROWSEPATHTARGET], /* .memberType */
15410 offsetof(UA_BrowsePathResult, targetsSize) - offsetof(UA_BrowsePathResult, statusCode) - sizeof(UA_StatusCode), /* .padding */
15411 true, /* .isArray */
15412 false /* .isOptional */
15413},};
15414
15415/* TranslateBrowsePathsToNodeIdsRequest */
15416static UA_DataTypeMember TranslateBrowsePathsToNodeIdsRequest_members[2] = {
15417{
15418 UA_TYPENAME("RequestHeader") /* .memberName */
15419 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
15420 0, /* .padding */
15421 false, /* .isArray */
15422 false /* .isOptional */
15423},
15424{
15425 UA_TYPENAME("BrowsePaths") /* .memberName */
15426 &UA_TYPES[UA_TYPES_BROWSEPATH], /* .memberType */
15427 offsetof(UA_TranslateBrowsePathsToNodeIdsRequest, browsePathsSize) - offsetof(UA_TranslateBrowsePathsToNodeIdsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
15428 true, /* .isArray */
15429 false /* .isOptional */
15430},};
15431
15432/* TranslateBrowsePathsToNodeIdsResponse */
15433static UA_DataTypeMember TranslateBrowsePathsToNodeIdsResponse_members[3] = {
15434{
15435 UA_TYPENAME("ResponseHeader") /* .memberName */
15436 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
15437 0, /* .padding */
15438 false, /* .isArray */
15439 false /* .isOptional */
15440},
15441{
15442 UA_TYPENAME("Results") /* .memberName */
15443 &UA_TYPES[UA_TYPES_BROWSEPATHRESULT], /* .memberType */
15444 offsetof(UA_TranslateBrowsePathsToNodeIdsResponse, resultsSize) - offsetof(UA_TranslateBrowsePathsToNodeIdsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
15445 true, /* .isArray */
15446 false /* .isOptional */
15447},
15448{
15449 UA_TYPENAME("DiagnosticInfos") /* .memberName */
15450 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
15451 offsetof(UA_TranslateBrowsePathsToNodeIdsResponse, diagnosticInfosSize) - offsetof(UA_TranslateBrowsePathsToNodeIdsResponse, results) - sizeof(void *), /* .padding */
15452 true, /* .isArray */
15453 false /* .isOptional */
15454},};
15455
15456/* RegisterNodesRequest */
15457static UA_DataTypeMember RegisterNodesRequest_members[2] = {
15458{
15459 UA_TYPENAME("RequestHeader") /* .memberName */
15460 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
15461 0, /* .padding */
15462 false, /* .isArray */
15463 false /* .isOptional */
15464},
15465{
15466 UA_TYPENAME("NodesToRegister") /* .memberName */
15467 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15468 offsetof(UA_RegisterNodesRequest, nodesToRegisterSize) - offsetof(UA_RegisterNodesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
15469 true, /* .isArray */
15470 false /* .isOptional */
15471},};
15472
15473/* RegisterNodesResponse */
15474static UA_DataTypeMember RegisterNodesResponse_members[2] = {
15475{
15476 UA_TYPENAME("ResponseHeader") /* .memberName */
15477 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
15478 0, /* .padding */
15479 false, /* .isArray */
15480 false /* .isOptional */
15481},
15482{
15483 UA_TYPENAME("RegisteredNodeIds") /* .memberName */
15484 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15485 offsetof(UA_RegisterNodesResponse, registeredNodeIdsSize) - offsetof(UA_RegisterNodesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
15486 true, /* .isArray */
15487 false /* .isOptional */
15488},};
15489
15490/* UnregisterNodesRequest */
15491static UA_DataTypeMember UnregisterNodesRequest_members[2] = {
15492{
15493 UA_TYPENAME("RequestHeader") /* .memberName */
15494 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
15495 0, /* .padding */
15496 false, /* .isArray */
15497 false /* .isOptional */
15498},
15499{
15500 UA_TYPENAME("NodesToUnregister") /* .memberName */
15501 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15502 offsetof(UA_UnregisterNodesRequest, nodesToUnregisterSize) - offsetof(UA_UnregisterNodesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
15503 true, /* .isArray */
15504 false /* .isOptional */
15505},};
15506
15507/* UnregisterNodesResponse */
15508static UA_DataTypeMember UnregisterNodesResponse_members[1] = {
15509{
15510 UA_TYPENAME("ResponseHeader") /* .memberName */
15511 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
15512 0, /* .padding */
15513 false, /* .isArray */
15514 false /* .isOptional */
15515},};
15516
15517/* Counter */
15518#define Counter_members NULL
15519
15520/* OpaqueNumericRange */
15521#define OpaqueNumericRange_members NULL
15522
15523/* EndpointConfiguration */
15524static UA_DataTypeMember EndpointConfiguration_members[9] = {
15525{
15526 UA_TYPENAME("OperationTimeout") /* .memberName */
15527 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
15528 0, /* .padding */
15529 false, /* .isArray */
15530 false /* .isOptional */
15531},
15532{
15533 UA_TYPENAME("UseBinaryEncoding") /* .memberName */
15534 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
15535 offsetof(UA_EndpointConfiguration, useBinaryEncoding) - offsetof(UA_EndpointConfiguration, operationTimeout) - sizeof(UA_Int32), /* .padding */
15536 false, /* .isArray */
15537 false /* .isOptional */
15538},
15539{
15540 UA_TYPENAME("MaxStringLength") /* .memberName */
15541 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
15542 offsetof(UA_EndpointConfiguration, maxStringLength) - offsetof(UA_EndpointConfiguration, useBinaryEncoding) - sizeof(UA_Boolean), /* .padding */
15543 false, /* .isArray */
15544 false /* .isOptional */
15545},
15546{
15547 UA_TYPENAME("MaxByteStringLength") /* .memberName */
15548 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
15549 offsetof(UA_EndpointConfiguration, maxByteStringLength) - offsetof(UA_EndpointConfiguration, maxStringLength) - sizeof(UA_Int32), /* .padding */
15550 false, /* .isArray */
15551 false /* .isOptional */
15552},
15553{
15554 UA_TYPENAME("MaxArrayLength") /* .memberName */
15555 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
15556 offsetof(UA_EndpointConfiguration, maxArrayLength) - offsetof(UA_EndpointConfiguration, maxByteStringLength) - sizeof(UA_Int32), /* .padding */
15557 false, /* .isArray */
15558 false /* .isOptional */
15559},
15560{
15561 UA_TYPENAME("MaxMessageSize") /* .memberName */
15562 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
15563 offsetof(UA_EndpointConfiguration, maxMessageSize) - offsetof(UA_EndpointConfiguration, maxArrayLength) - sizeof(UA_Int32), /* .padding */
15564 false, /* .isArray */
15565 false /* .isOptional */
15566},
15567{
15568 UA_TYPENAME("MaxBufferSize") /* .memberName */
15569 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
15570 offsetof(UA_EndpointConfiguration, maxBufferSize) - offsetof(UA_EndpointConfiguration, maxMessageSize) - sizeof(UA_Int32), /* .padding */
15571 false, /* .isArray */
15572 false /* .isOptional */
15573},
15574{
15575 UA_TYPENAME("ChannelLifetime") /* .memberName */
15576 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
15577 offsetof(UA_EndpointConfiguration, channelLifetime) - offsetof(UA_EndpointConfiguration, maxBufferSize) - sizeof(UA_Int32), /* .padding */
15578 false, /* .isArray */
15579 false /* .isOptional */
15580},
15581{
15582 UA_TYPENAME("SecurityTokenLifetime") /* .memberName */
15583 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
15584 offsetof(UA_EndpointConfiguration, securityTokenLifetime) - offsetof(UA_EndpointConfiguration, channelLifetime) - sizeof(UA_Int32), /* .padding */
15585 false, /* .isArray */
15586 false /* .isOptional */
15587},};
15588
15589/* QueryDataDescription */
15590static UA_DataTypeMember QueryDataDescription_members[3] = {
15591{
15592 UA_TYPENAME("RelativePath") /* .memberName */
15593 &UA_TYPES[UA_TYPES_RELATIVEPATH], /* .memberType */
15594 0, /* .padding */
15595 false, /* .isArray */
15596 false /* .isOptional */
15597},
15598{
15599 UA_TYPENAME("AttributeId") /* .memberName */
15600 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
15601 offsetof(UA_QueryDataDescription, attributeId) - offsetof(UA_QueryDataDescription, relativePath) - sizeof(UA_RelativePath), /* .padding */
15602 false, /* .isArray */
15603 false /* .isOptional */
15604},
15605{
15606 UA_TYPENAME("IndexRange") /* .memberName */
15607 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
15608 offsetof(UA_QueryDataDescription, indexRange) - offsetof(UA_QueryDataDescription, attributeId) - sizeof(UA_UInt32), /* .padding */
15609 false, /* .isArray */
15610 false /* .isOptional */
15611},};
15612
15613/* NodeTypeDescription */
15614static UA_DataTypeMember NodeTypeDescription_members[3] = {
15615{
15616 UA_TYPENAME("TypeDefinitionNode") /* .memberName */
15617 &UA_TYPES[UA_TYPES_EXPANDEDNODEID], /* .memberType */
15618 0, /* .padding */
15619 false, /* .isArray */
15620 false /* .isOptional */
15621},
15622{
15623 UA_TYPENAME("IncludeSubTypes") /* .memberName */
15624 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
15625 offsetof(UA_NodeTypeDescription, includeSubTypes) - offsetof(UA_NodeTypeDescription, typeDefinitionNode) - sizeof(UA_ExpandedNodeId), /* .padding */
15626 false, /* .isArray */
15627 false /* .isOptional */
15628},
15629{
15630 UA_TYPENAME("DataToReturn") /* .memberName */
15631 &UA_TYPES[UA_TYPES_QUERYDATADESCRIPTION], /* .memberType */
15632 offsetof(UA_NodeTypeDescription, dataToReturnSize) - offsetof(UA_NodeTypeDescription, includeSubTypes) - sizeof(UA_Boolean), /* .padding */
15633 true, /* .isArray */
15634 false /* .isOptional */
15635},};
15636
15637/* FilterOperator */
15638#define FilterOperator_members NULL
15639
15640/* QueryDataSet */
15641static UA_DataTypeMember QueryDataSet_members[3] = {
15642{
15643 UA_TYPENAME("NodeId") /* .memberName */
15644 &UA_TYPES[UA_TYPES_EXPANDEDNODEID], /* .memberType */
15645 0, /* .padding */
15646 false, /* .isArray */
15647 false /* .isOptional */
15648},
15649{
15650 UA_TYPENAME("TypeDefinitionNode") /* .memberName */
15651 &UA_TYPES[UA_TYPES_EXPANDEDNODEID], /* .memberType */
15652 offsetof(UA_QueryDataSet, typeDefinitionNode) - offsetof(UA_QueryDataSet, nodeId) - sizeof(UA_ExpandedNodeId), /* .padding */
15653 false, /* .isArray */
15654 false /* .isOptional */
15655},
15656{
15657 UA_TYPENAME("Values") /* .memberName */
15658 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
15659 offsetof(UA_QueryDataSet, valuesSize) - offsetof(UA_QueryDataSet, typeDefinitionNode) - sizeof(UA_ExpandedNodeId), /* .padding */
15660 true, /* .isArray */
15661 false /* .isOptional */
15662},};
15663
15664/* NodeReference */
15665static UA_DataTypeMember NodeReference_members[4] = {
15666{
15667 UA_TYPENAME("NodeId") /* .memberName */
15668 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15669 0, /* .padding */
15670 false, /* .isArray */
15671 false /* .isOptional */
15672},
15673{
15674 UA_TYPENAME("ReferenceTypeId") /* .memberName */
15675 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15676 offsetof(UA_NodeReference, referenceTypeId) - offsetof(UA_NodeReference, nodeId) - sizeof(UA_NodeId), /* .padding */
15677 false, /* .isArray */
15678 false /* .isOptional */
15679},
15680{
15681 UA_TYPENAME("IsForward") /* .memberName */
15682 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
15683 offsetof(UA_NodeReference, isForward) - offsetof(UA_NodeReference, referenceTypeId) - sizeof(UA_NodeId), /* .padding */
15684 false, /* .isArray */
15685 false /* .isOptional */
15686},
15687{
15688 UA_TYPENAME("ReferencedNodeIds") /* .memberName */
15689 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15690 offsetof(UA_NodeReference, referencedNodeIdsSize) - offsetof(UA_NodeReference, isForward) - sizeof(UA_Boolean), /* .padding */
15691 true, /* .isArray */
15692 false /* .isOptional */
15693},};
15694
15695/* ContentFilterElement */
15696static UA_DataTypeMember ContentFilterElement_members[2] = {
15697{
15698 UA_TYPENAME("FilterOperator") /* .memberName */
15699 &UA_TYPES[UA_TYPES_FILTEROPERATOR], /* .memberType */
15700 0, /* .padding */
15701 false, /* .isArray */
15702 false /* .isOptional */
15703},
15704{
15705 UA_TYPENAME("FilterOperands") /* .memberName */
15706 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
15707 offsetof(UA_ContentFilterElement, filterOperandsSize) - offsetof(UA_ContentFilterElement, filterOperator) - sizeof(UA_FilterOperator), /* .padding */
15708 true, /* .isArray */
15709 false /* .isOptional */
15710},};
15711
15712/* ContentFilter */
15713static UA_DataTypeMember ContentFilter_members[1] = {
15714{
15715 UA_TYPENAME("Elements") /* .memberName */
15716 &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT], /* .memberType */
15717 0, /* .padding */
15718 true, /* .isArray */
15719 false /* .isOptional */
15720},};
15721
15722/* ElementOperand */
15723static UA_DataTypeMember ElementOperand_members[1] = {
15724{
15725 UA_TYPENAME("Index") /* .memberName */
15726 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
15727 0, /* .padding */
15728 false, /* .isArray */
15729 false /* .isOptional */
15730},};
15731
15732/* LiteralOperand */
15733static UA_DataTypeMember LiteralOperand_members[1] = {
15734{
15735 UA_TYPENAME("Value") /* .memberName */
15736 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
15737 0, /* .padding */
15738 false, /* .isArray */
15739 false /* .isOptional */
15740},};
15741
15742/* AttributeOperand */
15743static UA_DataTypeMember AttributeOperand_members[5] = {
15744{
15745 UA_TYPENAME("NodeId") /* .memberName */
15746 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15747 0, /* .padding */
15748 false, /* .isArray */
15749 false /* .isOptional */
15750},
15751{
15752 UA_TYPENAME("Alias") /* .memberName */
15753 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
15754 offsetof(UA_AttributeOperand, alias) - offsetof(UA_AttributeOperand, nodeId) - sizeof(UA_NodeId), /* .padding */
15755 false, /* .isArray */
15756 false /* .isOptional */
15757},
15758{
15759 UA_TYPENAME("BrowsePath") /* .memberName */
15760 &UA_TYPES[UA_TYPES_RELATIVEPATH], /* .memberType */
15761 offsetof(UA_AttributeOperand, browsePath) - offsetof(UA_AttributeOperand, alias) - sizeof(UA_String), /* .padding */
15762 false, /* .isArray */
15763 false /* .isOptional */
15764},
15765{
15766 UA_TYPENAME("AttributeId") /* .memberName */
15767 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
15768 offsetof(UA_AttributeOperand, attributeId) - offsetof(UA_AttributeOperand, browsePath) - sizeof(UA_RelativePath), /* .padding */
15769 false, /* .isArray */
15770 false /* .isOptional */
15771},
15772{
15773 UA_TYPENAME("IndexRange") /* .memberName */
15774 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
15775 offsetof(UA_AttributeOperand, indexRange) - offsetof(UA_AttributeOperand, attributeId) - sizeof(UA_UInt32), /* .padding */
15776 false, /* .isArray */
15777 false /* .isOptional */
15778},};
15779
15780/* SimpleAttributeOperand */
15781static UA_DataTypeMember SimpleAttributeOperand_members[4] = {
15782{
15783 UA_TYPENAME("TypeDefinitionId") /* .memberName */
15784 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
15785 0, /* .padding */
15786 false, /* .isArray */
15787 false /* .isOptional */
15788},
15789{
15790 UA_TYPENAME("BrowsePath") /* .memberName */
15791 &UA_TYPES[UA_TYPES_QUALIFIEDNAME], /* .memberType */
15792 offsetof(UA_SimpleAttributeOperand, browsePathSize) - offsetof(UA_SimpleAttributeOperand, typeDefinitionId) - sizeof(UA_NodeId), /* .padding */
15793 true, /* .isArray */
15794 false /* .isOptional */
15795},
15796{
15797 UA_TYPENAME("AttributeId") /* .memberName */
15798 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
15799 offsetof(UA_SimpleAttributeOperand, attributeId) - offsetof(UA_SimpleAttributeOperand, browsePath) - sizeof(void *), /* .padding */
15800 false, /* .isArray */
15801 false /* .isOptional */
15802},
15803{
15804 UA_TYPENAME("IndexRange") /* .memberName */
15805 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
15806 offsetof(UA_SimpleAttributeOperand, indexRange) - offsetof(UA_SimpleAttributeOperand, attributeId) - sizeof(UA_UInt32), /* .padding */
15807 false, /* .isArray */
15808 false /* .isOptional */
15809},};
15810
15811/* ContentFilterElementResult */
15812static UA_DataTypeMember ContentFilterElementResult_members[3] = {
15813{
15814 UA_TYPENAME("StatusCode") /* .memberName */
15815 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
15816 0, /* .padding */
15817 false, /* .isArray */
15818 false /* .isOptional */
15819},
15820{
15821 UA_TYPENAME("OperandStatusCodes") /* .memberName */
15822 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
15823 offsetof(UA_ContentFilterElementResult, operandStatusCodesSize) - offsetof(UA_ContentFilterElementResult, statusCode) - sizeof(UA_StatusCode), /* .padding */
15824 true, /* .isArray */
15825 false /* .isOptional */
15826},
15827{
15828 UA_TYPENAME("OperandDiagnosticInfos") /* .memberName */
15829 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
15830 offsetof(UA_ContentFilterElementResult, operandDiagnosticInfosSize) - offsetof(UA_ContentFilterElementResult, operandStatusCodes) - sizeof(void *), /* .padding */
15831 true, /* .isArray */
15832 false /* .isOptional */
15833},};
15834
15835/* ContentFilterResult */
15836static UA_DataTypeMember ContentFilterResult_members[2] = {
15837{
15838 UA_TYPENAME("ElementResults") /* .memberName */
15839 &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENTRESULT], /* .memberType */
15840 0, /* .padding */
15841 true, /* .isArray */
15842 false /* .isOptional */
15843},
15844{
15845 UA_TYPENAME("ElementDiagnosticInfos") /* .memberName */
15846 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
15847 offsetof(UA_ContentFilterResult, elementDiagnosticInfosSize) - offsetof(UA_ContentFilterResult, elementResults) - sizeof(void *), /* .padding */
15848 true, /* .isArray */
15849 false /* .isOptional */
15850},};
15851
15852/* ParsingResult */
15853static UA_DataTypeMember ParsingResult_members[3] = {
15854{
15855 UA_TYPENAME("StatusCode") /* .memberName */
15856 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
15857 0, /* .padding */
15858 false, /* .isArray */
15859 false /* .isOptional */
15860},
15861{
15862 UA_TYPENAME("DataStatusCodes") /* .memberName */
15863 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
15864 offsetof(UA_ParsingResult, dataStatusCodesSize) - offsetof(UA_ParsingResult, statusCode) - sizeof(UA_StatusCode), /* .padding */
15865 true, /* .isArray */
15866 false /* .isOptional */
15867},
15868{
15869 UA_TYPENAME("DataDiagnosticInfos") /* .memberName */
15870 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
15871 offsetof(UA_ParsingResult, dataDiagnosticInfosSize) - offsetof(UA_ParsingResult, dataStatusCodes) - sizeof(void *), /* .padding */
15872 true, /* .isArray */
15873 false /* .isOptional */
15874},};
15875
15876/* QueryFirstRequest */
15877static UA_DataTypeMember QueryFirstRequest_members[6] = {
15878{
15879 UA_TYPENAME("RequestHeader") /* .memberName */
15880 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
15881 0, /* .padding */
15882 false, /* .isArray */
15883 false /* .isOptional */
15884},
15885{
15886 UA_TYPENAME("View") /* .memberName */
15887 &UA_TYPES[UA_TYPES_VIEWDESCRIPTION], /* .memberType */
15888 offsetof(UA_QueryFirstRequest, view) - offsetof(UA_QueryFirstRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
15889 false, /* .isArray */
15890 false /* .isOptional */
15891},
15892{
15893 UA_TYPENAME("NodeTypes") /* .memberName */
15894 &UA_TYPES[UA_TYPES_NODETYPEDESCRIPTION], /* .memberType */
15895 offsetof(UA_QueryFirstRequest, nodeTypesSize) - offsetof(UA_QueryFirstRequest, view) - sizeof(UA_ViewDescription), /* .padding */
15896 true, /* .isArray */
15897 false /* .isOptional */
15898},
15899{
15900 UA_TYPENAME("Filter") /* .memberName */
15901 &UA_TYPES[UA_TYPES_CONTENTFILTER], /* .memberType */
15902 offsetof(UA_QueryFirstRequest, filter) - offsetof(UA_QueryFirstRequest, nodeTypes) - sizeof(void *), /* .padding */
15903 false, /* .isArray */
15904 false /* .isOptional */
15905},
15906{
15907 UA_TYPENAME("MaxDataSetsToReturn") /* .memberName */
15908 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
15909 offsetof(UA_QueryFirstRequest, maxDataSetsToReturn) - offsetof(UA_QueryFirstRequest, filter) - sizeof(UA_ContentFilter), /* .padding */
15910 false, /* .isArray */
15911 false /* .isOptional */
15912},
15913{
15914 UA_TYPENAME("MaxReferencesToReturn") /* .memberName */
15915 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
15916 offsetof(UA_QueryFirstRequest, maxReferencesToReturn) - offsetof(UA_QueryFirstRequest, maxDataSetsToReturn) - sizeof(UA_UInt32), /* .padding */
15917 false, /* .isArray */
15918 false /* .isOptional */
15919},};
15920
15921/* QueryFirstResponse */
15922static UA_DataTypeMember QueryFirstResponse_members[6] = {
15923{
15924 UA_TYPENAME("ResponseHeader") /* .memberName */
15925 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
15926 0, /* .padding */
15927 false, /* .isArray */
15928 false /* .isOptional */
15929},
15930{
15931 UA_TYPENAME("QueryDataSets") /* .memberName */
15932 &UA_TYPES[UA_TYPES_QUERYDATASET], /* .memberType */
15933 offsetof(UA_QueryFirstResponse, queryDataSetsSize) - offsetof(UA_QueryFirstResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
15934 true, /* .isArray */
15935 false /* .isOptional */
15936},
15937{
15938 UA_TYPENAME("ContinuationPoint") /* .memberName */
15939 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
15940 offsetof(UA_QueryFirstResponse, continuationPoint) - offsetof(UA_QueryFirstResponse, queryDataSets) - sizeof(void *), /* .padding */
15941 false, /* .isArray */
15942 false /* .isOptional */
15943},
15944{
15945 UA_TYPENAME("ParsingResults") /* .memberName */
15946 &UA_TYPES[UA_TYPES_PARSINGRESULT], /* .memberType */
15947 offsetof(UA_QueryFirstResponse, parsingResultsSize) - offsetof(UA_QueryFirstResponse, continuationPoint) - sizeof(UA_ByteString), /* .padding */
15948 true, /* .isArray */
15949 false /* .isOptional */
15950},
15951{
15952 UA_TYPENAME("DiagnosticInfos") /* .memberName */
15953 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
15954 offsetof(UA_QueryFirstResponse, diagnosticInfosSize) - offsetof(UA_QueryFirstResponse, parsingResults) - sizeof(void *), /* .padding */
15955 true, /* .isArray */
15956 false /* .isOptional */
15957},
15958{
15959 UA_TYPENAME("FilterResult") /* .memberName */
15960 &UA_TYPES[UA_TYPES_CONTENTFILTERRESULT], /* .memberType */
15961 offsetof(UA_QueryFirstResponse, filterResult) - offsetof(UA_QueryFirstResponse, diagnosticInfos) - sizeof(void *), /* .padding */
15962 false, /* .isArray */
15963 false /* .isOptional */
15964},};
15965
15966/* QueryNextRequest */
15967static UA_DataTypeMember QueryNextRequest_members[3] = {
15968{
15969 UA_TYPENAME("RequestHeader") /* .memberName */
15970 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
15971 0, /* .padding */
15972 false, /* .isArray */
15973 false /* .isOptional */
15974},
15975{
15976 UA_TYPENAME("ReleaseContinuationPoint") /* .memberName */
15977 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
15978 offsetof(UA_QueryNextRequest, releaseContinuationPoint) - offsetof(UA_QueryNextRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
15979 false, /* .isArray */
15980 false /* .isOptional */
15981},
15982{
15983 UA_TYPENAME("ContinuationPoint") /* .memberName */
15984 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
15985 offsetof(UA_QueryNextRequest, continuationPoint) - offsetof(UA_QueryNextRequest, releaseContinuationPoint) - sizeof(UA_Boolean), /* .padding */
15986 false, /* .isArray */
15987 false /* .isOptional */
15988},};
15989
15990/* QueryNextResponse */
15991static UA_DataTypeMember QueryNextResponse_members[3] = {
15992{
15993 UA_TYPENAME("ResponseHeader") /* .memberName */
15994 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
15995 0, /* .padding */
15996 false, /* .isArray */
15997 false /* .isOptional */
15998},
15999{
16000 UA_TYPENAME("QueryDataSets") /* .memberName */
16001 &UA_TYPES[UA_TYPES_QUERYDATASET], /* .memberType */
16002 offsetof(UA_QueryNextResponse, queryDataSetsSize) - offsetof(UA_QueryNextResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
16003 true, /* .isArray */
16004 false /* .isOptional */
16005},
16006{
16007 UA_TYPENAME("RevisedContinuationPoint") /* .memberName */
16008 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
16009 offsetof(UA_QueryNextResponse, revisedContinuationPoint) - offsetof(UA_QueryNextResponse, queryDataSets) - sizeof(void *), /* .padding */
16010 false, /* .isArray */
16011 false /* .isOptional */
16012},};
16013
16014/* TimestampsToReturn */
16015#define TimestampsToReturn_members NULL
16016
16017/* ReadValueId */
16018static UA_DataTypeMember ReadValueId_members[4] = {
16019{
16020 UA_TYPENAME("NodeId") /* .memberName */
16021 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
16022 0, /* .padding */
16023 false, /* .isArray */
16024 false /* .isOptional */
16025},
16026{
16027 UA_TYPENAME("AttributeId") /* .memberName */
16028 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
16029 offsetof(UA_ReadValueId, attributeId) - offsetof(UA_ReadValueId, nodeId) - sizeof(UA_NodeId), /* .padding */
16030 false, /* .isArray */
16031 false /* .isOptional */
16032},
16033{
16034 UA_TYPENAME("IndexRange") /* .memberName */
16035 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
16036 offsetof(UA_ReadValueId, indexRange) - offsetof(UA_ReadValueId, attributeId) - sizeof(UA_UInt32), /* .padding */
16037 false, /* .isArray */
16038 false /* .isOptional */
16039},
16040{
16041 UA_TYPENAME("DataEncoding") /* .memberName */
16042 &UA_TYPES[UA_TYPES_QUALIFIEDNAME], /* .memberType */
16043 offsetof(UA_ReadValueId, dataEncoding) - offsetof(UA_ReadValueId, indexRange) - sizeof(UA_String), /* .padding */
16044 false, /* .isArray */
16045 false /* .isOptional */
16046},};
16047
16048/* ReadRequest */
16049static UA_DataTypeMember ReadRequest_members[4] = {
16050{
16051 UA_TYPENAME("RequestHeader") /* .memberName */
16052 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
16053 0, /* .padding */
16054 false, /* .isArray */
16055 false /* .isOptional */
16056},
16057{
16058 UA_TYPENAME("MaxAge") /* .memberName */
16059 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
16060 offsetof(UA_ReadRequest, maxAge) - offsetof(UA_ReadRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
16061 false, /* .isArray */
16062 false /* .isOptional */
16063},
16064{
16065 UA_TYPENAME("TimestampsToReturn") /* .memberName */
16066 &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN], /* .memberType */
16067 offsetof(UA_ReadRequest, timestampsToReturn) - offsetof(UA_ReadRequest, maxAge) - sizeof(UA_Double), /* .padding */
16068 false, /* .isArray */
16069 false /* .isOptional */
16070},
16071{
16072 UA_TYPENAME("NodesToRead") /* .memberName */
16073 &UA_TYPES[UA_TYPES_READVALUEID], /* .memberType */
16074 offsetof(UA_ReadRequest, nodesToReadSize) - offsetof(UA_ReadRequest, timestampsToReturn) - sizeof(UA_TimestampsToReturn), /* .padding */
16075 true, /* .isArray */
16076 false /* .isOptional */
16077},};
16078
16079/* ReadResponse */
16080static UA_DataTypeMember ReadResponse_members[3] = {
16081{
16082 UA_TYPENAME("ResponseHeader") /* .memberName */
16083 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
16084 0, /* .padding */
16085 false, /* .isArray */
16086 false /* .isOptional */
16087},
16088{
16089 UA_TYPENAME("Results") /* .memberName */
16090 &UA_TYPES[UA_TYPES_DATAVALUE], /* .memberType */
16091 offsetof(UA_ReadResponse, resultsSize) - offsetof(UA_ReadResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
16092 true, /* .isArray */
16093 false /* .isOptional */
16094},
16095{
16096 UA_TYPENAME("DiagnosticInfos") /* .memberName */
16097 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
16098 offsetof(UA_ReadResponse, diagnosticInfosSize) - offsetof(UA_ReadResponse, results) - sizeof(void *), /* .padding */
16099 true, /* .isArray */
16100 false /* .isOptional */
16101},};
16102
16103/* HistoryReadValueId */
16104static UA_DataTypeMember HistoryReadValueId_members[4] = {
16105{
16106 UA_TYPENAME("NodeId") /* .memberName */
16107 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
16108 0, /* .padding */
16109 false, /* .isArray */
16110 false /* .isOptional */
16111},
16112{
16113 UA_TYPENAME("IndexRange") /* .memberName */
16114 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
16115 offsetof(UA_HistoryReadValueId, indexRange) - offsetof(UA_HistoryReadValueId, nodeId) - sizeof(UA_NodeId), /* .padding */
16116 false, /* .isArray */
16117 false /* .isOptional */
16118},
16119{
16120 UA_TYPENAME("DataEncoding") /* .memberName */
16121 &UA_TYPES[UA_TYPES_QUALIFIEDNAME], /* .memberType */
16122 offsetof(UA_HistoryReadValueId, dataEncoding) - offsetof(UA_HistoryReadValueId, indexRange) - sizeof(UA_String), /* .padding */
16123 false, /* .isArray */
16124 false /* .isOptional */
16125},
16126{
16127 UA_TYPENAME("ContinuationPoint") /* .memberName */
16128 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
16129 offsetof(UA_HistoryReadValueId, continuationPoint) - offsetof(UA_HistoryReadValueId, dataEncoding) - sizeof(UA_QualifiedName), /* .padding */
16130 false, /* .isArray */
16131 false /* .isOptional */
16132},};
16133
16134/* HistoryReadResult */
16135static UA_DataTypeMember HistoryReadResult_members[3] = {
16136{
16137 UA_TYPENAME("StatusCode") /* .memberName */
16138 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
16139 0, /* .padding */
16140 false, /* .isArray */
16141 false /* .isOptional */
16142},
16143{
16144 UA_TYPENAME("ContinuationPoint") /* .memberName */
16145 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
16146 offsetof(UA_HistoryReadResult, continuationPoint) - offsetof(UA_HistoryReadResult, statusCode) - sizeof(UA_StatusCode), /* .padding */
16147 false, /* .isArray */
16148 false /* .isOptional */
16149},
16150{
16151 UA_TYPENAME("HistoryData") /* .memberName */
16152 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
16153 offsetof(UA_HistoryReadResult, historyData) - offsetof(UA_HistoryReadResult, continuationPoint) - sizeof(UA_ByteString), /* .padding */
16154 false, /* .isArray */
16155 false /* .isOptional */
16156},};
16157
16158/* ReadRawModifiedDetails */
16159static UA_DataTypeMember ReadRawModifiedDetails_members[5] = {
16160{
16161 UA_TYPENAME("IsReadModified") /* .memberName */
16162 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
16163 0, /* .padding */
16164 false, /* .isArray */
16165 false /* .isOptional */
16166},
16167{
16168 UA_TYPENAME("StartTime") /* .memberName */
16169 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
16170 offsetof(UA_ReadRawModifiedDetails, startTime) - offsetof(UA_ReadRawModifiedDetails, isReadModified) - sizeof(UA_Boolean), /* .padding */
16171 false, /* .isArray */
16172 false /* .isOptional */
16173},
16174{
16175 UA_TYPENAME("EndTime") /* .memberName */
16176 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
16177 offsetof(UA_ReadRawModifiedDetails, endTime) - offsetof(UA_ReadRawModifiedDetails, startTime) - sizeof(UA_DateTime), /* .padding */
16178 false, /* .isArray */
16179 false /* .isOptional */
16180},
16181{
16182 UA_TYPENAME("NumValuesPerNode") /* .memberName */
16183 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
16184 offsetof(UA_ReadRawModifiedDetails, numValuesPerNode) - offsetof(UA_ReadRawModifiedDetails, endTime) - sizeof(UA_DateTime), /* .padding */
16185 false, /* .isArray */
16186 false /* .isOptional */
16187},
16188{
16189 UA_TYPENAME("ReturnBounds") /* .memberName */
16190 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
16191 offsetof(UA_ReadRawModifiedDetails, returnBounds) - offsetof(UA_ReadRawModifiedDetails, numValuesPerNode) - sizeof(UA_UInt32), /* .padding */
16192 false, /* .isArray */
16193 false /* .isOptional */
16194},};
16195
16196/* ReadAtTimeDetails */
16197static UA_DataTypeMember ReadAtTimeDetails_members[2] = {
16198{
16199 UA_TYPENAME("ReqTimes") /* .memberName */
16200 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
16201 0, /* .padding */
16202 true, /* .isArray */
16203 false /* .isOptional */
16204},
16205{
16206 UA_TYPENAME("UseSimpleBounds") /* .memberName */
16207 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
16208 offsetof(UA_ReadAtTimeDetails, useSimpleBounds) - offsetof(UA_ReadAtTimeDetails, reqTimes) - sizeof(void *), /* .padding */
16209 false, /* .isArray */
16210 false /* .isOptional */
16211},};
16212
16213/* ReadAnnotationDataDetails */
16214static UA_DataTypeMember ReadAnnotationDataDetails_members[1] = {
16215{
16216 UA_TYPENAME("ReqTimes") /* .memberName */
16217 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
16218 0, /* .padding */
16219 true, /* .isArray */
16220 false /* .isOptional */
16221},};
16222
16223/* HistoryData */
16224static UA_DataTypeMember HistoryData_members[1] = {
16225{
16226 UA_TYPENAME("DataValues") /* .memberName */
16227 &UA_TYPES[UA_TYPES_DATAVALUE], /* .memberType */
16228 0, /* .padding */
16229 true, /* .isArray */
16230 false /* .isOptional */
16231},};
16232
16233/* HistoryReadRequest */
16234static UA_DataTypeMember HistoryReadRequest_members[5] = {
16235{
16236 UA_TYPENAME("RequestHeader") /* .memberName */
16237 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
16238 0, /* .padding */
16239 false, /* .isArray */
16240 false /* .isOptional */
16241},
16242{
16243 UA_TYPENAME("HistoryReadDetails") /* .memberName */
16244 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
16245 offsetof(UA_HistoryReadRequest, historyReadDetails) - offsetof(UA_HistoryReadRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
16246 false, /* .isArray */
16247 false /* .isOptional */
16248},
16249{
16250 UA_TYPENAME("TimestampsToReturn") /* .memberName */
16251 &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN], /* .memberType */
16252 offsetof(UA_HistoryReadRequest, timestampsToReturn) - offsetof(UA_HistoryReadRequest, historyReadDetails) - sizeof(UA_ExtensionObject), /* .padding */
16253 false, /* .isArray */
16254 false /* .isOptional */
16255},
16256{
16257 UA_TYPENAME("ReleaseContinuationPoints") /* .memberName */
16258 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
16259 offsetof(UA_HistoryReadRequest, releaseContinuationPoints) - offsetof(UA_HistoryReadRequest, timestampsToReturn) - sizeof(UA_TimestampsToReturn), /* .padding */
16260 false, /* .isArray */
16261 false /* .isOptional */
16262},
16263{
16264 UA_TYPENAME("NodesToRead") /* .memberName */
16265 &UA_TYPES[UA_TYPES_HISTORYREADVALUEID], /* .memberType */
16266 offsetof(UA_HistoryReadRequest, nodesToReadSize) - offsetof(UA_HistoryReadRequest, releaseContinuationPoints) - sizeof(UA_Boolean), /* .padding */
16267 true, /* .isArray */
16268 false /* .isOptional */
16269},};
16270
16271/* HistoryReadResponse */
16272static UA_DataTypeMember HistoryReadResponse_members[3] = {
16273{
16274 UA_TYPENAME("ResponseHeader") /* .memberName */
16275 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
16276 0, /* .padding */
16277 false, /* .isArray */
16278 false /* .isOptional */
16279},
16280{
16281 UA_TYPENAME("Results") /* .memberName */
16282 &UA_TYPES[UA_TYPES_HISTORYREADRESULT], /* .memberType */
16283 offsetof(UA_HistoryReadResponse, resultsSize) - offsetof(UA_HistoryReadResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
16284 true, /* .isArray */
16285 false /* .isOptional */
16286},
16287{
16288 UA_TYPENAME("DiagnosticInfos") /* .memberName */
16289 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
16290 offsetof(UA_HistoryReadResponse, diagnosticInfosSize) - offsetof(UA_HistoryReadResponse, results) - sizeof(void *), /* .padding */
16291 true, /* .isArray */
16292 false /* .isOptional */
16293},};
16294
16295/* WriteValue */
16296static UA_DataTypeMember WriteValue_members[4] = {
16297{
16298 UA_TYPENAME("NodeId") /* .memberName */
16299 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
16300 0, /* .padding */
16301 false, /* .isArray */
16302 false /* .isOptional */
16303},
16304{
16305 UA_TYPENAME("AttributeId") /* .memberName */
16306 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
16307 offsetof(UA_WriteValue, attributeId) - offsetof(UA_WriteValue, nodeId) - sizeof(UA_NodeId), /* .padding */
16308 false, /* .isArray */
16309 false /* .isOptional */
16310},
16311{
16312 UA_TYPENAME("IndexRange") /* .memberName */
16313 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
16314 offsetof(UA_WriteValue, indexRange) - offsetof(UA_WriteValue, attributeId) - sizeof(UA_UInt32), /* .padding */
16315 false, /* .isArray */
16316 false /* .isOptional */
16317},
16318{
16319 UA_TYPENAME("Value") /* .memberName */
16320 &UA_TYPES[UA_TYPES_DATAVALUE], /* .memberType */
16321 offsetof(UA_WriteValue, value) - offsetof(UA_WriteValue, indexRange) - sizeof(UA_String), /* .padding */
16322 false, /* .isArray */
16323 false /* .isOptional */
16324},};
16325
16326/* WriteRequest */
16327static UA_DataTypeMember WriteRequest_members[2] = {
16328{
16329 UA_TYPENAME("RequestHeader") /* .memberName */
16330 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
16331 0, /* .padding */
16332 false, /* .isArray */
16333 false /* .isOptional */
16334},
16335{
16336 UA_TYPENAME("NodesToWrite") /* .memberName */
16337 &UA_TYPES[UA_TYPES_WRITEVALUE], /* .memberType */
16338 offsetof(UA_WriteRequest, nodesToWriteSize) - offsetof(UA_WriteRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
16339 true, /* .isArray */
16340 false /* .isOptional */
16341},};
16342
16343/* WriteResponse */
16344static UA_DataTypeMember WriteResponse_members[3] = {
16345{
16346 UA_TYPENAME("ResponseHeader") /* .memberName */
16347 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
16348 0, /* .padding */
16349 false, /* .isArray */
16350 false /* .isOptional */
16351},
16352{
16353 UA_TYPENAME("Results") /* .memberName */
16354 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
16355 offsetof(UA_WriteResponse, resultsSize) - offsetof(UA_WriteResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
16356 true, /* .isArray */
16357 false /* .isOptional */
16358},
16359{
16360 UA_TYPENAME("DiagnosticInfos") /* .memberName */
16361 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
16362 offsetof(UA_WriteResponse, diagnosticInfosSize) - offsetof(UA_WriteResponse, results) - sizeof(void *), /* .padding */
16363 true, /* .isArray */
16364 false /* .isOptional */
16365},};
16366
16367/* HistoryUpdateDetails */
16368static UA_DataTypeMember HistoryUpdateDetails_members[1] = {
16369{
16370 UA_TYPENAME("NodeId") /* .memberName */
16371 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
16372 0, /* .padding */
16373 false, /* .isArray */
16374 false /* .isOptional */
16375},};
16376
16377/* HistoryUpdateType */
16378#define HistoryUpdateType_members NULL
16379
16380/* PerformUpdateType */
16381#define PerformUpdateType_members NULL
16382
16383/* UpdateDataDetails */
16384static UA_DataTypeMember UpdateDataDetails_members[3] = {
16385{
16386 UA_TYPENAME("NodeId") /* .memberName */
16387 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
16388 0, /* .padding */
16389 false, /* .isArray */
16390 false /* .isOptional */
16391},
16392{
16393 UA_TYPENAME("PerformInsertReplace") /* .memberName */
16394 &UA_TYPES[UA_TYPES_PERFORMUPDATETYPE], /* .memberType */
16395 offsetof(UA_UpdateDataDetails, performInsertReplace) - offsetof(UA_UpdateDataDetails, nodeId) - sizeof(UA_NodeId), /* .padding */
16396 false, /* .isArray */
16397 false /* .isOptional */
16398},
16399{
16400 UA_TYPENAME("UpdateValues") /* .memberName */
16401 &UA_TYPES[UA_TYPES_DATAVALUE], /* .memberType */
16402 offsetof(UA_UpdateDataDetails, updateValuesSize) - offsetof(UA_UpdateDataDetails, performInsertReplace) - sizeof(UA_PerformUpdateType), /* .padding */
16403 true, /* .isArray */
16404 false /* .isOptional */
16405},};
16406
16407/* UpdateStructureDataDetails */
16408static UA_DataTypeMember UpdateStructureDataDetails_members[3] = {
16409{
16410 UA_TYPENAME("NodeId") /* .memberName */
16411 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
16412 0, /* .padding */
16413 false, /* .isArray */
16414 false /* .isOptional */
16415},
16416{
16417 UA_TYPENAME("PerformInsertReplace") /* .memberName */
16418 &UA_TYPES[UA_TYPES_PERFORMUPDATETYPE], /* .memberType */
16419 offsetof(UA_UpdateStructureDataDetails, performInsertReplace) - offsetof(UA_UpdateStructureDataDetails, nodeId) - sizeof(UA_NodeId), /* .padding */
16420 false, /* .isArray */
16421 false /* .isOptional */
16422},
16423{
16424 UA_TYPENAME("UpdateValues") /* .memberName */
16425 &UA_TYPES[UA_TYPES_DATAVALUE], /* .memberType */
16426 offsetof(UA_UpdateStructureDataDetails, updateValuesSize) - offsetof(UA_UpdateStructureDataDetails, performInsertReplace) - sizeof(UA_PerformUpdateType), /* .padding */
16427 true, /* .isArray */
16428 false /* .isOptional */
16429},};
16430
16431/* DeleteRawModifiedDetails */
16432static UA_DataTypeMember DeleteRawModifiedDetails_members[4] = {
16433{
16434 UA_TYPENAME("NodeId") /* .memberName */
16435 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
16436 0, /* .padding */
16437 false, /* .isArray */
16438 false /* .isOptional */
16439},
16440{
16441 UA_TYPENAME("IsDeleteModified") /* .memberName */
16442 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
16443 offsetof(UA_DeleteRawModifiedDetails, isDeleteModified) - offsetof(UA_DeleteRawModifiedDetails, nodeId) - sizeof(UA_NodeId), /* .padding */
16444 false, /* .isArray */
16445 false /* .isOptional */
16446},
16447{
16448 UA_TYPENAME("StartTime") /* .memberName */
16449 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
16450 offsetof(UA_DeleteRawModifiedDetails, startTime) - offsetof(UA_DeleteRawModifiedDetails, isDeleteModified) - sizeof(UA_Boolean), /* .padding */
16451 false, /* .isArray */
16452 false /* .isOptional */
16453},
16454{
16455 UA_TYPENAME("EndTime") /* .memberName */
16456 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
16457 offsetof(UA_DeleteRawModifiedDetails, endTime) - offsetof(UA_DeleteRawModifiedDetails, startTime) - sizeof(UA_DateTime), /* .padding */
16458 false, /* .isArray */
16459 false /* .isOptional */
16460},};
16461
16462/* DeleteAtTimeDetails */
16463static UA_DataTypeMember DeleteAtTimeDetails_members[2] = {
16464{
16465 UA_TYPENAME("NodeId") /* .memberName */
16466 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
16467 0, /* .padding */
16468 false, /* .isArray */
16469 false /* .isOptional */
16470},
16471{
16472 UA_TYPENAME("ReqTimes") /* .memberName */
16473 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
16474 offsetof(UA_DeleteAtTimeDetails, reqTimesSize) - offsetof(UA_DeleteAtTimeDetails, nodeId) - sizeof(UA_NodeId), /* .padding */
16475 true, /* .isArray */
16476 false /* .isOptional */
16477},};
16478
16479/* DeleteEventDetails */
16480static UA_DataTypeMember DeleteEventDetails_members[2] = {
16481{
16482 UA_TYPENAME("NodeId") /* .memberName */
16483 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
16484 0, /* .padding */
16485 false, /* .isArray */
16486 false /* .isOptional */
16487},
16488{
16489 UA_TYPENAME("EventIds") /* .memberName */
16490 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
16491 offsetof(UA_DeleteEventDetails, eventIdsSize) - offsetof(UA_DeleteEventDetails, nodeId) - sizeof(UA_NodeId), /* .padding */
16492 true, /* .isArray */
16493 false /* .isOptional */
16494},};
16495
16496/* HistoryUpdateResult */
16497static UA_DataTypeMember HistoryUpdateResult_members[3] = {
16498{
16499 UA_TYPENAME("StatusCode") /* .memberName */
16500 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
16501 0, /* .padding */
16502 false, /* .isArray */
16503 false /* .isOptional */
16504},
16505{
16506 UA_TYPENAME("OperationResults") /* .memberName */
16507 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
16508 offsetof(UA_HistoryUpdateResult, operationResultsSize) - offsetof(UA_HistoryUpdateResult, statusCode) - sizeof(UA_StatusCode), /* .padding */
16509 true, /* .isArray */
16510 false /* .isOptional */
16511},
16512{
16513 UA_TYPENAME("DiagnosticInfos") /* .memberName */
16514 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
16515 offsetof(UA_HistoryUpdateResult, diagnosticInfosSize) - offsetof(UA_HistoryUpdateResult, operationResults) - sizeof(void *), /* .padding */
16516 true, /* .isArray */
16517 false /* .isOptional */
16518},};
16519
16520/* HistoryUpdateRequest */
16521static UA_DataTypeMember HistoryUpdateRequest_members[2] = {
16522{
16523 UA_TYPENAME("RequestHeader") /* .memberName */
16524 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
16525 0, /* .padding */
16526 false, /* .isArray */
16527 false /* .isOptional */
16528},
16529{
16530 UA_TYPENAME("HistoryUpdateDetails") /* .memberName */
16531 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
16532 offsetof(UA_HistoryUpdateRequest, historyUpdateDetailsSize) - offsetof(UA_HistoryUpdateRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
16533 true, /* .isArray */
16534 false /* .isOptional */
16535},};
16536
16537/* HistoryUpdateResponse */
16538static UA_DataTypeMember HistoryUpdateResponse_members[3] = {
16539{
16540 UA_TYPENAME("ResponseHeader") /* .memberName */
16541 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
16542 0, /* .padding */
16543 false, /* .isArray */
16544 false /* .isOptional */
16545},
16546{
16547 UA_TYPENAME("Results") /* .memberName */
16548 &UA_TYPES[UA_TYPES_HISTORYUPDATERESULT], /* .memberType */
16549 offsetof(UA_HistoryUpdateResponse, resultsSize) - offsetof(UA_HistoryUpdateResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
16550 true, /* .isArray */
16551 false /* .isOptional */
16552},
16553{
16554 UA_TYPENAME("DiagnosticInfos") /* .memberName */
16555 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
16556 offsetof(UA_HistoryUpdateResponse, diagnosticInfosSize) - offsetof(UA_HistoryUpdateResponse, results) - sizeof(void *), /* .padding */
16557 true, /* .isArray */
16558 false /* .isOptional */
16559},};
16560
16561/* CallMethodRequest */
16562static UA_DataTypeMember CallMethodRequest_members[3] = {
16563{
16564 UA_TYPENAME("ObjectId") /* .memberName */
16565 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
16566 0, /* .padding */
16567 false, /* .isArray */
16568 false /* .isOptional */
16569},
16570{
16571 UA_TYPENAME("MethodId") /* .memberName */
16572 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
16573 offsetof(UA_CallMethodRequest, methodId) - offsetof(UA_CallMethodRequest, objectId) - sizeof(UA_NodeId), /* .padding */
16574 false, /* .isArray */
16575 false /* .isOptional */
16576},
16577{
16578 UA_TYPENAME("InputArguments") /* .memberName */
16579 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
16580 offsetof(UA_CallMethodRequest, inputArgumentsSize) - offsetof(UA_CallMethodRequest, methodId) - sizeof(UA_NodeId), /* .padding */
16581 true, /* .isArray */
16582 false /* .isOptional */
16583},};
16584
16585/* CallMethodResult */
16586static UA_DataTypeMember CallMethodResult_members[4] = {
16587{
16588 UA_TYPENAME("StatusCode") /* .memberName */
16589 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
16590 0, /* .padding */
16591 false, /* .isArray */
16592 false /* .isOptional */
16593},
16594{
16595 UA_TYPENAME("InputArgumentResults") /* .memberName */
16596 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
16597 offsetof(UA_CallMethodResult, inputArgumentResultsSize) - offsetof(UA_CallMethodResult, statusCode) - sizeof(UA_StatusCode), /* .padding */
16598 true, /* .isArray */
16599 false /* .isOptional */
16600},
16601{
16602 UA_TYPENAME("InputArgumentDiagnosticInfos") /* .memberName */
16603 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
16604 offsetof(UA_CallMethodResult, inputArgumentDiagnosticInfosSize) - offsetof(UA_CallMethodResult, inputArgumentResults) - sizeof(void *), /* .padding */
16605 true, /* .isArray */
16606 false /* .isOptional */
16607},
16608{
16609 UA_TYPENAME("OutputArguments") /* .memberName */
16610 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
16611 offsetof(UA_CallMethodResult, outputArgumentsSize) - offsetof(UA_CallMethodResult, inputArgumentDiagnosticInfos) - sizeof(void *), /* .padding */
16612 true, /* .isArray */
16613 false /* .isOptional */
16614},};
16615
16616/* CallRequest */
16617static UA_DataTypeMember CallRequest_members[2] = {
16618{
16619 UA_TYPENAME("RequestHeader") /* .memberName */
16620 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
16621 0, /* .padding */
16622 false, /* .isArray */
16623 false /* .isOptional */
16624},
16625{
16626 UA_TYPENAME("MethodsToCall") /* .memberName */
16627 &UA_TYPES[UA_TYPES_CALLMETHODREQUEST], /* .memberType */
16628 offsetof(UA_CallRequest, methodsToCallSize) - offsetof(UA_CallRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
16629 true, /* .isArray */
16630 false /* .isOptional */
16631},};
16632
16633/* CallResponse */
16634static UA_DataTypeMember CallResponse_members[3] = {
16635{
16636 UA_TYPENAME("ResponseHeader") /* .memberName */
16637 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
16638 0, /* .padding */
16639 false, /* .isArray */
16640 false /* .isOptional */
16641},
16642{
16643 UA_TYPENAME("Results") /* .memberName */
16644 &UA_TYPES[UA_TYPES_CALLMETHODRESULT], /* .memberType */
16645 offsetof(UA_CallResponse, resultsSize) - offsetof(UA_CallResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
16646 true, /* .isArray */
16647 false /* .isOptional */
16648},
16649{
16650 UA_TYPENAME("DiagnosticInfos") /* .memberName */
16651 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
16652 offsetof(UA_CallResponse, diagnosticInfosSize) - offsetof(UA_CallResponse, results) - sizeof(void *), /* .padding */
16653 true, /* .isArray */
16654 false /* .isOptional */
16655},};
16656
16657/* MonitoringMode */
16658#define MonitoringMode_members NULL
16659
16660/* DataChangeTrigger */
16661#define DataChangeTrigger_members NULL
16662
16663/* DeadbandType */
16664#define DeadbandType_members NULL
16665
16666/* DataChangeFilter */
16667static UA_DataTypeMember DataChangeFilter_members[3] = {
16668{
16669 UA_TYPENAME("Trigger") /* .memberName */
16670 &UA_TYPES[UA_TYPES_DATACHANGETRIGGER], /* .memberType */
16671 0, /* .padding */
16672 false, /* .isArray */
16673 false /* .isOptional */
16674},
16675{
16676 UA_TYPENAME("DeadbandType") /* .memberName */
16677 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
16678 offsetof(UA_DataChangeFilter, deadbandType) - offsetof(UA_DataChangeFilter, trigger) - sizeof(UA_DataChangeTrigger), /* .padding */
16679 false, /* .isArray */
16680 false /* .isOptional */
16681},
16682{
16683 UA_TYPENAME("DeadbandValue") /* .memberName */
16684 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
16685 offsetof(UA_DataChangeFilter, deadbandValue) - offsetof(UA_DataChangeFilter, deadbandType) - sizeof(UA_UInt32), /* .padding */
16686 false, /* .isArray */
16687 false /* .isOptional */
16688},};
16689
16690/* EventFilter */
16691static UA_DataTypeMember EventFilter_members[2] = {
16692{
16693 UA_TYPENAME("SelectClauses") /* .memberName */
16694 &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND], /* .memberType */
16695 0, /* .padding */
16696 true, /* .isArray */
16697 false /* .isOptional */
16698},
16699{
16700 UA_TYPENAME("WhereClause") /* .memberName */
16701 &UA_TYPES[UA_TYPES_CONTENTFILTER], /* .memberType */
16702 offsetof(UA_EventFilter, whereClause) - offsetof(UA_EventFilter, selectClauses) - sizeof(void *), /* .padding */
16703 false, /* .isArray */
16704 false /* .isOptional */
16705},};
16706
16707/* AggregateConfiguration */
16708static UA_DataTypeMember AggregateConfiguration_members[5] = {
16709{
16710 UA_TYPENAME("UseServerCapabilitiesDefaults") /* .memberName */
16711 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
16712 0, /* .padding */
16713 false, /* .isArray */
16714 false /* .isOptional */
16715},
16716{
16717 UA_TYPENAME("TreatUncertainAsBad") /* .memberName */
16718 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
16719 offsetof(UA_AggregateConfiguration, treatUncertainAsBad) - offsetof(UA_AggregateConfiguration, useServerCapabilitiesDefaults) - sizeof(UA_Boolean), /* .padding */
16720 false, /* .isArray */
16721 false /* .isOptional */
16722},
16723{
16724 UA_TYPENAME("PercentDataBad") /* .memberName */
16725 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
16726 offsetof(UA_AggregateConfiguration, percentDataBad) - offsetof(UA_AggregateConfiguration, treatUncertainAsBad) - sizeof(UA_Boolean), /* .padding */
16727 false, /* .isArray */
16728 false /* .isOptional */
16729},
16730{
16731 UA_TYPENAME("PercentDataGood") /* .memberName */
16732 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
16733 offsetof(UA_AggregateConfiguration, percentDataGood) - offsetof(UA_AggregateConfiguration, percentDataBad) - sizeof(UA_Byte), /* .padding */
16734 false, /* .isArray */
16735 false /* .isOptional */
16736},
16737{
16738 UA_TYPENAME("UseSlopedExtrapolation") /* .memberName */
16739 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
16740 offsetof(UA_AggregateConfiguration, useSlopedExtrapolation) - offsetof(UA_AggregateConfiguration, percentDataGood) - sizeof(UA_Byte), /* .padding */
16741 false, /* .isArray */
16742 false /* .isOptional */
16743},};
16744
16745/* AggregateFilter */
16746static UA_DataTypeMember AggregateFilter_members[4] = {
16747{
16748 UA_TYPENAME("StartTime") /* .memberName */
16749 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
16750 0, /* .padding */
16751 false, /* .isArray */
16752 false /* .isOptional */
16753},
16754{
16755 UA_TYPENAME("AggregateType") /* .memberName */
16756 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
16757 offsetof(UA_AggregateFilter, aggregateType) - offsetof(UA_AggregateFilter, startTime) - sizeof(UA_DateTime), /* .padding */
16758 false, /* .isArray */
16759 false /* .isOptional */
16760},
16761{
16762 UA_TYPENAME("ProcessingInterval") /* .memberName */
16763 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
16764 offsetof(UA_AggregateFilter, processingInterval) - offsetof(UA_AggregateFilter, aggregateType) - sizeof(UA_NodeId), /* .padding */
16765 false, /* .isArray */
16766 false /* .isOptional */
16767},
16768{
16769 UA_TYPENAME("AggregateConfiguration") /* .memberName */
16770 &UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION], /* .memberType */
16771 offsetof(UA_AggregateFilter, aggregateConfiguration) - offsetof(UA_AggregateFilter, processingInterval) - sizeof(UA_Double), /* .padding */
16772 false, /* .isArray */
16773 false /* .isOptional */
16774},};
16775
16776/* EventFilterResult */
16777static UA_DataTypeMember EventFilterResult_members[3] = {
16778{
16779 UA_TYPENAME("SelectClauseResults") /* .memberName */
16780 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
16781 0, /* .padding */
16782 true, /* .isArray */
16783 false /* .isOptional */
16784},
16785{
16786 UA_TYPENAME("SelectClauseDiagnosticInfos") /* .memberName */
16787 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
16788 offsetof(UA_EventFilterResult, selectClauseDiagnosticInfosSize) - offsetof(UA_EventFilterResult, selectClauseResults) - sizeof(void *), /* .padding */
16789 true, /* .isArray */
16790 false /* .isOptional */
16791},
16792{
16793 UA_TYPENAME("WhereClauseResult") /* .memberName */
16794 &UA_TYPES[UA_TYPES_CONTENTFILTERRESULT], /* .memberType */
16795 offsetof(UA_EventFilterResult, whereClauseResult) - offsetof(UA_EventFilterResult, selectClauseDiagnosticInfos) - sizeof(void *), /* .padding */
16796 false, /* .isArray */
16797 false /* .isOptional */
16798},};
16799
16800/* AggregateFilterResult */
16801static UA_DataTypeMember AggregateFilterResult_members[3] = {
16802{
16803 UA_TYPENAME("RevisedStartTime") /* .memberName */
16804 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
16805 0, /* .padding */
16806 false, /* .isArray */
16807 false /* .isOptional */
16808},
16809{
16810 UA_TYPENAME("RevisedProcessingInterval") /* .memberName */
16811 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
16812 offsetof(UA_AggregateFilterResult, revisedProcessingInterval) - offsetof(UA_AggregateFilterResult, revisedStartTime) - sizeof(UA_DateTime), /* .padding */
16813 false, /* .isArray */
16814 false /* .isOptional */
16815},
16816{
16817 UA_TYPENAME("RevisedAggregateConfiguration") /* .memberName */
16818 &UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION], /* .memberType */
16819 offsetof(UA_AggregateFilterResult, revisedAggregateConfiguration) - offsetof(UA_AggregateFilterResult, revisedProcessingInterval) - sizeof(UA_Double), /* .padding */
16820 false, /* .isArray */
16821 false /* .isOptional */
16822},};
16823
16824/* MonitoringParameters */
16825static UA_DataTypeMember MonitoringParameters_members[5] = {
16826{
16827 UA_TYPENAME("ClientHandle") /* .memberName */
16828 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
16829 0, /* .padding */
16830 false, /* .isArray */
16831 false /* .isOptional */
16832},
16833{
16834 UA_TYPENAME("SamplingInterval") /* .memberName */
16835 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
16836 offsetof(UA_MonitoringParameters, samplingInterval) - offsetof(UA_MonitoringParameters, clientHandle) - sizeof(UA_UInt32), /* .padding */
16837 false, /* .isArray */
16838 false /* .isOptional */
16839},
16840{
16841 UA_TYPENAME("Filter") /* .memberName */
16842 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
16843 offsetof(UA_MonitoringParameters, filter) - offsetof(UA_MonitoringParameters, samplingInterval) - sizeof(UA_Double), /* .padding */
16844 false, /* .isArray */
16845 false /* .isOptional */
16846},
16847{
16848 UA_TYPENAME("QueueSize") /* .memberName */
16849 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
16850 offsetof(UA_MonitoringParameters, queueSize) - offsetof(UA_MonitoringParameters, filter) - sizeof(UA_ExtensionObject), /* .padding */
16851 false, /* .isArray */
16852 false /* .isOptional */
16853},
16854{
16855 UA_TYPENAME("DiscardOldest") /* .memberName */
16856 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
16857 offsetof(UA_MonitoringParameters, discardOldest) - offsetof(UA_MonitoringParameters, queueSize) - sizeof(UA_UInt32), /* .padding */
16858 false, /* .isArray */
16859 false /* .isOptional */
16860},};
16861
16862/* MonitoredItemCreateRequest */
16863static UA_DataTypeMember MonitoredItemCreateRequest_members[3] = {
16864{
16865 UA_TYPENAME("ItemToMonitor") /* .memberName */
16866 &UA_TYPES[UA_TYPES_READVALUEID], /* .memberType */
16867 0, /* .padding */
16868 false, /* .isArray */
16869 false /* .isOptional */
16870},
16871{
16872 UA_TYPENAME("MonitoringMode") /* .memberName */
16873 &UA_TYPES[UA_TYPES_MONITORINGMODE], /* .memberType */
16874 offsetof(UA_MonitoredItemCreateRequest, monitoringMode) - offsetof(UA_MonitoredItemCreateRequest, itemToMonitor) - sizeof(UA_ReadValueId), /* .padding */
16875 false, /* .isArray */
16876 false /* .isOptional */
16877},
16878{
16879 UA_TYPENAME("RequestedParameters") /* .memberName */
16880 &UA_TYPES[UA_TYPES_MONITORINGPARAMETERS], /* .memberType */
16881 offsetof(UA_MonitoredItemCreateRequest, requestedParameters) - offsetof(UA_MonitoredItemCreateRequest, monitoringMode) - sizeof(UA_MonitoringMode), /* .padding */
16882 false, /* .isArray */
16883 false /* .isOptional */
16884},};
16885
16886/* MonitoredItemCreateResult */
16887static UA_DataTypeMember MonitoredItemCreateResult_members[5] = {
16888{
16889 UA_TYPENAME("StatusCode") /* .memberName */
16890 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
16891 0, /* .padding */
16892 false, /* .isArray */
16893 false /* .isOptional */
16894},
16895{
16896 UA_TYPENAME("MonitoredItemId") /* .memberName */
16897 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
16898 offsetof(UA_MonitoredItemCreateResult, monitoredItemId) - offsetof(UA_MonitoredItemCreateResult, statusCode) - sizeof(UA_StatusCode), /* .padding */
16899 false, /* .isArray */
16900 false /* .isOptional */
16901},
16902{
16903 UA_TYPENAME("RevisedSamplingInterval") /* .memberName */
16904 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
16905 offsetof(UA_MonitoredItemCreateResult, revisedSamplingInterval) - offsetof(UA_MonitoredItemCreateResult, monitoredItemId) - sizeof(UA_UInt32), /* .padding */
16906 false, /* .isArray */
16907 false /* .isOptional */
16908},
16909{
16910 UA_TYPENAME("RevisedQueueSize") /* .memberName */
16911 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
16912 offsetof(UA_MonitoredItemCreateResult, revisedQueueSize) - offsetof(UA_MonitoredItemCreateResult, revisedSamplingInterval) - sizeof(UA_Double), /* .padding */
16913 false, /* .isArray */
16914 false /* .isOptional */
16915},
16916{
16917 UA_TYPENAME("FilterResult") /* .memberName */
16918 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
16919 offsetof(UA_MonitoredItemCreateResult, filterResult) - offsetof(UA_MonitoredItemCreateResult, revisedQueueSize) - sizeof(UA_UInt32), /* .padding */
16920 false, /* .isArray */
16921 false /* .isOptional */
16922},};
16923
16924/* CreateMonitoredItemsRequest */
16925static UA_DataTypeMember CreateMonitoredItemsRequest_members[4] = {
16926{
16927 UA_TYPENAME("RequestHeader") /* .memberName */
16928 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
16929 0, /* .padding */
16930 false, /* .isArray */
16931 false /* .isOptional */
16932},
16933{
16934 UA_TYPENAME("SubscriptionId") /* .memberName */
16935 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
16936 offsetof(UA_CreateMonitoredItemsRequest, subscriptionId) - offsetof(UA_CreateMonitoredItemsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
16937 false, /* .isArray */
16938 false /* .isOptional */
16939},
16940{
16941 UA_TYPENAME("TimestampsToReturn") /* .memberName */
16942 &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN], /* .memberType */
16943 offsetof(UA_CreateMonitoredItemsRequest, timestampsToReturn) - offsetof(UA_CreateMonitoredItemsRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */
16944 false, /* .isArray */
16945 false /* .isOptional */
16946},
16947{
16948 UA_TYPENAME("ItemsToCreate") /* .memberName */
16949 &UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST], /* .memberType */
16950 offsetof(UA_CreateMonitoredItemsRequest, itemsToCreateSize) - offsetof(UA_CreateMonitoredItemsRequest, timestampsToReturn) - sizeof(UA_TimestampsToReturn), /* .padding */
16951 true, /* .isArray */
16952 false /* .isOptional */
16953},};
16954
16955/* CreateMonitoredItemsResponse */
16956static UA_DataTypeMember CreateMonitoredItemsResponse_members[3] = {
16957{
16958 UA_TYPENAME("ResponseHeader") /* .memberName */
16959 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
16960 0, /* .padding */
16961 false, /* .isArray */
16962 false /* .isOptional */
16963},
16964{
16965 UA_TYPENAME("Results") /* .memberName */
16966 &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT], /* .memberType */
16967 offsetof(UA_CreateMonitoredItemsResponse, resultsSize) - offsetof(UA_CreateMonitoredItemsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
16968 true, /* .isArray */
16969 false /* .isOptional */
16970},
16971{
16972 UA_TYPENAME("DiagnosticInfos") /* .memberName */
16973 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
16974 offsetof(UA_CreateMonitoredItemsResponse, diagnosticInfosSize) - offsetof(UA_CreateMonitoredItemsResponse, results) - sizeof(void *), /* .padding */
16975 true, /* .isArray */
16976 false /* .isOptional */
16977},};
16978
16979/* MonitoredItemModifyRequest */
16980static UA_DataTypeMember MonitoredItemModifyRequest_members[2] = {
16981{
16982 UA_TYPENAME("MonitoredItemId") /* .memberName */
16983 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
16984 0, /* .padding */
16985 false, /* .isArray */
16986 false /* .isOptional */
16987},
16988{
16989 UA_TYPENAME("RequestedParameters") /* .memberName */
16990 &UA_TYPES[UA_TYPES_MONITORINGPARAMETERS], /* .memberType */
16991 offsetof(UA_MonitoredItemModifyRequest, requestedParameters) - offsetof(UA_MonitoredItemModifyRequest, monitoredItemId) - sizeof(UA_UInt32), /* .padding */
16992 false, /* .isArray */
16993 false /* .isOptional */
16994},};
16995
16996/* MonitoredItemModifyResult */
16997static UA_DataTypeMember MonitoredItemModifyResult_members[4] = {
16998{
16999 UA_TYPENAME("StatusCode") /* .memberName */
17000 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
17001 0, /* .padding */
17002 false, /* .isArray */
17003 false /* .isOptional */
17004},
17005{
17006 UA_TYPENAME("RevisedSamplingInterval") /* .memberName */
17007 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
17008 offsetof(UA_MonitoredItemModifyResult, revisedSamplingInterval) - offsetof(UA_MonitoredItemModifyResult, statusCode) - sizeof(UA_StatusCode), /* .padding */
17009 false, /* .isArray */
17010 false /* .isOptional */
17011},
17012{
17013 UA_TYPENAME("RevisedQueueSize") /* .memberName */
17014 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17015 offsetof(UA_MonitoredItemModifyResult, revisedQueueSize) - offsetof(UA_MonitoredItemModifyResult, revisedSamplingInterval) - sizeof(UA_Double), /* .padding */
17016 false, /* .isArray */
17017 false /* .isOptional */
17018},
17019{
17020 UA_TYPENAME("FilterResult") /* .memberName */
17021 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
17022 offsetof(UA_MonitoredItemModifyResult, filterResult) - offsetof(UA_MonitoredItemModifyResult, revisedQueueSize) - sizeof(UA_UInt32), /* .padding */
17023 false, /* .isArray */
17024 false /* .isOptional */
17025},};
17026
17027/* ModifyMonitoredItemsRequest */
17028static UA_DataTypeMember ModifyMonitoredItemsRequest_members[4] = {
17029{
17030 UA_TYPENAME("RequestHeader") /* .memberName */
17031 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
17032 0, /* .padding */
17033 false, /* .isArray */
17034 false /* .isOptional */
17035},
17036{
17037 UA_TYPENAME("SubscriptionId") /* .memberName */
17038 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17039 offsetof(UA_ModifyMonitoredItemsRequest, subscriptionId) - offsetof(UA_ModifyMonitoredItemsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
17040 false, /* .isArray */
17041 false /* .isOptional */
17042},
17043{
17044 UA_TYPENAME("TimestampsToReturn") /* .memberName */
17045 &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN], /* .memberType */
17046 offsetof(UA_ModifyMonitoredItemsRequest, timestampsToReturn) - offsetof(UA_ModifyMonitoredItemsRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */
17047 false, /* .isArray */
17048 false /* .isOptional */
17049},
17050{
17051 UA_TYPENAME("ItemsToModify") /* .memberName */
17052 &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST], /* .memberType */
17053 offsetof(UA_ModifyMonitoredItemsRequest, itemsToModifySize) - offsetof(UA_ModifyMonitoredItemsRequest, timestampsToReturn) - sizeof(UA_TimestampsToReturn), /* .padding */
17054 true, /* .isArray */
17055 false /* .isOptional */
17056},};
17057
17058/* ModifyMonitoredItemsResponse */
17059static UA_DataTypeMember ModifyMonitoredItemsResponse_members[3] = {
17060{
17061 UA_TYPENAME("ResponseHeader") /* .memberName */
17062 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
17063 0, /* .padding */
17064 false, /* .isArray */
17065 false /* .isOptional */
17066},
17067{
17068 UA_TYPENAME("Results") /* .memberName */
17069 &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT], /* .memberType */
17070 offsetof(UA_ModifyMonitoredItemsResponse, resultsSize) - offsetof(UA_ModifyMonitoredItemsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
17071 true, /* .isArray */
17072 false /* .isOptional */
17073},
17074{
17075 UA_TYPENAME("DiagnosticInfos") /* .memberName */
17076 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
17077 offsetof(UA_ModifyMonitoredItemsResponse, diagnosticInfosSize) - offsetof(UA_ModifyMonitoredItemsResponse, results) - sizeof(void *), /* .padding */
17078 true, /* .isArray */
17079 false /* .isOptional */
17080},};
17081
17082/* SetMonitoringModeRequest */
17083static UA_DataTypeMember SetMonitoringModeRequest_members[4] = {
17084{
17085 UA_TYPENAME("RequestHeader") /* .memberName */
17086 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
17087 0, /* .padding */
17088 false, /* .isArray */
17089 false /* .isOptional */
17090},
17091{
17092 UA_TYPENAME("SubscriptionId") /* .memberName */
17093 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17094 offsetof(UA_SetMonitoringModeRequest, subscriptionId) - offsetof(UA_SetMonitoringModeRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
17095 false, /* .isArray */
17096 false /* .isOptional */
17097},
17098{
17099 UA_TYPENAME("MonitoringMode") /* .memberName */
17100 &UA_TYPES[UA_TYPES_MONITORINGMODE], /* .memberType */
17101 offsetof(UA_SetMonitoringModeRequest, monitoringMode) - offsetof(UA_SetMonitoringModeRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */
17102 false, /* .isArray */
17103 false /* .isOptional */
17104},
17105{
17106 UA_TYPENAME("MonitoredItemIds") /* .memberName */
17107 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17108 offsetof(UA_SetMonitoringModeRequest, monitoredItemIdsSize) - offsetof(UA_SetMonitoringModeRequest, monitoringMode) - sizeof(UA_MonitoringMode), /* .padding */
17109 true, /* .isArray */
17110 false /* .isOptional */
17111},};
17112
17113/* SetMonitoringModeResponse */
17114static UA_DataTypeMember SetMonitoringModeResponse_members[3] = {
17115{
17116 UA_TYPENAME("ResponseHeader") /* .memberName */
17117 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
17118 0, /* .padding */
17119 false, /* .isArray */
17120 false /* .isOptional */
17121},
17122{
17123 UA_TYPENAME("Results") /* .memberName */
17124 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
17125 offsetof(UA_SetMonitoringModeResponse, resultsSize) - offsetof(UA_SetMonitoringModeResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
17126 true, /* .isArray */
17127 false /* .isOptional */
17128},
17129{
17130 UA_TYPENAME("DiagnosticInfos") /* .memberName */
17131 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
17132 offsetof(UA_SetMonitoringModeResponse, diagnosticInfosSize) - offsetof(UA_SetMonitoringModeResponse, results) - sizeof(void *), /* .padding */
17133 true, /* .isArray */
17134 false /* .isOptional */
17135},};
17136
17137/* SetTriggeringRequest */
17138static UA_DataTypeMember SetTriggeringRequest_members[5] = {
17139{
17140 UA_TYPENAME("RequestHeader") /* .memberName */
17141 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
17142 0, /* .padding */
17143 false, /* .isArray */
17144 false /* .isOptional */
17145},
17146{
17147 UA_TYPENAME("SubscriptionId") /* .memberName */
17148 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17149 offsetof(UA_SetTriggeringRequest, subscriptionId) - offsetof(UA_SetTriggeringRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
17150 false, /* .isArray */
17151 false /* .isOptional */
17152},
17153{
17154 UA_TYPENAME("TriggeringItemId") /* .memberName */
17155 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17156 offsetof(UA_SetTriggeringRequest, triggeringItemId) - offsetof(UA_SetTriggeringRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */
17157 false, /* .isArray */
17158 false /* .isOptional */
17159},
17160{
17161 UA_TYPENAME("LinksToAdd") /* .memberName */
17162 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17163 offsetof(UA_SetTriggeringRequest, linksToAddSize) - offsetof(UA_SetTriggeringRequest, triggeringItemId) - sizeof(UA_UInt32), /* .padding */
17164 true, /* .isArray */
17165 false /* .isOptional */
17166},
17167{
17168 UA_TYPENAME("LinksToRemove") /* .memberName */
17169 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17170 offsetof(UA_SetTriggeringRequest, linksToRemoveSize) - offsetof(UA_SetTriggeringRequest, linksToAdd) - sizeof(void *), /* .padding */
17171 true, /* .isArray */
17172 false /* .isOptional */
17173},};
17174
17175/* SetTriggeringResponse */
17176static UA_DataTypeMember SetTriggeringResponse_members[5] = {
17177{
17178 UA_TYPENAME("ResponseHeader") /* .memberName */
17179 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
17180 0, /* .padding */
17181 false, /* .isArray */
17182 false /* .isOptional */
17183},
17184{
17185 UA_TYPENAME("AddResults") /* .memberName */
17186 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
17187 offsetof(UA_SetTriggeringResponse, addResultsSize) - offsetof(UA_SetTriggeringResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
17188 true, /* .isArray */
17189 false /* .isOptional */
17190},
17191{
17192 UA_TYPENAME("AddDiagnosticInfos") /* .memberName */
17193 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
17194 offsetof(UA_SetTriggeringResponse, addDiagnosticInfosSize) - offsetof(UA_SetTriggeringResponse, addResults) - sizeof(void *), /* .padding */
17195 true, /* .isArray */
17196 false /* .isOptional */
17197},
17198{
17199 UA_TYPENAME("RemoveResults") /* .memberName */
17200 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
17201 offsetof(UA_SetTriggeringResponse, removeResultsSize) - offsetof(UA_SetTriggeringResponse, addDiagnosticInfos) - sizeof(void *), /* .padding */
17202 true, /* .isArray */
17203 false /* .isOptional */
17204},
17205{
17206 UA_TYPENAME("RemoveDiagnosticInfos") /* .memberName */
17207 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
17208 offsetof(UA_SetTriggeringResponse, removeDiagnosticInfosSize) - offsetof(UA_SetTriggeringResponse, removeResults) - sizeof(void *), /* .padding */
17209 true, /* .isArray */
17210 false /* .isOptional */
17211},};
17212
17213/* DeleteMonitoredItemsRequest */
17214static UA_DataTypeMember DeleteMonitoredItemsRequest_members[3] = {
17215{
17216 UA_TYPENAME("RequestHeader") /* .memberName */
17217 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
17218 0, /* .padding */
17219 false, /* .isArray */
17220 false /* .isOptional */
17221},
17222{
17223 UA_TYPENAME("SubscriptionId") /* .memberName */
17224 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17225 offsetof(UA_DeleteMonitoredItemsRequest, subscriptionId) - offsetof(UA_DeleteMonitoredItemsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
17226 false, /* .isArray */
17227 false /* .isOptional */
17228},
17229{
17230 UA_TYPENAME("MonitoredItemIds") /* .memberName */
17231 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17232 offsetof(UA_DeleteMonitoredItemsRequest, monitoredItemIdsSize) - offsetof(UA_DeleteMonitoredItemsRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */
17233 true, /* .isArray */
17234 false /* .isOptional */
17235},};
17236
17237/* DeleteMonitoredItemsResponse */
17238static UA_DataTypeMember DeleteMonitoredItemsResponse_members[3] = {
17239{
17240 UA_TYPENAME("ResponseHeader") /* .memberName */
17241 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
17242 0, /* .padding */
17243 false, /* .isArray */
17244 false /* .isOptional */
17245},
17246{
17247 UA_TYPENAME("Results") /* .memberName */
17248 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
17249 offsetof(UA_DeleteMonitoredItemsResponse, resultsSize) - offsetof(UA_DeleteMonitoredItemsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
17250 true, /* .isArray */
17251 false /* .isOptional */
17252},
17253{
17254 UA_TYPENAME("DiagnosticInfos") /* .memberName */
17255 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
17256 offsetof(UA_DeleteMonitoredItemsResponse, diagnosticInfosSize) - offsetof(UA_DeleteMonitoredItemsResponse, results) - sizeof(void *), /* .padding */
17257 true, /* .isArray */
17258 false /* .isOptional */
17259},};
17260
17261/* CreateSubscriptionRequest */
17262static UA_DataTypeMember CreateSubscriptionRequest_members[7] = {
17263{
17264 UA_TYPENAME("RequestHeader") /* .memberName */
17265 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
17266 0, /* .padding */
17267 false, /* .isArray */
17268 false /* .isOptional */
17269},
17270{
17271 UA_TYPENAME("RequestedPublishingInterval") /* .memberName */
17272 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
17273 offsetof(UA_CreateSubscriptionRequest, requestedPublishingInterval) - offsetof(UA_CreateSubscriptionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
17274 false, /* .isArray */
17275 false /* .isOptional */
17276},
17277{
17278 UA_TYPENAME("RequestedLifetimeCount") /* .memberName */
17279 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17280 offsetof(UA_CreateSubscriptionRequest, requestedLifetimeCount) - offsetof(UA_CreateSubscriptionRequest, requestedPublishingInterval) - sizeof(UA_Double), /* .padding */
17281 false, /* .isArray */
17282 false /* .isOptional */
17283},
17284{
17285 UA_TYPENAME("RequestedMaxKeepAliveCount") /* .memberName */
17286 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17287 offsetof(UA_CreateSubscriptionRequest, requestedMaxKeepAliveCount) - offsetof(UA_CreateSubscriptionRequest, requestedLifetimeCount) - sizeof(UA_UInt32), /* .padding */
17288 false, /* .isArray */
17289 false /* .isOptional */
17290},
17291{
17292 UA_TYPENAME("MaxNotificationsPerPublish") /* .memberName */
17293 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17294 offsetof(UA_CreateSubscriptionRequest, maxNotificationsPerPublish) - offsetof(UA_CreateSubscriptionRequest, requestedMaxKeepAliveCount) - sizeof(UA_UInt32), /* .padding */
17295 false, /* .isArray */
17296 false /* .isOptional */
17297},
17298{
17299 UA_TYPENAME("PublishingEnabled") /* .memberName */
17300 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
17301 offsetof(UA_CreateSubscriptionRequest, publishingEnabled) - offsetof(UA_CreateSubscriptionRequest, maxNotificationsPerPublish) - sizeof(UA_UInt32), /* .padding */
17302 false, /* .isArray */
17303 false /* .isOptional */
17304},
17305{
17306 UA_TYPENAME("Priority") /* .memberName */
17307 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
17308 offsetof(UA_CreateSubscriptionRequest, priority) - offsetof(UA_CreateSubscriptionRequest, publishingEnabled) - sizeof(UA_Boolean), /* .padding */
17309 false, /* .isArray */
17310 false /* .isOptional */
17311},};
17312
17313/* CreateSubscriptionResponse */
17314static UA_DataTypeMember CreateSubscriptionResponse_members[5] = {
17315{
17316 UA_TYPENAME("ResponseHeader") /* .memberName */
17317 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
17318 0, /* .padding */
17319 false, /* .isArray */
17320 false /* .isOptional */
17321},
17322{
17323 UA_TYPENAME("SubscriptionId") /* .memberName */
17324 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17325 offsetof(UA_CreateSubscriptionResponse, subscriptionId) - offsetof(UA_CreateSubscriptionResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
17326 false, /* .isArray */
17327 false /* .isOptional */
17328},
17329{
17330 UA_TYPENAME("RevisedPublishingInterval") /* .memberName */
17331 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
17332 offsetof(UA_CreateSubscriptionResponse, revisedPublishingInterval) - offsetof(UA_CreateSubscriptionResponse, subscriptionId) - sizeof(UA_UInt32), /* .padding */
17333 false, /* .isArray */
17334 false /* .isOptional */
17335},
17336{
17337 UA_TYPENAME("RevisedLifetimeCount") /* .memberName */
17338 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17339 offsetof(UA_CreateSubscriptionResponse, revisedLifetimeCount) - offsetof(UA_CreateSubscriptionResponse, revisedPublishingInterval) - sizeof(UA_Double), /* .padding */
17340 false, /* .isArray */
17341 false /* .isOptional */
17342},
17343{
17344 UA_TYPENAME("RevisedMaxKeepAliveCount") /* .memberName */
17345 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17346 offsetof(UA_CreateSubscriptionResponse, revisedMaxKeepAliveCount) - offsetof(UA_CreateSubscriptionResponse, revisedLifetimeCount) - sizeof(UA_UInt32), /* .padding */
17347 false, /* .isArray */
17348 false /* .isOptional */
17349},};
17350
17351/* ModifySubscriptionRequest */
17352static UA_DataTypeMember ModifySubscriptionRequest_members[7] = {
17353{
17354 UA_TYPENAME("RequestHeader") /* .memberName */
17355 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
17356 0, /* .padding */
17357 false, /* .isArray */
17358 false /* .isOptional */
17359},
17360{
17361 UA_TYPENAME("SubscriptionId") /* .memberName */
17362 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17363 offsetof(UA_ModifySubscriptionRequest, subscriptionId) - offsetof(UA_ModifySubscriptionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
17364 false, /* .isArray */
17365 false /* .isOptional */
17366},
17367{
17368 UA_TYPENAME("RequestedPublishingInterval") /* .memberName */
17369 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
17370 offsetof(UA_ModifySubscriptionRequest, requestedPublishingInterval) - offsetof(UA_ModifySubscriptionRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */
17371 false, /* .isArray */
17372 false /* .isOptional */
17373},
17374{
17375 UA_TYPENAME("RequestedLifetimeCount") /* .memberName */
17376 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17377 offsetof(UA_ModifySubscriptionRequest, requestedLifetimeCount) - offsetof(UA_ModifySubscriptionRequest, requestedPublishingInterval) - sizeof(UA_Double), /* .padding */
17378 false, /* .isArray */
17379 false /* .isOptional */
17380},
17381{
17382 UA_TYPENAME("RequestedMaxKeepAliveCount") /* .memberName */
17383 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17384 offsetof(UA_ModifySubscriptionRequest, requestedMaxKeepAliveCount) - offsetof(UA_ModifySubscriptionRequest, requestedLifetimeCount) - sizeof(UA_UInt32), /* .padding */
17385 false, /* .isArray */
17386 false /* .isOptional */
17387},
17388{
17389 UA_TYPENAME("MaxNotificationsPerPublish") /* .memberName */
17390 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17391 offsetof(UA_ModifySubscriptionRequest, maxNotificationsPerPublish) - offsetof(UA_ModifySubscriptionRequest, requestedMaxKeepAliveCount) - sizeof(UA_UInt32), /* .padding */
17392 false, /* .isArray */
17393 false /* .isOptional */
17394},
17395{
17396 UA_TYPENAME("Priority") /* .memberName */
17397 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
17398 offsetof(UA_ModifySubscriptionRequest, priority) - offsetof(UA_ModifySubscriptionRequest, maxNotificationsPerPublish) - sizeof(UA_UInt32), /* .padding */
17399 false, /* .isArray */
17400 false /* .isOptional */
17401},};
17402
17403/* ModifySubscriptionResponse */
17404static UA_DataTypeMember ModifySubscriptionResponse_members[4] = {
17405{
17406 UA_TYPENAME("ResponseHeader") /* .memberName */
17407 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
17408 0, /* .padding */
17409 false, /* .isArray */
17410 false /* .isOptional */
17411},
17412{
17413 UA_TYPENAME("RevisedPublishingInterval") /* .memberName */
17414 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
17415 offsetof(UA_ModifySubscriptionResponse, revisedPublishingInterval) - offsetof(UA_ModifySubscriptionResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
17416 false, /* .isArray */
17417 false /* .isOptional */
17418},
17419{
17420 UA_TYPENAME("RevisedLifetimeCount") /* .memberName */
17421 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17422 offsetof(UA_ModifySubscriptionResponse, revisedLifetimeCount) - offsetof(UA_ModifySubscriptionResponse, revisedPublishingInterval) - sizeof(UA_Double), /* .padding */
17423 false, /* .isArray */
17424 false /* .isOptional */
17425},
17426{
17427 UA_TYPENAME("RevisedMaxKeepAliveCount") /* .memberName */
17428 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17429 offsetof(UA_ModifySubscriptionResponse, revisedMaxKeepAliveCount) - offsetof(UA_ModifySubscriptionResponse, revisedLifetimeCount) - sizeof(UA_UInt32), /* .padding */
17430 false, /* .isArray */
17431 false /* .isOptional */
17432},};
17433
17434/* SetPublishingModeRequest */
17435static UA_DataTypeMember SetPublishingModeRequest_members[3] = {
17436{
17437 UA_TYPENAME("RequestHeader") /* .memberName */
17438 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
17439 0, /* .padding */
17440 false, /* .isArray */
17441 false /* .isOptional */
17442},
17443{
17444 UA_TYPENAME("PublishingEnabled") /* .memberName */
17445 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
17446 offsetof(UA_SetPublishingModeRequest, publishingEnabled) - offsetof(UA_SetPublishingModeRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
17447 false, /* .isArray */
17448 false /* .isOptional */
17449},
17450{
17451 UA_TYPENAME("SubscriptionIds") /* .memberName */
17452 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17453 offsetof(UA_SetPublishingModeRequest, subscriptionIdsSize) - offsetof(UA_SetPublishingModeRequest, publishingEnabled) - sizeof(UA_Boolean), /* .padding */
17454 true, /* .isArray */
17455 false /* .isOptional */
17456},};
17457
17458/* SetPublishingModeResponse */
17459static UA_DataTypeMember SetPublishingModeResponse_members[3] = {
17460{
17461 UA_TYPENAME("ResponseHeader") /* .memberName */
17462 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
17463 0, /* .padding */
17464 false, /* .isArray */
17465 false /* .isOptional */
17466},
17467{
17468 UA_TYPENAME("Results") /* .memberName */
17469 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
17470 offsetof(UA_SetPublishingModeResponse, resultsSize) - offsetof(UA_SetPublishingModeResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
17471 true, /* .isArray */
17472 false /* .isOptional */
17473},
17474{
17475 UA_TYPENAME("DiagnosticInfos") /* .memberName */
17476 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
17477 offsetof(UA_SetPublishingModeResponse, diagnosticInfosSize) - offsetof(UA_SetPublishingModeResponse, results) - sizeof(void *), /* .padding */
17478 true, /* .isArray */
17479 false /* .isOptional */
17480},};
17481
17482/* NotificationMessage */
17483static UA_DataTypeMember NotificationMessage_members[3] = {
17484{
17485 UA_TYPENAME("SequenceNumber") /* .memberName */
17486 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17487 0, /* .padding */
17488 false, /* .isArray */
17489 false /* .isOptional */
17490},
17491{
17492 UA_TYPENAME("PublishTime") /* .memberName */
17493 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
17494 offsetof(UA_NotificationMessage, publishTime) - offsetof(UA_NotificationMessage, sequenceNumber) - sizeof(UA_UInt32), /* .padding */
17495 false, /* .isArray */
17496 false /* .isOptional */
17497},
17498{
17499 UA_TYPENAME("NotificationData") /* .memberName */
17500 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
17501 offsetof(UA_NotificationMessage, notificationDataSize) - offsetof(UA_NotificationMessage, publishTime) - sizeof(UA_DateTime), /* .padding */
17502 true, /* .isArray */
17503 false /* .isOptional */
17504},};
17505
17506/* MonitoredItemNotification */
17507static UA_DataTypeMember MonitoredItemNotification_members[2] = {
17508{
17509 UA_TYPENAME("ClientHandle") /* .memberName */
17510 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17511 0, /* .padding */
17512 false, /* .isArray */
17513 false /* .isOptional */
17514},
17515{
17516 UA_TYPENAME("Value") /* .memberName */
17517 &UA_TYPES[UA_TYPES_DATAVALUE], /* .memberType */
17518 offsetof(UA_MonitoredItemNotification, value) - offsetof(UA_MonitoredItemNotification, clientHandle) - sizeof(UA_UInt32), /* .padding */
17519 false, /* .isArray */
17520 false /* .isOptional */
17521},};
17522
17523/* EventFieldList */
17524static UA_DataTypeMember EventFieldList_members[2] = {
17525{
17526 UA_TYPENAME("ClientHandle") /* .memberName */
17527 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17528 0, /* .padding */
17529 false, /* .isArray */
17530 false /* .isOptional */
17531},
17532{
17533 UA_TYPENAME("EventFields") /* .memberName */
17534 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
17535 offsetof(UA_EventFieldList, eventFieldsSize) - offsetof(UA_EventFieldList, clientHandle) - sizeof(UA_UInt32), /* .padding */
17536 true, /* .isArray */
17537 false /* .isOptional */
17538},};
17539
17540/* HistoryEventFieldList */
17541static UA_DataTypeMember HistoryEventFieldList_members[1] = {
17542{
17543 UA_TYPENAME("EventFields") /* .memberName */
17544 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
17545 0, /* .padding */
17546 true, /* .isArray */
17547 false /* .isOptional */
17548},};
17549
17550/* StatusChangeNotification */
17551static UA_DataTypeMember StatusChangeNotification_members[2] = {
17552{
17553 UA_TYPENAME("Status") /* .memberName */
17554 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
17555 0, /* .padding */
17556 false, /* .isArray */
17557 false /* .isOptional */
17558},
17559{
17560 UA_TYPENAME("DiagnosticInfo") /* .memberName */
17561 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
17562 offsetof(UA_StatusChangeNotification, diagnosticInfo) - offsetof(UA_StatusChangeNotification, status) - sizeof(UA_StatusCode), /* .padding */
17563 false, /* .isArray */
17564 false /* .isOptional */
17565},};
17566
17567/* SubscriptionAcknowledgement */
17568static UA_DataTypeMember SubscriptionAcknowledgement_members[2] = {
17569{
17570 UA_TYPENAME("SubscriptionId") /* .memberName */
17571 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17572 0, /* .padding */
17573 false, /* .isArray */
17574 false /* .isOptional */
17575},
17576{
17577 UA_TYPENAME("SequenceNumber") /* .memberName */
17578 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17579 offsetof(UA_SubscriptionAcknowledgement, sequenceNumber) - offsetof(UA_SubscriptionAcknowledgement, subscriptionId) - sizeof(UA_UInt32), /* .padding */
17580 false, /* .isArray */
17581 false /* .isOptional */
17582},};
17583
17584/* PublishRequest */
17585static UA_DataTypeMember PublishRequest_members[2] = {
17586{
17587 UA_TYPENAME("RequestHeader") /* .memberName */
17588 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
17589 0, /* .padding */
17590 false, /* .isArray */
17591 false /* .isOptional */
17592},
17593{
17594 UA_TYPENAME("SubscriptionAcknowledgements") /* .memberName */
17595 &UA_TYPES[UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT], /* .memberType */
17596 offsetof(UA_PublishRequest, subscriptionAcknowledgementsSize) - offsetof(UA_PublishRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
17597 true, /* .isArray */
17598 false /* .isOptional */
17599},};
17600
17601/* PublishResponse */
17602static UA_DataTypeMember PublishResponse_members[7] = {
17603{
17604 UA_TYPENAME("ResponseHeader") /* .memberName */
17605 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
17606 0, /* .padding */
17607 false, /* .isArray */
17608 false /* .isOptional */
17609},
17610{
17611 UA_TYPENAME("SubscriptionId") /* .memberName */
17612 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17613 offsetof(UA_PublishResponse, subscriptionId) - offsetof(UA_PublishResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
17614 false, /* .isArray */
17615 false /* .isOptional */
17616},
17617{
17618 UA_TYPENAME("AvailableSequenceNumbers") /* .memberName */
17619 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17620 offsetof(UA_PublishResponse, availableSequenceNumbersSize) - offsetof(UA_PublishResponse, subscriptionId) - sizeof(UA_UInt32), /* .padding */
17621 true, /* .isArray */
17622 false /* .isOptional */
17623},
17624{
17625 UA_TYPENAME("MoreNotifications") /* .memberName */
17626 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
17627 offsetof(UA_PublishResponse, moreNotifications) - offsetof(UA_PublishResponse, availableSequenceNumbers) - sizeof(void *), /* .padding */
17628 false, /* .isArray */
17629 false /* .isOptional */
17630},
17631{
17632 UA_TYPENAME("NotificationMessage") /* .memberName */
17633 &UA_TYPES[UA_TYPES_NOTIFICATIONMESSAGE], /* .memberType */
17634 offsetof(UA_PublishResponse, notificationMessage) - offsetof(UA_PublishResponse, moreNotifications) - sizeof(UA_Boolean), /* .padding */
17635 false, /* .isArray */
17636 false /* .isOptional */
17637},
17638{
17639 UA_TYPENAME("Results") /* .memberName */
17640 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
17641 offsetof(UA_PublishResponse, resultsSize) - offsetof(UA_PublishResponse, notificationMessage) - sizeof(UA_NotificationMessage), /* .padding */
17642 true, /* .isArray */
17643 false /* .isOptional */
17644},
17645{
17646 UA_TYPENAME("DiagnosticInfos") /* .memberName */
17647 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
17648 offsetof(UA_PublishResponse, diagnosticInfosSize) - offsetof(UA_PublishResponse, results) - sizeof(void *), /* .padding */
17649 true, /* .isArray */
17650 false /* .isOptional */
17651},};
17652
17653/* RepublishRequest */
17654static UA_DataTypeMember RepublishRequest_members[3] = {
17655{
17656 UA_TYPENAME("RequestHeader") /* .memberName */
17657 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
17658 0, /* .padding */
17659 false, /* .isArray */
17660 false /* .isOptional */
17661},
17662{
17663 UA_TYPENAME("SubscriptionId") /* .memberName */
17664 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17665 offsetof(UA_RepublishRequest, subscriptionId) - offsetof(UA_RepublishRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
17666 false, /* .isArray */
17667 false /* .isOptional */
17668},
17669{
17670 UA_TYPENAME("RetransmitSequenceNumber") /* .memberName */
17671 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17672 offsetof(UA_RepublishRequest, retransmitSequenceNumber) - offsetof(UA_RepublishRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */
17673 false, /* .isArray */
17674 false /* .isOptional */
17675},};
17676
17677/* RepublishResponse */
17678static UA_DataTypeMember RepublishResponse_members[2] = {
17679{
17680 UA_TYPENAME("ResponseHeader") /* .memberName */
17681 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
17682 0, /* .padding */
17683 false, /* .isArray */
17684 false /* .isOptional */
17685},
17686{
17687 UA_TYPENAME("NotificationMessage") /* .memberName */
17688 &UA_TYPES[UA_TYPES_NOTIFICATIONMESSAGE], /* .memberType */
17689 offsetof(UA_RepublishResponse, notificationMessage) - offsetof(UA_RepublishResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
17690 false, /* .isArray */
17691 false /* .isOptional */
17692},};
17693
17694/* TransferResult */
17695static UA_DataTypeMember TransferResult_members[2] = {
17696{
17697 UA_TYPENAME("StatusCode") /* .memberName */
17698 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
17699 0, /* .padding */
17700 false, /* .isArray */
17701 false /* .isOptional */
17702},
17703{
17704 UA_TYPENAME("AvailableSequenceNumbers") /* .memberName */
17705 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17706 offsetof(UA_TransferResult, availableSequenceNumbersSize) - offsetof(UA_TransferResult, statusCode) - sizeof(UA_StatusCode), /* .padding */
17707 true, /* .isArray */
17708 false /* .isOptional */
17709},};
17710
17711/* TransferSubscriptionsRequest */
17712static UA_DataTypeMember TransferSubscriptionsRequest_members[3] = {
17713{
17714 UA_TYPENAME("RequestHeader") /* .memberName */
17715 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
17716 0, /* .padding */
17717 false, /* .isArray */
17718 false /* .isOptional */
17719},
17720{
17721 UA_TYPENAME("SubscriptionIds") /* .memberName */
17722 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17723 offsetof(UA_TransferSubscriptionsRequest, subscriptionIdsSize) - offsetof(UA_TransferSubscriptionsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
17724 true, /* .isArray */
17725 false /* .isOptional */
17726},
17727{
17728 UA_TYPENAME("SendInitialValues") /* .memberName */
17729 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
17730 offsetof(UA_TransferSubscriptionsRequest, sendInitialValues) - offsetof(UA_TransferSubscriptionsRequest, subscriptionIds) - sizeof(void *), /* .padding */
17731 false, /* .isArray */
17732 false /* .isOptional */
17733},};
17734
17735/* TransferSubscriptionsResponse */
17736static UA_DataTypeMember TransferSubscriptionsResponse_members[3] = {
17737{
17738 UA_TYPENAME("ResponseHeader") /* .memberName */
17739 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
17740 0, /* .padding */
17741 false, /* .isArray */
17742 false /* .isOptional */
17743},
17744{
17745 UA_TYPENAME("Results") /* .memberName */
17746 &UA_TYPES[UA_TYPES_TRANSFERRESULT], /* .memberType */
17747 offsetof(UA_TransferSubscriptionsResponse, resultsSize) - offsetof(UA_TransferSubscriptionsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
17748 true, /* .isArray */
17749 false /* .isOptional */
17750},
17751{
17752 UA_TYPENAME("DiagnosticInfos") /* .memberName */
17753 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
17754 offsetof(UA_TransferSubscriptionsResponse, diagnosticInfosSize) - offsetof(UA_TransferSubscriptionsResponse, results) - sizeof(void *), /* .padding */
17755 true, /* .isArray */
17756 false /* .isOptional */
17757},};
17758
17759/* DeleteSubscriptionsRequest */
17760static UA_DataTypeMember DeleteSubscriptionsRequest_members[2] = {
17761{
17762 UA_TYPENAME("RequestHeader") /* .memberName */
17763 &UA_TYPES[UA_TYPES_REQUESTHEADER], /* .memberType */
17764 0, /* .padding */
17765 false, /* .isArray */
17766 false /* .isOptional */
17767},
17768{
17769 UA_TYPENAME("SubscriptionIds") /* .memberName */
17770 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17771 offsetof(UA_DeleteSubscriptionsRequest, subscriptionIdsSize) - offsetof(UA_DeleteSubscriptionsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */
17772 true, /* .isArray */
17773 false /* .isOptional */
17774},};
17775
17776/* DeleteSubscriptionsResponse */
17777static UA_DataTypeMember DeleteSubscriptionsResponse_members[3] = {
17778{
17779 UA_TYPENAME("ResponseHeader") /* .memberName */
17780 &UA_TYPES[UA_TYPES_RESPONSEHEADER], /* .memberType */
17781 0, /* .padding */
17782 false, /* .isArray */
17783 false /* .isOptional */
17784},
17785{
17786 UA_TYPENAME("Results") /* .memberName */
17787 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
17788 offsetof(UA_DeleteSubscriptionsResponse, resultsSize) - offsetof(UA_DeleteSubscriptionsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */
17789 true, /* .isArray */
17790 false /* .isOptional */
17791},
17792{
17793 UA_TYPENAME("DiagnosticInfos") /* .memberName */
17794 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
17795 offsetof(UA_DeleteSubscriptionsResponse, diagnosticInfosSize) - offsetof(UA_DeleteSubscriptionsResponse, results) - sizeof(void *), /* .padding */
17796 true, /* .isArray */
17797 false /* .isOptional */
17798},};
17799
17800/* BuildInfo */
17801static UA_DataTypeMember BuildInfo_members[6] = {
17802{
17803 UA_TYPENAME("ProductUri") /* .memberName */
17804 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
17805 0, /* .padding */
17806 false, /* .isArray */
17807 false /* .isOptional */
17808},
17809{
17810 UA_TYPENAME("ManufacturerName") /* .memberName */
17811 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
17812 offsetof(UA_BuildInfo, manufacturerName) - offsetof(UA_BuildInfo, productUri) - sizeof(UA_String), /* .padding */
17813 false, /* .isArray */
17814 false /* .isOptional */
17815},
17816{
17817 UA_TYPENAME("ProductName") /* .memberName */
17818 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
17819 offsetof(UA_BuildInfo, productName) - offsetof(UA_BuildInfo, manufacturerName) - sizeof(UA_String), /* .padding */
17820 false, /* .isArray */
17821 false /* .isOptional */
17822},
17823{
17824 UA_TYPENAME("SoftwareVersion") /* .memberName */
17825 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
17826 offsetof(UA_BuildInfo, softwareVersion) - offsetof(UA_BuildInfo, productName) - sizeof(UA_String), /* .padding */
17827 false, /* .isArray */
17828 false /* .isOptional */
17829},
17830{
17831 UA_TYPENAME("BuildNumber") /* .memberName */
17832 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
17833 offsetof(UA_BuildInfo, buildNumber) - offsetof(UA_BuildInfo, softwareVersion) - sizeof(UA_String), /* .padding */
17834 false, /* .isArray */
17835 false /* .isOptional */
17836},
17837{
17838 UA_TYPENAME("BuildDate") /* .memberName */
17839 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
17840 offsetof(UA_BuildInfo, buildDate) - offsetof(UA_BuildInfo, buildNumber) - sizeof(UA_String), /* .padding */
17841 false, /* .isArray */
17842 false /* .isOptional */
17843},};
17844
17845/* RedundancySupport */
17846#define RedundancySupport_members NULL
17847
17848/* ServerState */
17849#define ServerState_members NULL
17850
17851/* RedundantServerDataType */
17852static UA_DataTypeMember RedundantServerDataType_members[3] = {
17853{
17854 UA_TYPENAME("ServerId") /* .memberName */
17855 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
17856 0, /* .padding */
17857 false, /* .isArray */
17858 false /* .isOptional */
17859},
17860{
17861 UA_TYPENAME("ServiceLevel") /* .memberName */
17862 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
17863 offsetof(UA_RedundantServerDataType, serviceLevel) - offsetof(UA_RedundantServerDataType, serverId) - sizeof(UA_String), /* .padding */
17864 false, /* .isArray */
17865 false /* .isOptional */
17866},
17867{
17868 UA_TYPENAME("ServerState") /* .memberName */
17869 &UA_TYPES[UA_TYPES_SERVERSTATE], /* .memberType */
17870 offsetof(UA_RedundantServerDataType, serverState) - offsetof(UA_RedundantServerDataType, serviceLevel) - sizeof(UA_Byte), /* .padding */
17871 false, /* .isArray */
17872 false /* .isOptional */
17873},};
17874
17875/* EndpointUrlListDataType */
17876static UA_DataTypeMember EndpointUrlListDataType_members[1] = {
17877{
17878 UA_TYPENAME("EndpointUrlList") /* .memberName */
17879 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
17880 0, /* .padding */
17881 true, /* .isArray */
17882 false /* .isOptional */
17883},};
17884
17885/* NetworkGroupDataType */
17886static UA_DataTypeMember NetworkGroupDataType_members[2] = {
17887{
17888 UA_TYPENAME("ServerUri") /* .memberName */
17889 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
17890 0, /* .padding */
17891 false, /* .isArray */
17892 false /* .isOptional */
17893},
17894{
17895 UA_TYPENAME("NetworkPaths") /* .memberName */
17896 &UA_TYPES[UA_TYPES_ENDPOINTURLLISTDATATYPE], /* .memberType */
17897 offsetof(UA_NetworkGroupDataType, networkPathsSize) - offsetof(UA_NetworkGroupDataType, serverUri) - sizeof(UA_String), /* .padding */
17898 true, /* .isArray */
17899 false /* .isOptional */
17900},};
17901
17902/* SamplingIntervalDiagnosticsDataType */
17903static UA_DataTypeMember SamplingIntervalDiagnosticsDataType_members[4] = {
17904{
17905 UA_TYPENAME("SamplingInterval") /* .memberName */
17906 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
17907 0, /* .padding */
17908 false, /* .isArray */
17909 false /* .isOptional */
17910},
17911{
17912 UA_TYPENAME("MonitoredItemCount") /* .memberName */
17913 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17914 offsetof(UA_SamplingIntervalDiagnosticsDataType, monitoredItemCount) - offsetof(UA_SamplingIntervalDiagnosticsDataType, samplingInterval) - sizeof(UA_Double), /* .padding */
17915 false, /* .isArray */
17916 false /* .isOptional */
17917},
17918{
17919 UA_TYPENAME("MaxMonitoredItemCount") /* .memberName */
17920 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17921 offsetof(UA_SamplingIntervalDiagnosticsDataType, maxMonitoredItemCount) - offsetof(UA_SamplingIntervalDiagnosticsDataType, monitoredItemCount) - sizeof(UA_UInt32), /* .padding */
17922 false, /* .isArray */
17923 false /* .isOptional */
17924},
17925{
17926 UA_TYPENAME("DisabledMonitoredItemCount") /* .memberName */
17927 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17928 offsetof(UA_SamplingIntervalDiagnosticsDataType, disabledMonitoredItemCount) - offsetof(UA_SamplingIntervalDiagnosticsDataType, maxMonitoredItemCount) - sizeof(UA_UInt32), /* .padding */
17929 false, /* .isArray */
17930 false /* .isOptional */
17931},};
17932
17933/* ServerDiagnosticsSummaryDataType */
17934static UA_DataTypeMember ServerDiagnosticsSummaryDataType_members[12] = {
17935{
17936 UA_TYPENAME("ServerViewCount") /* .memberName */
17937 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17938 0, /* .padding */
17939 false, /* .isArray */
17940 false /* .isOptional */
17941},
17942{
17943 UA_TYPENAME("CurrentSessionCount") /* .memberName */
17944 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17945 offsetof(UA_ServerDiagnosticsSummaryDataType, currentSessionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, serverViewCount) - sizeof(UA_UInt32), /* .padding */
17946 false, /* .isArray */
17947 false /* .isOptional */
17948},
17949{
17950 UA_TYPENAME("CumulatedSessionCount") /* .memberName */
17951 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17952 offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSessionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, currentSessionCount) - sizeof(UA_UInt32), /* .padding */
17953 false, /* .isArray */
17954 false /* .isOptional */
17955},
17956{
17957 UA_TYPENAME("SecurityRejectedSessionCount") /* .memberName */
17958 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17959 offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedSessionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSessionCount) - sizeof(UA_UInt32), /* .padding */
17960 false, /* .isArray */
17961 false /* .isOptional */
17962},
17963{
17964 UA_TYPENAME("RejectedSessionCount") /* .memberName */
17965 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17966 offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedSessionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedSessionCount) - sizeof(UA_UInt32), /* .padding */
17967 false, /* .isArray */
17968 false /* .isOptional */
17969},
17970{
17971 UA_TYPENAME("SessionTimeoutCount") /* .memberName */
17972 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17973 offsetof(UA_ServerDiagnosticsSummaryDataType, sessionTimeoutCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedSessionCount) - sizeof(UA_UInt32), /* .padding */
17974 false, /* .isArray */
17975 false /* .isOptional */
17976},
17977{
17978 UA_TYPENAME("SessionAbortCount") /* .memberName */
17979 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17980 offsetof(UA_ServerDiagnosticsSummaryDataType, sessionAbortCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, sessionTimeoutCount) - sizeof(UA_UInt32), /* .padding */
17981 false, /* .isArray */
17982 false /* .isOptional */
17983},
17984{
17985 UA_TYPENAME("CurrentSubscriptionCount") /* .memberName */
17986 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17987 offsetof(UA_ServerDiagnosticsSummaryDataType, currentSubscriptionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, sessionAbortCount) - sizeof(UA_UInt32), /* .padding */
17988 false, /* .isArray */
17989 false /* .isOptional */
17990},
17991{
17992 UA_TYPENAME("CumulatedSubscriptionCount") /* .memberName */
17993 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
17994 offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSubscriptionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, currentSubscriptionCount) - sizeof(UA_UInt32), /* .padding */
17995 false, /* .isArray */
17996 false /* .isOptional */
17997},
17998{
17999 UA_TYPENAME("PublishingIntervalCount") /* .memberName */
18000 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18001 offsetof(UA_ServerDiagnosticsSummaryDataType, publishingIntervalCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSubscriptionCount) - sizeof(UA_UInt32), /* .padding */
18002 false, /* .isArray */
18003 false /* .isOptional */
18004},
18005{
18006 UA_TYPENAME("SecurityRejectedRequestsCount") /* .memberName */
18007 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18008 offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedRequestsCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, publishingIntervalCount) - sizeof(UA_UInt32), /* .padding */
18009 false, /* .isArray */
18010 false /* .isOptional */
18011},
18012{
18013 UA_TYPENAME("RejectedRequestsCount") /* .memberName */
18014 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18015 offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedRequestsCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedRequestsCount) - sizeof(UA_UInt32), /* .padding */
18016 false, /* .isArray */
18017 false /* .isOptional */
18018},};
18019
18020/* ServerStatusDataType */
18021static UA_DataTypeMember ServerStatusDataType_members[6] = {
18022{
18023 UA_TYPENAME("StartTime") /* .memberName */
18024 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
18025 0, /* .padding */
18026 false, /* .isArray */
18027 false /* .isOptional */
18028},
18029{
18030 UA_TYPENAME("CurrentTime") /* .memberName */
18031 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
18032 offsetof(UA_ServerStatusDataType, currentTime) - offsetof(UA_ServerStatusDataType, startTime) - sizeof(UA_DateTime), /* .padding */
18033 false, /* .isArray */
18034 false /* .isOptional */
18035},
18036{
18037 UA_TYPENAME("State") /* .memberName */
18038 &UA_TYPES[UA_TYPES_SERVERSTATE], /* .memberType */
18039 offsetof(UA_ServerStatusDataType, state) - offsetof(UA_ServerStatusDataType, currentTime) - sizeof(UA_DateTime), /* .padding */
18040 false, /* .isArray */
18041 false /* .isOptional */
18042},
18043{
18044 UA_TYPENAME("BuildInfo") /* .memberName */
18045 &UA_TYPES[UA_TYPES_BUILDINFO], /* .memberType */
18046 offsetof(UA_ServerStatusDataType, buildInfo) - offsetof(UA_ServerStatusDataType, state) - sizeof(UA_ServerState), /* .padding */
18047 false, /* .isArray */
18048 false /* .isOptional */
18049},
18050{
18051 UA_TYPENAME("SecondsTillShutdown") /* .memberName */
18052 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18053 offsetof(UA_ServerStatusDataType, secondsTillShutdown) - offsetof(UA_ServerStatusDataType, buildInfo) - sizeof(UA_BuildInfo), /* .padding */
18054 false, /* .isArray */
18055 false /* .isOptional */
18056},
18057{
18058 UA_TYPENAME("ShutdownReason") /* .memberName */
18059 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
18060 offsetof(UA_ServerStatusDataType, shutdownReason) - offsetof(UA_ServerStatusDataType, secondsTillShutdown) - sizeof(UA_UInt32), /* .padding */
18061 false, /* .isArray */
18062 false /* .isOptional */
18063},};
18064
18065/* SessionSecurityDiagnosticsDataType */
18066static UA_DataTypeMember SessionSecurityDiagnosticsDataType_members[9] = {
18067{
18068 UA_TYPENAME("SessionId") /* .memberName */
18069 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
18070 0, /* .padding */
18071 false, /* .isArray */
18072 false /* .isOptional */
18073},
18074{
18075 UA_TYPENAME("ClientUserIdOfSession") /* .memberName */
18076 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18077 offsetof(UA_SessionSecurityDiagnosticsDataType, clientUserIdOfSession) - offsetof(UA_SessionSecurityDiagnosticsDataType, sessionId) - sizeof(UA_NodeId), /* .padding */
18078 false, /* .isArray */
18079 false /* .isOptional */
18080},
18081{
18082 UA_TYPENAME("ClientUserIdHistory") /* .memberName */
18083 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18084 offsetof(UA_SessionSecurityDiagnosticsDataType, clientUserIdHistorySize) - offsetof(UA_SessionSecurityDiagnosticsDataType, clientUserIdOfSession) - sizeof(UA_String), /* .padding */
18085 true, /* .isArray */
18086 false /* .isOptional */
18087},
18088{
18089 UA_TYPENAME("AuthenticationMechanism") /* .memberName */
18090 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18091 offsetof(UA_SessionSecurityDiagnosticsDataType, authenticationMechanism) - offsetof(UA_SessionSecurityDiagnosticsDataType, clientUserIdHistory) - sizeof(void *), /* .padding */
18092 false, /* .isArray */
18093 false /* .isOptional */
18094},
18095{
18096 UA_TYPENAME("Encoding") /* .memberName */
18097 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18098 offsetof(UA_SessionSecurityDiagnosticsDataType, encoding) - offsetof(UA_SessionSecurityDiagnosticsDataType, authenticationMechanism) - sizeof(UA_String), /* .padding */
18099 false, /* .isArray */
18100 false /* .isOptional */
18101},
18102{
18103 UA_TYPENAME("TransportProtocol") /* .memberName */
18104 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18105 offsetof(UA_SessionSecurityDiagnosticsDataType, transportProtocol) - offsetof(UA_SessionSecurityDiagnosticsDataType, encoding) - sizeof(UA_String), /* .padding */
18106 false, /* .isArray */
18107 false /* .isOptional */
18108},
18109{
18110 UA_TYPENAME("SecurityMode") /* .memberName */
18111 &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE], /* .memberType */
18112 offsetof(UA_SessionSecurityDiagnosticsDataType, securityMode) - offsetof(UA_SessionSecurityDiagnosticsDataType, transportProtocol) - sizeof(UA_String), /* .padding */
18113 false, /* .isArray */
18114 false /* .isOptional */
18115},
18116{
18117 UA_TYPENAME("SecurityPolicyUri") /* .memberName */
18118 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18119 offsetof(UA_SessionSecurityDiagnosticsDataType, securityPolicyUri) - offsetof(UA_SessionSecurityDiagnosticsDataType, securityMode) - sizeof(UA_MessageSecurityMode), /* .padding */
18120 false, /* .isArray */
18121 false /* .isOptional */
18122},
18123{
18124 UA_TYPENAME("ClientCertificate") /* .memberName */
18125 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
18126 offsetof(UA_SessionSecurityDiagnosticsDataType, clientCertificate) - offsetof(UA_SessionSecurityDiagnosticsDataType, securityPolicyUri) - sizeof(UA_String), /* .padding */
18127 false, /* .isArray */
18128 false /* .isOptional */
18129},};
18130
18131/* ServiceCounterDataType */
18132static UA_DataTypeMember ServiceCounterDataType_members[2] = {
18133{
18134 UA_TYPENAME("TotalCount") /* .memberName */
18135 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18136 0, /* .padding */
18137 false, /* .isArray */
18138 false /* .isOptional */
18139},
18140{
18141 UA_TYPENAME("ErrorCount") /* .memberName */
18142 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18143 offsetof(UA_ServiceCounterDataType, errorCount) - offsetof(UA_ServiceCounterDataType, totalCount) - sizeof(UA_UInt32), /* .padding */
18144 false, /* .isArray */
18145 false /* .isOptional */
18146},};
18147
18148/* StatusResult */
18149static UA_DataTypeMember StatusResult_members[2] = {
18150{
18151 UA_TYPENAME("StatusCode") /* .memberName */
18152 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
18153 0, /* .padding */
18154 false, /* .isArray */
18155 false /* .isOptional */
18156},
18157{
18158 UA_TYPENAME("DiagnosticInfo") /* .memberName */
18159 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
18160 offsetof(UA_StatusResult, diagnosticInfo) - offsetof(UA_StatusResult, statusCode) - sizeof(UA_StatusCode), /* .padding */
18161 false, /* .isArray */
18162 false /* .isOptional */
18163},};
18164
18165/* SubscriptionDiagnosticsDataType */
18166static UA_DataTypeMember SubscriptionDiagnosticsDataType_members[31] = {
18167{
18168 UA_TYPENAME("SessionId") /* .memberName */
18169 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
18170 0, /* .padding */
18171 false, /* .isArray */
18172 false /* .isOptional */
18173},
18174{
18175 UA_TYPENAME("SubscriptionId") /* .memberName */
18176 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18177 offsetof(UA_SubscriptionDiagnosticsDataType, subscriptionId) - offsetof(UA_SubscriptionDiagnosticsDataType, sessionId) - sizeof(UA_NodeId), /* .padding */
18178 false, /* .isArray */
18179 false /* .isOptional */
18180},
18181{
18182 UA_TYPENAME("Priority") /* .memberName */
18183 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
18184 offsetof(UA_SubscriptionDiagnosticsDataType, priority) - offsetof(UA_SubscriptionDiagnosticsDataType, subscriptionId) - sizeof(UA_UInt32), /* .padding */
18185 false, /* .isArray */
18186 false /* .isOptional */
18187},
18188{
18189 UA_TYPENAME("PublishingInterval") /* .memberName */
18190 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
18191 offsetof(UA_SubscriptionDiagnosticsDataType, publishingInterval) - offsetof(UA_SubscriptionDiagnosticsDataType, priority) - sizeof(UA_Byte), /* .padding */
18192 false, /* .isArray */
18193 false /* .isOptional */
18194},
18195{
18196 UA_TYPENAME("MaxKeepAliveCount") /* .memberName */
18197 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18198 offsetof(UA_SubscriptionDiagnosticsDataType, maxKeepAliveCount) - offsetof(UA_SubscriptionDiagnosticsDataType, publishingInterval) - sizeof(UA_Double), /* .padding */
18199 false, /* .isArray */
18200 false /* .isOptional */
18201},
18202{
18203 UA_TYPENAME("MaxLifetimeCount") /* .memberName */
18204 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18205 offsetof(UA_SubscriptionDiagnosticsDataType, maxLifetimeCount) - offsetof(UA_SubscriptionDiagnosticsDataType, maxKeepAliveCount) - sizeof(UA_UInt32), /* .padding */
18206 false, /* .isArray */
18207 false /* .isOptional */
18208},
18209{
18210 UA_TYPENAME("MaxNotificationsPerPublish") /* .memberName */
18211 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18212 offsetof(UA_SubscriptionDiagnosticsDataType, maxNotificationsPerPublish) - offsetof(UA_SubscriptionDiagnosticsDataType, maxLifetimeCount) - sizeof(UA_UInt32), /* .padding */
18213 false, /* .isArray */
18214 false /* .isOptional */
18215},
18216{
18217 UA_TYPENAME("PublishingEnabled") /* .memberName */
18218 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
18219 offsetof(UA_SubscriptionDiagnosticsDataType, publishingEnabled) - offsetof(UA_SubscriptionDiagnosticsDataType, maxNotificationsPerPublish) - sizeof(UA_UInt32), /* .padding */
18220 false, /* .isArray */
18221 false /* .isOptional */
18222},
18223{
18224 UA_TYPENAME("ModifyCount") /* .memberName */
18225 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18226 offsetof(UA_SubscriptionDiagnosticsDataType, modifyCount) - offsetof(UA_SubscriptionDiagnosticsDataType, publishingEnabled) - sizeof(UA_Boolean), /* .padding */
18227 false, /* .isArray */
18228 false /* .isOptional */
18229},
18230{
18231 UA_TYPENAME("EnableCount") /* .memberName */
18232 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18233 offsetof(UA_SubscriptionDiagnosticsDataType, enableCount) - offsetof(UA_SubscriptionDiagnosticsDataType, modifyCount) - sizeof(UA_UInt32), /* .padding */
18234 false, /* .isArray */
18235 false /* .isOptional */
18236},
18237{
18238 UA_TYPENAME("DisableCount") /* .memberName */
18239 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18240 offsetof(UA_SubscriptionDiagnosticsDataType, disableCount) - offsetof(UA_SubscriptionDiagnosticsDataType, enableCount) - sizeof(UA_UInt32), /* .padding */
18241 false, /* .isArray */
18242 false /* .isOptional */
18243},
18244{
18245 UA_TYPENAME("RepublishRequestCount") /* .memberName */
18246 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18247 offsetof(UA_SubscriptionDiagnosticsDataType, republishRequestCount) - offsetof(UA_SubscriptionDiagnosticsDataType, disableCount) - sizeof(UA_UInt32), /* .padding */
18248 false, /* .isArray */
18249 false /* .isOptional */
18250},
18251{
18252 UA_TYPENAME("RepublishMessageRequestCount") /* .memberName */
18253 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18254 offsetof(UA_SubscriptionDiagnosticsDataType, republishMessageRequestCount) - offsetof(UA_SubscriptionDiagnosticsDataType, republishRequestCount) - sizeof(UA_UInt32), /* .padding */
18255 false, /* .isArray */
18256 false /* .isOptional */
18257},
18258{
18259 UA_TYPENAME("RepublishMessageCount") /* .memberName */
18260 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18261 offsetof(UA_SubscriptionDiagnosticsDataType, republishMessageCount) - offsetof(UA_SubscriptionDiagnosticsDataType, republishMessageRequestCount) - sizeof(UA_UInt32), /* .padding */
18262 false, /* .isArray */
18263 false /* .isOptional */
18264},
18265{
18266 UA_TYPENAME("TransferRequestCount") /* .memberName */
18267 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18268 offsetof(UA_SubscriptionDiagnosticsDataType, transferRequestCount) - offsetof(UA_SubscriptionDiagnosticsDataType, republishMessageCount) - sizeof(UA_UInt32), /* .padding */
18269 false, /* .isArray */
18270 false /* .isOptional */
18271},
18272{
18273 UA_TYPENAME("TransferredToAltClientCount") /* .memberName */
18274 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18275 offsetof(UA_SubscriptionDiagnosticsDataType, transferredToAltClientCount) - offsetof(UA_SubscriptionDiagnosticsDataType, transferRequestCount) - sizeof(UA_UInt32), /* .padding */
18276 false, /* .isArray */
18277 false /* .isOptional */
18278},
18279{
18280 UA_TYPENAME("TransferredToSameClientCount") /* .memberName */
18281 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18282 offsetof(UA_SubscriptionDiagnosticsDataType, transferredToSameClientCount) - offsetof(UA_SubscriptionDiagnosticsDataType, transferredToAltClientCount) - sizeof(UA_UInt32), /* .padding */
18283 false, /* .isArray */
18284 false /* .isOptional */
18285},
18286{
18287 UA_TYPENAME("PublishRequestCount") /* .memberName */
18288 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18289 offsetof(UA_SubscriptionDiagnosticsDataType, publishRequestCount) - offsetof(UA_SubscriptionDiagnosticsDataType, transferredToSameClientCount) - sizeof(UA_UInt32), /* .padding */
18290 false, /* .isArray */
18291 false /* .isOptional */
18292},
18293{
18294 UA_TYPENAME("DataChangeNotificationsCount") /* .memberName */
18295 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18296 offsetof(UA_SubscriptionDiagnosticsDataType, dataChangeNotificationsCount) - offsetof(UA_SubscriptionDiagnosticsDataType, publishRequestCount) - sizeof(UA_UInt32), /* .padding */
18297 false, /* .isArray */
18298 false /* .isOptional */
18299},
18300{
18301 UA_TYPENAME("EventNotificationsCount") /* .memberName */
18302 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18303 offsetof(UA_SubscriptionDiagnosticsDataType, eventNotificationsCount) - offsetof(UA_SubscriptionDiagnosticsDataType, dataChangeNotificationsCount) - sizeof(UA_UInt32), /* .padding */
18304 false, /* .isArray */
18305 false /* .isOptional */
18306},
18307{
18308 UA_TYPENAME("NotificationsCount") /* .memberName */
18309 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18310 offsetof(UA_SubscriptionDiagnosticsDataType, notificationsCount) - offsetof(UA_SubscriptionDiagnosticsDataType, eventNotificationsCount) - sizeof(UA_UInt32), /* .padding */
18311 false, /* .isArray */
18312 false /* .isOptional */
18313},
18314{
18315 UA_TYPENAME("LatePublishRequestCount") /* .memberName */
18316 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18317 offsetof(UA_SubscriptionDiagnosticsDataType, latePublishRequestCount) - offsetof(UA_SubscriptionDiagnosticsDataType, notificationsCount) - sizeof(UA_UInt32), /* .padding */
18318 false, /* .isArray */
18319 false /* .isOptional */
18320},
18321{
18322 UA_TYPENAME("CurrentKeepAliveCount") /* .memberName */
18323 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18324 offsetof(UA_SubscriptionDiagnosticsDataType, currentKeepAliveCount) - offsetof(UA_SubscriptionDiagnosticsDataType, latePublishRequestCount) - sizeof(UA_UInt32), /* .padding */
18325 false, /* .isArray */
18326 false /* .isOptional */
18327},
18328{
18329 UA_TYPENAME("CurrentLifetimeCount") /* .memberName */
18330 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18331 offsetof(UA_SubscriptionDiagnosticsDataType, currentLifetimeCount) - offsetof(UA_SubscriptionDiagnosticsDataType, currentKeepAliveCount) - sizeof(UA_UInt32), /* .padding */
18332 false, /* .isArray */
18333 false /* .isOptional */
18334},
18335{
18336 UA_TYPENAME("UnacknowledgedMessageCount") /* .memberName */
18337 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18338 offsetof(UA_SubscriptionDiagnosticsDataType, unacknowledgedMessageCount) - offsetof(UA_SubscriptionDiagnosticsDataType, currentLifetimeCount) - sizeof(UA_UInt32), /* .padding */
18339 false, /* .isArray */
18340 false /* .isOptional */
18341},
18342{
18343 UA_TYPENAME("DiscardedMessageCount") /* .memberName */
18344 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18345 offsetof(UA_SubscriptionDiagnosticsDataType, discardedMessageCount) - offsetof(UA_SubscriptionDiagnosticsDataType, unacknowledgedMessageCount) - sizeof(UA_UInt32), /* .padding */
18346 false, /* .isArray */
18347 false /* .isOptional */
18348},
18349{
18350 UA_TYPENAME("MonitoredItemCount") /* .memberName */
18351 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18352 offsetof(UA_SubscriptionDiagnosticsDataType, monitoredItemCount) - offsetof(UA_SubscriptionDiagnosticsDataType, discardedMessageCount) - sizeof(UA_UInt32), /* .padding */
18353 false, /* .isArray */
18354 false /* .isOptional */
18355},
18356{
18357 UA_TYPENAME("DisabledMonitoredItemCount") /* .memberName */
18358 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18359 offsetof(UA_SubscriptionDiagnosticsDataType, disabledMonitoredItemCount) - offsetof(UA_SubscriptionDiagnosticsDataType, monitoredItemCount) - sizeof(UA_UInt32), /* .padding */
18360 false, /* .isArray */
18361 false /* .isOptional */
18362},
18363{
18364 UA_TYPENAME("MonitoringQueueOverflowCount") /* .memberName */
18365 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18366 offsetof(UA_SubscriptionDiagnosticsDataType, monitoringQueueOverflowCount) - offsetof(UA_SubscriptionDiagnosticsDataType, disabledMonitoredItemCount) - sizeof(UA_UInt32), /* .padding */
18367 false, /* .isArray */
18368 false /* .isOptional */
18369},
18370{
18371 UA_TYPENAME("NextSequenceNumber") /* .memberName */
18372 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18373 offsetof(UA_SubscriptionDiagnosticsDataType, nextSequenceNumber) - offsetof(UA_SubscriptionDiagnosticsDataType, monitoringQueueOverflowCount) - sizeof(UA_UInt32), /* .padding */
18374 false, /* .isArray */
18375 false /* .isOptional */
18376},
18377{
18378 UA_TYPENAME("EventQueueOverFlowCount") /* .memberName */
18379 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18380 offsetof(UA_SubscriptionDiagnosticsDataType, eventQueueOverFlowCount) - offsetof(UA_SubscriptionDiagnosticsDataType, nextSequenceNumber) - sizeof(UA_UInt32), /* .padding */
18381 false, /* .isArray */
18382 false /* .isOptional */
18383},};
18384
18385/* ModelChangeStructureVerbMask */
18386#define ModelChangeStructureVerbMask_members NULL
18387
18388/* ModelChangeStructureDataType */
18389static UA_DataTypeMember ModelChangeStructureDataType_members[3] = {
18390{
18391 UA_TYPENAME("Affected") /* .memberName */
18392 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
18393 0, /* .padding */
18394 false, /* .isArray */
18395 false /* .isOptional */
18396},
18397{
18398 UA_TYPENAME("AffectedType") /* .memberName */
18399 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
18400 offsetof(UA_ModelChangeStructureDataType, affectedType) - offsetof(UA_ModelChangeStructureDataType, affected) - sizeof(UA_NodeId), /* .padding */
18401 false, /* .isArray */
18402 false /* .isOptional */
18403},
18404{
18405 UA_TYPENAME("Verb") /* .memberName */
18406 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
18407 offsetof(UA_ModelChangeStructureDataType, verb) - offsetof(UA_ModelChangeStructureDataType, affectedType) - sizeof(UA_NodeId), /* .padding */
18408 false, /* .isArray */
18409 false /* .isOptional */
18410},};
18411
18412/* SemanticChangeStructureDataType */
18413static UA_DataTypeMember SemanticChangeStructureDataType_members[2] = {
18414{
18415 UA_TYPENAME("Affected") /* .memberName */
18416 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
18417 0, /* .padding */
18418 false, /* .isArray */
18419 false /* .isOptional */
18420},
18421{
18422 UA_TYPENAME("AffectedType") /* .memberName */
18423 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
18424 offsetof(UA_SemanticChangeStructureDataType, affectedType) - offsetof(UA_SemanticChangeStructureDataType, affected) - sizeof(UA_NodeId), /* .padding */
18425 false, /* .isArray */
18426 false /* .isOptional */
18427},};
18428
18429/* Range */
18430static UA_DataTypeMember Range_members[2] = {
18431{
18432 UA_TYPENAME("Low") /* .memberName */
18433 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
18434 0, /* .padding */
18435 false, /* .isArray */
18436 false /* .isOptional */
18437},
18438{
18439 UA_TYPENAME("High") /* .memberName */
18440 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
18441 offsetof(UA_Range, high) - offsetof(UA_Range, low) - sizeof(UA_Double), /* .padding */
18442 false, /* .isArray */
18443 false /* .isOptional */
18444},};
18445
18446/* EUInformation */
18447static UA_DataTypeMember EUInformation_members[4] = {
18448{
18449 UA_TYPENAME("NamespaceUri") /* .memberName */
18450 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18451 0, /* .padding */
18452 false, /* .isArray */
18453 false /* .isOptional */
18454},
18455{
18456 UA_TYPENAME("UnitId") /* .memberName */
18457 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
18458 offsetof(UA_EUInformation, unitId) - offsetof(UA_EUInformation, namespaceUri) - sizeof(UA_String), /* .padding */
18459 false, /* .isArray */
18460 false /* .isOptional */
18461},
18462{
18463 UA_TYPENAME("DisplayName") /* .memberName */
18464 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
18465 offsetof(UA_EUInformation, displayName) - offsetof(UA_EUInformation, unitId) - sizeof(UA_Int32), /* .padding */
18466 false, /* .isArray */
18467 false /* .isOptional */
18468},
18469{
18470 UA_TYPENAME("Description") /* .memberName */
18471 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
18472 offsetof(UA_EUInformation, description) - offsetof(UA_EUInformation, displayName) - sizeof(UA_LocalizedText), /* .padding */
18473 false, /* .isArray */
18474 false /* .isOptional */
18475},};
18476
18477/* AxisScaleEnumeration */
18478#define AxisScaleEnumeration_members NULL
18479
18480/* ComplexNumberType */
18481static UA_DataTypeMember ComplexNumberType_members[2] = {
18482{
18483 UA_TYPENAME("Real") /* .memberName */
18484 &UA_TYPES[UA_TYPES_FLOAT], /* .memberType */
18485 0, /* .padding */
18486 false, /* .isArray */
18487 false /* .isOptional */
18488},
18489{
18490 UA_TYPENAME("Imaginary") /* .memberName */
18491 &UA_TYPES[UA_TYPES_FLOAT], /* .memberType */
18492 offsetof(UA_ComplexNumberType, imaginary) - offsetof(UA_ComplexNumberType, real) - sizeof(UA_Float), /* .padding */
18493 false, /* .isArray */
18494 false /* .isOptional */
18495},};
18496
18497/* DoubleComplexNumberType */
18498static UA_DataTypeMember DoubleComplexNumberType_members[2] = {
18499{
18500 UA_TYPENAME("Real") /* .memberName */
18501 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
18502 0, /* .padding */
18503 false, /* .isArray */
18504 false /* .isOptional */
18505},
18506{
18507 UA_TYPENAME("Imaginary") /* .memberName */
18508 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
18509 offsetof(UA_DoubleComplexNumberType, imaginary) - offsetof(UA_DoubleComplexNumberType, real) - sizeof(UA_Double), /* .padding */
18510 false, /* .isArray */
18511 false /* .isOptional */
18512},};
18513
18514/* AxisInformation */
18515static UA_DataTypeMember AxisInformation_members[5] = {
18516{
18517 UA_TYPENAME("EngineeringUnits") /* .memberName */
18518 &UA_TYPES[UA_TYPES_EUINFORMATION], /* .memberType */
18519 0, /* .padding */
18520 false, /* .isArray */
18521 false /* .isOptional */
18522},
18523{
18524 UA_TYPENAME("EURange") /* .memberName */
18525 &UA_TYPES[UA_TYPES_RANGE], /* .memberType */
18526 offsetof(UA_AxisInformation, eURange) - offsetof(UA_AxisInformation, engineeringUnits) - sizeof(UA_EUInformation), /* .padding */
18527 false, /* .isArray */
18528 false /* .isOptional */
18529},
18530{
18531 UA_TYPENAME("Title") /* .memberName */
18532 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
18533 offsetof(UA_AxisInformation, title) - offsetof(UA_AxisInformation, eURange) - sizeof(UA_Range), /* .padding */
18534 false, /* .isArray */
18535 false /* .isOptional */
18536},
18537{
18538 UA_TYPENAME("AxisScaleType") /* .memberName */
18539 &UA_TYPES[UA_TYPES_AXISSCALEENUMERATION], /* .memberType */
18540 offsetof(UA_AxisInformation, axisScaleType) - offsetof(UA_AxisInformation, title) - sizeof(UA_LocalizedText), /* .padding */
18541 false, /* .isArray */
18542 false /* .isOptional */
18543},
18544{
18545 UA_TYPENAME("AxisSteps") /* .memberName */
18546 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
18547 offsetof(UA_AxisInformation, axisStepsSize) - offsetof(UA_AxisInformation, axisScaleType) - sizeof(UA_AxisScaleEnumeration), /* .padding */
18548 true, /* .isArray */
18549 false /* .isOptional */
18550},};
18551
18552/* XVType */
18553static UA_DataTypeMember XVType_members[2] = {
18554{
18555 UA_TYPENAME("X") /* .memberName */
18556 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
18557 0, /* .padding */
18558 false, /* .isArray */
18559 false /* .isOptional */
18560},
18561{
18562 UA_TYPENAME("Value") /* .memberName */
18563 &UA_TYPES[UA_TYPES_FLOAT], /* .memberType */
18564 offsetof(UA_XVType, value) - offsetof(UA_XVType, x) - sizeof(UA_Double), /* .padding */
18565 false, /* .isArray */
18566 false /* .isOptional */
18567},};
18568
18569/* ProgramDiagnosticDataType */
18570static UA_DataTypeMember ProgramDiagnosticDataType_members[10] = {
18571{
18572 UA_TYPENAME("CreateSessionId") /* .memberName */
18573 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
18574 0, /* .padding */
18575 false, /* .isArray */
18576 false /* .isOptional */
18577},
18578{
18579 UA_TYPENAME("CreateClientName") /* .memberName */
18580 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18581 offsetof(UA_ProgramDiagnosticDataType, createClientName) - offsetof(UA_ProgramDiagnosticDataType, createSessionId) - sizeof(UA_NodeId), /* .padding */
18582 false, /* .isArray */
18583 false /* .isOptional */
18584},
18585{
18586 UA_TYPENAME("InvocationCreationTime") /* .memberName */
18587 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
18588 offsetof(UA_ProgramDiagnosticDataType, invocationCreationTime) - offsetof(UA_ProgramDiagnosticDataType, createClientName) - sizeof(UA_String), /* .padding */
18589 false, /* .isArray */
18590 false /* .isOptional */
18591},
18592{
18593 UA_TYPENAME("LastTransitionTime") /* .memberName */
18594 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
18595 offsetof(UA_ProgramDiagnosticDataType, lastTransitionTime) - offsetof(UA_ProgramDiagnosticDataType, invocationCreationTime) - sizeof(UA_DateTime), /* .padding */
18596 false, /* .isArray */
18597 false /* .isOptional */
18598},
18599{
18600 UA_TYPENAME("LastMethodCall") /* .memberName */
18601 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18602 offsetof(UA_ProgramDiagnosticDataType, lastMethodCall) - offsetof(UA_ProgramDiagnosticDataType, lastTransitionTime) - sizeof(UA_DateTime), /* .padding */
18603 false, /* .isArray */
18604 false /* .isOptional */
18605},
18606{
18607 UA_TYPENAME("LastMethodSessionId") /* .memberName */
18608 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
18609 offsetof(UA_ProgramDiagnosticDataType, lastMethodSessionId) - offsetof(UA_ProgramDiagnosticDataType, lastMethodCall) - sizeof(UA_String), /* .padding */
18610 false, /* .isArray */
18611 false /* .isOptional */
18612},
18613{
18614 UA_TYPENAME("LastMethodInputArguments") /* .memberName */
18615 &UA_TYPES[UA_TYPES_ARGUMENT], /* .memberType */
18616 offsetof(UA_ProgramDiagnosticDataType, lastMethodInputArgumentsSize) - offsetof(UA_ProgramDiagnosticDataType, lastMethodSessionId) - sizeof(UA_NodeId), /* .padding */
18617 true, /* .isArray */
18618 false /* .isOptional */
18619},
18620{
18621 UA_TYPENAME("LastMethodOutputArguments") /* .memberName */
18622 &UA_TYPES[UA_TYPES_ARGUMENT], /* .memberType */
18623 offsetof(UA_ProgramDiagnosticDataType, lastMethodOutputArgumentsSize) - offsetof(UA_ProgramDiagnosticDataType, lastMethodInputArguments) - sizeof(void *), /* .padding */
18624 true, /* .isArray */
18625 false /* .isOptional */
18626},
18627{
18628 UA_TYPENAME("LastMethodCallTime") /* .memberName */
18629 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
18630 offsetof(UA_ProgramDiagnosticDataType, lastMethodCallTime) - offsetof(UA_ProgramDiagnosticDataType, lastMethodOutputArguments) - sizeof(void *), /* .padding */
18631 false, /* .isArray */
18632 false /* .isOptional */
18633},
18634{
18635 UA_TYPENAME("LastMethodReturnStatus") /* .memberName */
18636 &UA_TYPES[UA_TYPES_STATUSRESULT], /* .memberType */
18637 offsetof(UA_ProgramDiagnosticDataType, lastMethodReturnStatus) - offsetof(UA_ProgramDiagnosticDataType, lastMethodCallTime) - sizeof(UA_DateTime), /* .padding */
18638 false, /* .isArray */
18639 false /* .isOptional */
18640},};
18641
18642/* ProgramDiagnostic2DataType */
18643static UA_DataTypeMember ProgramDiagnostic2DataType_members[12] = {
18644{
18645 UA_TYPENAME("CreateSessionId") /* .memberName */
18646 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
18647 0, /* .padding */
18648 false, /* .isArray */
18649 false /* .isOptional */
18650},
18651{
18652 UA_TYPENAME("CreateClientName") /* .memberName */
18653 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18654 offsetof(UA_ProgramDiagnostic2DataType, createClientName) - offsetof(UA_ProgramDiagnostic2DataType, createSessionId) - sizeof(UA_NodeId), /* .padding */
18655 false, /* .isArray */
18656 false /* .isOptional */
18657},
18658{
18659 UA_TYPENAME("InvocationCreationTime") /* .memberName */
18660 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
18661 offsetof(UA_ProgramDiagnostic2DataType, invocationCreationTime) - offsetof(UA_ProgramDiagnostic2DataType, createClientName) - sizeof(UA_String), /* .padding */
18662 false, /* .isArray */
18663 false /* .isOptional */
18664},
18665{
18666 UA_TYPENAME("LastTransitionTime") /* .memberName */
18667 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
18668 offsetof(UA_ProgramDiagnostic2DataType, lastTransitionTime) - offsetof(UA_ProgramDiagnostic2DataType, invocationCreationTime) - sizeof(UA_DateTime), /* .padding */
18669 false, /* .isArray */
18670 false /* .isOptional */
18671},
18672{
18673 UA_TYPENAME("LastMethodCall") /* .memberName */
18674 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18675 offsetof(UA_ProgramDiagnostic2DataType, lastMethodCall) - offsetof(UA_ProgramDiagnostic2DataType, lastTransitionTime) - sizeof(UA_DateTime), /* .padding */
18676 false, /* .isArray */
18677 false /* .isOptional */
18678},
18679{
18680 UA_TYPENAME("LastMethodSessionId") /* .memberName */
18681 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
18682 offsetof(UA_ProgramDiagnostic2DataType, lastMethodSessionId) - offsetof(UA_ProgramDiagnostic2DataType, lastMethodCall) - sizeof(UA_String), /* .padding */
18683 false, /* .isArray */
18684 false /* .isOptional */
18685},
18686{
18687 UA_TYPENAME("LastMethodInputArguments") /* .memberName */
18688 &UA_TYPES[UA_TYPES_ARGUMENT], /* .memberType */
18689 offsetof(UA_ProgramDiagnostic2DataType, lastMethodInputArgumentsSize) - offsetof(UA_ProgramDiagnostic2DataType, lastMethodSessionId) - sizeof(UA_NodeId), /* .padding */
18690 true, /* .isArray */
18691 false /* .isOptional */
18692},
18693{
18694 UA_TYPENAME("LastMethodOutputArguments") /* .memberName */
18695 &UA_TYPES[UA_TYPES_ARGUMENT], /* .memberType */
18696 offsetof(UA_ProgramDiagnostic2DataType, lastMethodOutputArgumentsSize) - offsetof(UA_ProgramDiagnostic2DataType, lastMethodInputArguments) - sizeof(void *), /* .padding */
18697 true, /* .isArray */
18698 false /* .isOptional */
18699},
18700{
18701 UA_TYPENAME("LastMethodInputValues") /* .memberName */
18702 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
18703 offsetof(UA_ProgramDiagnostic2DataType, lastMethodInputValuesSize) - offsetof(UA_ProgramDiagnostic2DataType, lastMethodOutputArguments) - sizeof(void *), /* .padding */
18704 true, /* .isArray */
18705 false /* .isOptional */
18706},
18707{
18708 UA_TYPENAME("LastMethodOutputValues") /* .memberName */
18709 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
18710 offsetof(UA_ProgramDiagnostic2DataType, lastMethodOutputValuesSize) - offsetof(UA_ProgramDiagnostic2DataType, lastMethodInputValues) - sizeof(void *), /* .padding */
18711 true, /* .isArray */
18712 false /* .isOptional */
18713},
18714{
18715 UA_TYPENAME("LastMethodCallTime") /* .memberName */
18716 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
18717 offsetof(UA_ProgramDiagnostic2DataType, lastMethodCallTime) - offsetof(UA_ProgramDiagnostic2DataType, lastMethodOutputValues) - sizeof(void *), /* .padding */
18718 false, /* .isArray */
18719 false /* .isOptional */
18720},
18721{
18722 UA_TYPENAME("LastMethodReturnStatus") /* .memberName */
18723 &UA_TYPES[UA_TYPES_STATUSCODE], /* .memberType */
18724 offsetof(UA_ProgramDiagnostic2DataType, lastMethodReturnStatus) - offsetof(UA_ProgramDiagnostic2DataType, lastMethodCallTime) - sizeof(UA_DateTime), /* .padding */
18725 false, /* .isArray */
18726 false /* .isOptional */
18727},};
18728
18729/* Annotation */
18730static UA_DataTypeMember Annotation_members[3] = {
18731{
18732 UA_TYPENAME("Message") /* .memberName */
18733 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18734 0, /* .padding */
18735 false, /* .isArray */
18736 false /* .isOptional */
18737},
18738{
18739 UA_TYPENAME("UserName") /* .memberName */
18740 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18741 offsetof(UA_Annotation, userName) - offsetof(UA_Annotation, message) - sizeof(UA_String), /* .padding */
18742 false, /* .isArray */
18743 false /* .isOptional */
18744},
18745{
18746 UA_TYPENAME("AnnotationTime") /* .memberName */
18747 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
18748 offsetof(UA_Annotation, annotationTime) - offsetof(UA_Annotation, userName) - sizeof(UA_String), /* .padding */
18749 false, /* .isArray */
18750 false /* .isOptional */
18751},};
18752
18753/* ExceptionDeviationFormat */
18754#define ExceptionDeviationFormat_members NULL
18755
18756/* EndpointType */
18757static UA_DataTypeMember EndpointType_members[4] = {
18758{
18759 UA_TYPENAME("EndpointUrl") /* .memberName */
18760 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18761 0, /* .padding */
18762 false, /* .isArray */
18763 false /* .isOptional */
18764},
18765{
18766 UA_TYPENAME("SecurityMode") /* .memberName */
18767 &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE], /* .memberType */
18768 offsetof(UA_EndpointType, securityMode) - offsetof(UA_EndpointType, endpointUrl) - sizeof(UA_String), /* .padding */
18769 false, /* .isArray */
18770 false /* .isOptional */
18771},
18772{
18773 UA_TYPENAME("SecurityPolicyUri") /* .memberName */
18774 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18775 offsetof(UA_EndpointType, securityPolicyUri) - offsetof(UA_EndpointType, securityMode) - sizeof(UA_MessageSecurityMode), /* .padding */
18776 false, /* .isArray */
18777 false /* .isOptional */
18778},
18779{
18780 UA_TYPENAME("TransportProfileUri") /* .memberName */
18781 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18782 offsetof(UA_EndpointType, transportProfileUri) - offsetof(UA_EndpointType, securityPolicyUri) - sizeof(UA_String), /* .padding */
18783 false, /* .isArray */
18784 false /* .isOptional */
18785},};
18786
18787/* StructureDescription */
18788static UA_DataTypeMember StructureDescription_members[3] = {
18789{
18790 UA_TYPENAME("DataTypeId") /* .memberName */
18791 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
18792 0, /* .padding */
18793 false, /* .isArray */
18794 false /* .isOptional */
18795},
18796{
18797 UA_TYPENAME("Name") /* .memberName */
18798 &UA_TYPES[UA_TYPES_QUALIFIEDNAME], /* .memberType */
18799 offsetof(UA_StructureDescription, name) - offsetof(UA_StructureDescription, dataTypeId) - sizeof(UA_NodeId), /* .padding */
18800 false, /* .isArray */
18801 false /* .isOptional */
18802},
18803{
18804 UA_TYPENAME("StructureDefinition") /* .memberName */
18805 &UA_TYPES[UA_TYPES_STRUCTUREDEFINITION], /* .memberType */
18806 offsetof(UA_StructureDescription, structureDefinition) - offsetof(UA_StructureDescription, name) - sizeof(UA_QualifiedName), /* .padding */
18807 false, /* .isArray */
18808 false /* .isOptional */
18809},};
18810
18811/* FieldMetaData */
18812static UA_DataTypeMember FieldMetaData_members[10] = {
18813{
18814 UA_TYPENAME("Name") /* .memberName */
18815 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18816 0, /* .padding */
18817 false, /* .isArray */
18818 false /* .isOptional */
18819},
18820{
18821 UA_TYPENAME("Description") /* .memberName */
18822 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
18823 offsetof(UA_FieldMetaData, description) - offsetof(UA_FieldMetaData, name) - sizeof(UA_String), /* .padding */
18824 false, /* .isArray */
18825 false /* .isOptional */
18826},
18827{
18828 UA_TYPENAME("FieldFlags") /* .memberName */
18829 &UA_TYPES[UA_TYPES_DATASETFIELDFLAGS], /* .memberType */
18830 offsetof(UA_FieldMetaData, fieldFlags) - offsetof(UA_FieldMetaData, description) - sizeof(UA_LocalizedText), /* .padding */
18831 false, /* .isArray */
18832 false /* .isOptional */
18833},
18834{
18835 UA_TYPENAME("BuiltInType") /* .memberName */
18836 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
18837 offsetof(UA_FieldMetaData, builtInType) - offsetof(UA_FieldMetaData, fieldFlags) - sizeof(UA_DataSetFieldFlags), /* .padding */
18838 false, /* .isArray */
18839 false /* .isOptional */
18840},
18841{
18842 UA_TYPENAME("DataType") /* .memberName */
18843 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
18844 offsetof(UA_FieldMetaData, dataType) - offsetof(UA_FieldMetaData, builtInType) - sizeof(UA_Byte), /* .padding */
18845 false, /* .isArray */
18846 false /* .isOptional */
18847},
18848{
18849 UA_TYPENAME("ValueRank") /* .memberName */
18850 &UA_TYPES[UA_TYPES_INT32], /* .memberType */
18851 offsetof(UA_FieldMetaData, valueRank) - offsetof(UA_FieldMetaData, dataType) - sizeof(UA_NodeId), /* .padding */
18852 false, /* .isArray */
18853 false /* .isOptional */
18854},
18855{
18856 UA_TYPENAME("ArrayDimensions") /* .memberName */
18857 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18858 offsetof(UA_FieldMetaData, arrayDimensionsSize) - offsetof(UA_FieldMetaData, valueRank) - sizeof(UA_Int32), /* .padding */
18859 true, /* .isArray */
18860 false /* .isOptional */
18861},
18862{
18863 UA_TYPENAME("MaxStringLength") /* .memberName */
18864 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18865 offsetof(UA_FieldMetaData, maxStringLength) - offsetof(UA_FieldMetaData, arrayDimensions) - sizeof(void *), /* .padding */
18866 false, /* .isArray */
18867 false /* .isOptional */
18868},
18869{
18870 UA_TYPENAME("DataSetFieldId") /* .memberName */
18871 &UA_TYPES[UA_TYPES_GUID], /* .memberType */
18872 offsetof(UA_FieldMetaData, dataSetFieldId) - offsetof(UA_FieldMetaData, maxStringLength) - sizeof(UA_UInt32), /* .padding */
18873 false, /* .isArray */
18874 false /* .isOptional */
18875},
18876{
18877 UA_TYPENAME("Properties") /* .memberName */
18878 &UA_TYPES[UA_TYPES_KEYVALUEPAIR], /* .memberType */
18879 offsetof(UA_FieldMetaData, propertiesSize) - offsetof(UA_FieldMetaData, dataSetFieldId) - sizeof(UA_Guid), /* .padding */
18880 true, /* .isArray */
18881 false /* .isOptional */
18882},};
18883
18884/* PublishedEventsDataType */
18885static UA_DataTypeMember PublishedEventsDataType_members[3] = {
18886{
18887 UA_TYPENAME("EventNotifier") /* .memberName */
18888 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
18889 0, /* .padding */
18890 false, /* .isArray */
18891 false /* .isOptional */
18892},
18893{
18894 UA_TYPENAME("SelectedFields") /* .memberName */
18895 &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND], /* .memberType */
18896 offsetof(UA_PublishedEventsDataType, selectedFieldsSize) - offsetof(UA_PublishedEventsDataType, eventNotifier) - sizeof(UA_NodeId), /* .padding */
18897 true, /* .isArray */
18898 false /* .isOptional */
18899},
18900{
18901 UA_TYPENAME("Filter") /* .memberName */
18902 &UA_TYPES[UA_TYPES_CONTENTFILTER], /* .memberType */
18903 offsetof(UA_PublishedEventsDataType, filter) - offsetof(UA_PublishedEventsDataType, selectedFields) - sizeof(void *), /* .padding */
18904 false, /* .isArray */
18905 false /* .isOptional */
18906},};
18907
18908/* PubSubGroupDataType */
18909static UA_DataTypeMember PubSubGroupDataType_members[7] = {
18910{
18911 UA_TYPENAME("Name") /* .memberName */
18912 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18913 0, /* .padding */
18914 false, /* .isArray */
18915 false /* .isOptional */
18916},
18917{
18918 UA_TYPENAME("Enabled") /* .memberName */
18919 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
18920 offsetof(UA_PubSubGroupDataType, enabled) - offsetof(UA_PubSubGroupDataType, name) - sizeof(UA_String), /* .padding */
18921 false, /* .isArray */
18922 false /* .isOptional */
18923},
18924{
18925 UA_TYPENAME("SecurityMode") /* .memberName */
18926 &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE], /* .memberType */
18927 offsetof(UA_PubSubGroupDataType, securityMode) - offsetof(UA_PubSubGroupDataType, enabled) - sizeof(UA_Boolean), /* .padding */
18928 false, /* .isArray */
18929 false /* .isOptional */
18930},
18931{
18932 UA_TYPENAME("SecurityGroupId") /* .memberName */
18933 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18934 offsetof(UA_PubSubGroupDataType, securityGroupId) - offsetof(UA_PubSubGroupDataType, securityMode) - sizeof(UA_MessageSecurityMode), /* .padding */
18935 false, /* .isArray */
18936 false /* .isOptional */
18937},
18938{
18939 UA_TYPENAME("SecurityKeyServices") /* .memberName */
18940 &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION], /* .memberType */
18941 offsetof(UA_PubSubGroupDataType, securityKeyServicesSize) - offsetof(UA_PubSubGroupDataType, securityGroupId) - sizeof(UA_String), /* .padding */
18942 true, /* .isArray */
18943 false /* .isOptional */
18944},
18945{
18946 UA_TYPENAME("MaxNetworkMessageSize") /* .memberName */
18947 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
18948 offsetof(UA_PubSubGroupDataType, maxNetworkMessageSize) - offsetof(UA_PubSubGroupDataType, securityKeyServices) - sizeof(void *), /* .padding */
18949 false, /* .isArray */
18950 false /* .isOptional */
18951},
18952{
18953 UA_TYPENAME("GroupProperties") /* .memberName */
18954 &UA_TYPES[UA_TYPES_KEYVALUEPAIR], /* .memberType */
18955 offsetof(UA_PubSubGroupDataType, groupPropertiesSize) - offsetof(UA_PubSubGroupDataType, maxNetworkMessageSize) - sizeof(UA_UInt32), /* .padding */
18956 true, /* .isArray */
18957 false /* .isOptional */
18958},};
18959
18960/* WriterGroupDataType */
18961static UA_DataTypeMember WriterGroupDataType_members[16] = {
18962{
18963 UA_TYPENAME("Name") /* .memberName */
18964 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18965 0, /* .padding */
18966 false, /* .isArray */
18967 false /* .isOptional */
18968},
18969{
18970 UA_TYPENAME("Enabled") /* .memberName */
18971 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
18972 offsetof(UA_WriterGroupDataType, enabled) - offsetof(UA_WriterGroupDataType, name) - sizeof(UA_String), /* .padding */
18973 false, /* .isArray */
18974 false /* .isOptional */
18975},
18976{
18977 UA_TYPENAME("SecurityMode") /* .memberName */
18978 &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE], /* .memberType */
18979 offsetof(UA_WriterGroupDataType, securityMode) - offsetof(UA_WriterGroupDataType, enabled) - sizeof(UA_Boolean), /* .padding */
18980 false, /* .isArray */
18981 false /* .isOptional */
18982},
18983{
18984 UA_TYPENAME("SecurityGroupId") /* .memberName */
18985 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
18986 offsetof(UA_WriterGroupDataType, securityGroupId) - offsetof(UA_WriterGroupDataType, securityMode) - sizeof(UA_MessageSecurityMode), /* .padding */
18987 false, /* .isArray */
18988 false /* .isOptional */
18989},
18990{
18991 UA_TYPENAME("SecurityKeyServices") /* .memberName */
18992 &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION], /* .memberType */
18993 offsetof(UA_WriterGroupDataType, securityKeyServicesSize) - offsetof(UA_WriterGroupDataType, securityGroupId) - sizeof(UA_String), /* .padding */
18994 true, /* .isArray */
18995 false /* .isOptional */
18996},
18997{
18998 UA_TYPENAME("MaxNetworkMessageSize") /* .memberName */
18999 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
19000 offsetof(UA_WriterGroupDataType, maxNetworkMessageSize) - offsetof(UA_WriterGroupDataType, securityKeyServices) - sizeof(void *), /* .padding */
19001 false, /* .isArray */
19002 false /* .isOptional */
19003},
19004{
19005 UA_TYPENAME("GroupProperties") /* .memberName */
19006 &UA_TYPES[UA_TYPES_KEYVALUEPAIR], /* .memberType */
19007 offsetof(UA_WriterGroupDataType, groupPropertiesSize) - offsetof(UA_WriterGroupDataType, maxNetworkMessageSize) - sizeof(UA_UInt32), /* .padding */
19008 true, /* .isArray */
19009 false /* .isOptional */
19010},
19011{
19012 UA_TYPENAME("WriterGroupId") /* .memberName */
19013 &UA_TYPES[UA_TYPES_UINT16], /* .memberType */
19014 offsetof(UA_WriterGroupDataType, writerGroupId) - offsetof(UA_WriterGroupDataType, groupProperties) - sizeof(void *), /* .padding */
19015 false, /* .isArray */
19016 false /* .isOptional */
19017},
19018{
19019 UA_TYPENAME("PublishingInterval") /* .memberName */
19020 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
19021 offsetof(UA_WriterGroupDataType, publishingInterval) - offsetof(UA_WriterGroupDataType, writerGroupId) - sizeof(UA_UInt16), /* .padding */
19022 false, /* .isArray */
19023 false /* .isOptional */
19024},
19025{
19026 UA_TYPENAME("KeepAliveTime") /* .memberName */
19027 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
19028 offsetof(UA_WriterGroupDataType, keepAliveTime) - offsetof(UA_WriterGroupDataType, publishingInterval) - sizeof(UA_Double), /* .padding */
19029 false, /* .isArray */
19030 false /* .isOptional */
19031},
19032{
19033 UA_TYPENAME("Priority") /* .memberName */
19034 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
19035 offsetof(UA_WriterGroupDataType, priority) - offsetof(UA_WriterGroupDataType, keepAliveTime) - sizeof(UA_Double), /* .padding */
19036 false, /* .isArray */
19037 false /* .isOptional */
19038},
19039{
19040 UA_TYPENAME("LocaleIds") /* .memberName */
19041 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19042 offsetof(UA_WriterGroupDataType, localeIdsSize) - offsetof(UA_WriterGroupDataType, priority) - sizeof(UA_Byte), /* .padding */
19043 true, /* .isArray */
19044 false /* .isOptional */
19045},
19046{
19047 UA_TYPENAME("HeaderLayoutUri") /* .memberName */
19048 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19049 offsetof(UA_WriterGroupDataType, headerLayoutUri) - offsetof(UA_WriterGroupDataType, localeIds) - sizeof(void *), /* .padding */
19050 false, /* .isArray */
19051 false /* .isOptional */
19052},
19053{
19054 UA_TYPENAME("TransportSettings") /* .memberName */
19055 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
19056 offsetof(UA_WriterGroupDataType, transportSettings) - offsetof(UA_WriterGroupDataType, headerLayoutUri) - sizeof(UA_String), /* .padding */
19057 false, /* .isArray */
19058 false /* .isOptional */
19059},
19060{
19061 UA_TYPENAME("MessageSettings") /* .memberName */
19062 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
19063 offsetof(UA_WriterGroupDataType, messageSettings) - offsetof(UA_WriterGroupDataType, transportSettings) - sizeof(UA_ExtensionObject), /* .padding */
19064 false, /* .isArray */
19065 false /* .isOptional */
19066},
19067{
19068 UA_TYPENAME("DataSetWriters") /* .memberName */
19069 &UA_TYPES[UA_TYPES_DATASETWRITERDATATYPE], /* .memberType */
19070 offsetof(UA_WriterGroupDataType, dataSetWritersSize) - offsetof(UA_WriterGroupDataType, messageSettings) - sizeof(UA_ExtensionObject), /* .padding */
19071 true, /* .isArray */
19072 false /* .isOptional */
19073},};
19074
19075/* FieldTargetDataType */
19076static UA_DataTypeMember FieldTargetDataType_members[7] = {
19077{
19078 UA_TYPENAME("DataSetFieldId") /* .memberName */
19079 &UA_TYPES[UA_TYPES_GUID], /* .memberType */
19080 0, /* .padding */
19081 false, /* .isArray */
19082 false /* .isOptional */
19083},
19084{
19085 UA_TYPENAME("ReceiverIndexRange") /* .memberName */
19086 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19087 offsetof(UA_FieldTargetDataType, receiverIndexRange) - offsetof(UA_FieldTargetDataType, dataSetFieldId) - sizeof(UA_Guid), /* .padding */
19088 false, /* .isArray */
19089 false /* .isOptional */
19090},
19091{
19092 UA_TYPENAME("TargetNodeId") /* .memberName */
19093 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
19094 offsetof(UA_FieldTargetDataType, targetNodeId) - offsetof(UA_FieldTargetDataType, receiverIndexRange) - sizeof(UA_String), /* .padding */
19095 false, /* .isArray */
19096 false /* .isOptional */
19097},
19098{
19099 UA_TYPENAME("AttributeId") /* .memberName */
19100 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
19101 offsetof(UA_FieldTargetDataType, attributeId) - offsetof(UA_FieldTargetDataType, targetNodeId) - sizeof(UA_NodeId), /* .padding */
19102 false, /* .isArray */
19103 false /* .isOptional */
19104},
19105{
19106 UA_TYPENAME("WriteIndexRange") /* .memberName */
19107 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19108 offsetof(UA_FieldTargetDataType, writeIndexRange) - offsetof(UA_FieldTargetDataType, attributeId) - sizeof(UA_UInt32), /* .padding */
19109 false, /* .isArray */
19110 false /* .isOptional */
19111},
19112{
19113 UA_TYPENAME("OverrideValueHandling") /* .memberName */
19114 &UA_TYPES[UA_TYPES_OVERRIDEVALUEHANDLING], /* .memberType */
19115 offsetof(UA_FieldTargetDataType, overrideValueHandling) - offsetof(UA_FieldTargetDataType, writeIndexRange) - sizeof(UA_String), /* .padding */
19116 false, /* .isArray */
19117 false /* .isOptional */
19118},
19119{
19120 UA_TYPENAME("OverrideValue") /* .memberName */
19121 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
19122 offsetof(UA_FieldTargetDataType, overrideValue) - offsetof(UA_FieldTargetDataType, overrideValueHandling) - sizeof(UA_OverrideValueHandling), /* .padding */
19123 false, /* .isArray */
19124 false /* .isOptional */
19125},};
19126
19127/* SubscribedDataSetMirrorDataType */
19128static UA_DataTypeMember SubscribedDataSetMirrorDataType_members[2] = {
19129{
19130 UA_TYPENAME("ParentNodeName") /* .memberName */
19131 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19132 0, /* .padding */
19133 false, /* .isArray */
19134 false /* .isOptional */
19135},
19136{
19137 UA_TYPENAME("RolePermissions") /* .memberName */
19138 &UA_TYPES[UA_TYPES_ROLEPERMISSIONTYPE], /* .memberType */
19139 offsetof(UA_SubscribedDataSetMirrorDataType, rolePermissionsSize) - offsetof(UA_SubscribedDataSetMirrorDataType, parentNodeName) - sizeof(UA_String), /* .padding */
19140 true, /* .isArray */
19141 false /* .isOptional */
19142},};
19143
19144/* SecurityGroupDataType */
19145static UA_DataTypeMember SecurityGroupDataType_members[9] = {
19146{
19147 UA_TYPENAME("Name") /* .memberName */
19148 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19149 0, /* .padding */
19150 false, /* .isArray */
19151 false /* .isOptional */
19152},
19153{
19154 UA_TYPENAME("SecurityGroupFolder") /* .memberName */
19155 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19156 offsetof(UA_SecurityGroupDataType, securityGroupFolderSize) - offsetof(UA_SecurityGroupDataType, name) - sizeof(UA_String), /* .padding */
19157 true, /* .isArray */
19158 false /* .isOptional */
19159},
19160{
19161 UA_TYPENAME("KeyLifetime") /* .memberName */
19162 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
19163 offsetof(UA_SecurityGroupDataType, keyLifetime) - offsetof(UA_SecurityGroupDataType, securityGroupFolder) - sizeof(void *), /* .padding */
19164 false, /* .isArray */
19165 false /* .isOptional */
19166},
19167{
19168 UA_TYPENAME("SecurityPolicyUri") /* .memberName */
19169 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19170 offsetof(UA_SecurityGroupDataType, securityPolicyUri) - offsetof(UA_SecurityGroupDataType, keyLifetime) - sizeof(UA_Double), /* .padding */
19171 false, /* .isArray */
19172 false /* .isOptional */
19173},
19174{
19175 UA_TYPENAME("MaxFutureKeyCount") /* .memberName */
19176 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
19177 offsetof(UA_SecurityGroupDataType, maxFutureKeyCount) - offsetof(UA_SecurityGroupDataType, securityPolicyUri) - sizeof(UA_String), /* .padding */
19178 false, /* .isArray */
19179 false /* .isOptional */
19180},
19181{
19182 UA_TYPENAME("MaxPastKeyCount") /* .memberName */
19183 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
19184 offsetof(UA_SecurityGroupDataType, maxPastKeyCount) - offsetof(UA_SecurityGroupDataType, maxFutureKeyCount) - sizeof(UA_UInt32), /* .padding */
19185 false, /* .isArray */
19186 false /* .isOptional */
19187},
19188{
19189 UA_TYPENAME("SecurityGroupId") /* .memberName */
19190 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19191 offsetof(UA_SecurityGroupDataType, securityGroupId) - offsetof(UA_SecurityGroupDataType, maxPastKeyCount) - sizeof(UA_UInt32), /* .padding */
19192 false, /* .isArray */
19193 false /* .isOptional */
19194},
19195{
19196 UA_TYPENAME("RolePermissions") /* .memberName */
19197 &UA_TYPES[UA_TYPES_ROLEPERMISSIONTYPE], /* .memberType */
19198 offsetof(UA_SecurityGroupDataType, rolePermissionsSize) - offsetof(UA_SecurityGroupDataType, securityGroupId) - sizeof(UA_String), /* .padding */
19199 true, /* .isArray */
19200 false /* .isOptional */
19201},
19202{
19203 UA_TYPENAME("GroupProperties") /* .memberName */
19204 &UA_TYPES[UA_TYPES_KEYVALUEPAIR], /* .memberType */
19205 offsetof(UA_SecurityGroupDataType, groupPropertiesSize) - offsetof(UA_SecurityGroupDataType, rolePermissions) - sizeof(void *), /* .padding */
19206 true, /* .isArray */
19207 false /* .isOptional */
19208},};
19209
19210/* PubSubKeyPushTargetDataType */
19211static UA_DataTypeMember PubSubKeyPushTargetDataType_members[9] = {
19212{
19213 UA_TYPENAME("ApplicationUri") /* .memberName */
19214 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19215 0, /* .padding */
19216 false, /* .isArray */
19217 false /* .isOptional */
19218},
19219{
19220 UA_TYPENAME("PushTargetFolder") /* .memberName */
19221 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19222 offsetof(UA_PubSubKeyPushTargetDataType, pushTargetFolderSize) - offsetof(UA_PubSubKeyPushTargetDataType, applicationUri) - sizeof(UA_String), /* .padding */
19223 true, /* .isArray */
19224 false /* .isOptional */
19225},
19226{
19227 UA_TYPENAME("EndpointUrl") /* .memberName */
19228 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19229 offsetof(UA_PubSubKeyPushTargetDataType, endpointUrl) - offsetof(UA_PubSubKeyPushTargetDataType, pushTargetFolder) - sizeof(void *), /* .padding */
19230 false, /* .isArray */
19231 false /* .isOptional */
19232},
19233{
19234 UA_TYPENAME("SecurityPolicyUri") /* .memberName */
19235 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19236 offsetof(UA_PubSubKeyPushTargetDataType, securityPolicyUri) - offsetof(UA_PubSubKeyPushTargetDataType, endpointUrl) - sizeof(UA_String), /* .padding */
19237 false, /* .isArray */
19238 false /* .isOptional */
19239},
19240{
19241 UA_TYPENAME("UserTokenType") /* .memberName */
19242 &UA_TYPES[UA_TYPES_USERTOKENPOLICY], /* .memberType */
19243 offsetof(UA_PubSubKeyPushTargetDataType, userTokenType) - offsetof(UA_PubSubKeyPushTargetDataType, securityPolicyUri) - sizeof(UA_String), /* .padding */
19244 false, /* .isArray */
19245 false /* .isOptional */
19246},
19247{
19248 UA_TYPENAME("RequestedKeyCount") /* .memberName */
19249 &UA_TYPES[UA_TYPES_UINT16], /* .memberType */
19250 offsetof(UA_PubSubKeyPushTargetDataType, requestedKeyCount) - offsetof(UA_PubSubKeyPushTargetDataType, userTokenType) - sizeof(UA_UserTokenPolicy), /* .padding */
19251 false, /* .isArray */
19252 false /* .isOptional */
19253},
19254{
19255 UA_TYPENAME("RetryInterval") /* .memberName */
19256 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
19257 offsetof(UA_PubSubKeyPushTargetDataType, retryInterval) - offsetof(UA_PubSubKeyPushTargetDataType, requestedKeyCount) - sizeof(UA_UInt16), /* .padding */
19258 false, /* .isArray */
19259 false /* .isOptional */
19260},
19261{
19262 UA_TYPENAME("PushTargetProperties") /* .memberName */
19263 &UA_TYPES[UA_TYPES_KEYVALUEPAIR], /* .memberType */
19264 offsetof(UA_PubSubKeyPushTargetDataType, pushTargetPropertiesSize) - offsetof(UA_PubSubKeyPushTargetDataType, retryInterval) - sizeof(UA_Double), /* .padding */
19265 true, /* .isArray */
19266 false /* .isOptional */
19267},
19268{
19269 UA_TYPENAME("SecurityGroups") /* .memberName */
19270 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19271 offsetof(UA_PubSubKeyPushTargetDataType, securityGroupsSize) - offsetof(UA_PubSubKeyPushTargetDataType, pushTargetProperties) - sizeof(void *), /* .padding */
19272 true, /* .isArray */
19273 false /* .isOptional */
19274},};
19275
19276/* EnumDefinition */
19277static UA_DataTypeMember EnumDefinition_members[1] = {
19278{
19279 UA_TYPENAME("Fields") /* .memberName */
19280 &UA_TYPES[UA_TYPES_ENUMFIELD], /* .memberType */
19281 0, /* .padding */
19282 true, /* .isArray */
19283 false /* .isOptional */
19284},};
19285
19286/* ReadEventDetails */
19287static UA_DataTypeMember ReadEventDetails_members[4] = {
19288{
19289 UA_TYPENAME("NumValuesPerNode") /* .memberName */
19290 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
19291 0, /* .padding */
19292 false, /* .isArray */
19293 false /* .isOptional */
19294},
19295{
19296 UA_TYPENAME("StartTime") /* .memberName */
19297 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
19298 offsetof(UA_ReadEventDetails, startTime) - offsetof(UA_ReadEventDetails, numValuesPerNode) - sizeof(UA_UInt32), /* .padding */
19299 false, /* .isArray */
19300 false /* .isOptional */
19301},
19302{
19303 UA_TYPENAME("EndTime") /* .memberName */
19304 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
19305 offsetof(UA_ReadEventDetails, endTime) - offsetof(UA_ReadEventDetails, startTime) - sizeof(UA_DateTime), /* .padding */
19306 false, /* .isArray */
19307 false /* .isOptional */
19308},
19309{
19310 UA_TYPENAME("Filter") /* .memberName */
19311 &UA_TYPES[UA_TYPES_EVENTFILTER], /* .memberType */
19312 offsetof(UA_ReadEventDetails, filter) - offsetof(UA_ReadEventDetails, endTime) - sizeof(UA_DateTime), /* .padding */
19313 false, /* .isArray */
19314 false /* .isOptional */
19315},};
19316
19317/* ReadProcessedDetails */
19318static UA_DataTypeMember ReadProcessedDetails_members[5] = {
19319{
19320 UA_TYPENAME("StartTime") /* .memberName */
19321 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
19322 0, /* .padding */
19323 false, /* .isArray */
19324 false /* .isOptional */
19325},
19326{
19327 UA_TYPENAME("EndTime") /* .memberName */
19328 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
19329 offsetof(UA_ReadProcessedDetails, endTime) - offsetof(UA_ReadProcessedDetails, startTime) - sizeof(UA_DateTime), /* .padding */
19330 false, /* .isArray */
19331 false /* .isOptional */
19332},
19333{
19334 UA_TYPENAME("ProcessingInterval") /* .memberName */
19335 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
19336 offsetof(UA_ReadProcessedDetails, processingInterval) - offsetof(UA_ReadProcessedDetails, endTime) - sizeof(UA_DateTime), /* .padding */
19337 false, /* .isArray */
19338 false /* .isOptional */
19339},
19340{
19341 UA_TYPENAME("AggregateType") /* .memberName */
19342 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
19343 offsetof(UA_ReadProcessedDetails, aggregateTypeSize) - offsetof(UA_ReadProcessedDetails, processingInterval) - sizeof(UA_Double), /* .padding */
19344 true, /* .isArray */
19345 false /* .isOptional */
19346},
19347{
19348 UA_TYPENAME("AggregateConfiguration") /* .memberName */
19349 &UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION], /* .memberType */
19350 offsetof(UA_ReadProcessedDetails, aggregateConfiguration) - offsetof(UA_ReadProcessedDetails, aggregateType) - sizeof(void *), /* .padding */
19351 false, /* .isArray */
19352 false /* .isOptional */
19353},};
19354
19355/* ModificationInfo */
19356static UA_DataTypeMember ModificationInfo_members[3] = {
19357{
19358 UA_TYPENAME("ModificationTime") /* .memberName */
19359 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
19360 0, /* .padding */
19361 false, /* .isArray */
19362 false /* .isOptional */
19363},
19364{
19365 UA_TYPENAME("UpdateType") /* .memberName */
19366 &UA_TYPES[UA_TYPES_HISTORYUPDATETYPE], /* .memberType */
19367 offsetof(UA_ModificationInfo, updateType) - offsetof(UA_ModificationInfo, modificationTime) - sizeof(UA_DateTime), /* .padding */
19368 false, /* .isArray */
19369 false /* .isOptional */
19370},
19371{
19372 UA_TYPENAME("UserName") /* .memberName */
19373 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19374 offsetof(UA_ModificationInfo, userName) - offsetof(UA_ModificationInfo, updateType) - sizeof(UA_HistoryUpdateType), /* .padding */
19375 false, /* .isArray */
19376 false /* .isOptional */
19377},};
19378
19379/* HistoryModifiedData */
19380static UA_DataTypeMember HistoryModifiedData_members[2] = {
19381{
19382 UA_TYPENAME("DataValues") /* .memberName */
19383 &UA_TYPES[UA_TYPES_DATAVALUE], /* .memberType */
19384 0, /* .padding */
19385 true, /* .isArray */
19386 false /* .isOptional */
19387},
19388{
19389 UA_TYPENAME("ModificationInfos") /* .memberName */
19390 &UA_TYPES[UA_TYPES_MODIFICATIONINFO], /* .memberType */
19391 offsetof(UA_HistoryModifiedData, modificationInfosSize) - offsetof(UA_HistoryModifiedData, dataValues) - sizeof(void *), /* .padding */
19392 true, /* .isArray */
19393 false /* .isOptional */
19394},};
19395
19396/* HistoryEvent */
19397static UA_DataTypeMember HistoryEvent_members[1] = {
19398{
19399 UA_TYPENAME("Events") /* .memberName */
19400 &UA_TYPES[UA_TYPES_HISTORYEVENTFIELDLIST], /* .memberType */
19401 0, /* .padding */
19402 true, /* .isArray */
19403 false /* .isOptional */
19404},};
19405
19406/* UpdateEventDetails */
19407static UA_DataTypeMember UpdateEventDetails_members[4] = {
19408{
19409 UA_TYPENAME("NodeId") /* .memberName */
19410 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
19411 0, /* .padding */
19412 false, /* .isArray */
19413 false /* .isOptional */
19414},
19415{
19416 UA_TYPENAME("PerformInsertReplace") /* .memberName */
19417 &UA_TYPES[UA_TYPES_PERFORMUPDATETYPE], /* .memberType */
19418 offsetof(UA_UpdateEventDetails, performInsertReplace) - offsetof(UA_UpdateEventDetails, nodeId) - sizeof(UA_NodeId), /* .padding */
19419 false, /* .isArray */
19420 false /* .isOptional */
19421},
19422{
19423 UA_TYPENAME("Filter") /* .memberName */
19424 &UA_TYPES[UA_TYPES_EVENTFILTER], /* .memberType */
19425 offsetof(UA_UpdateEventDetails, filter) - offsetof(UA_UpdateEventDetails, performInsertReplace) - sizeof(UA_PerformUpdateType), /* .padding */
19426 false, /* .isArray */
19427 false /* .isOptional */
19428},
19429{
19430 UA_TYPENAME("EventData") /* .memberName */
19431 &UA_TYPES[UA_TYPES_HISTORYEVENTFIELDLIST], /* .memberType */
19432 offsetof(UA_UpdateEventDetails, eventDataSize) - offsetof(UA_UpdateEventDetails, filter) - sizeof(UA_EventFilter), /* .padding */
19433 true, /* .isArray */
19434 false /* .isOptional */
19435},};
19436
19437/* DataChangeNotification */
19438static UA_DataTypeMember DataChangeNotification_members[2] = {
19439{
19440 UA_TYPENAME("MonitoredItems") /* .memberName */
19441 &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION], /* .memberType */
19442 0, /* .padding */
19443 true, /* .isArray */
19444 false /* .isOptional */
19445},
19446{
19447 UA_TYPENAME("DiagnosticInfos") /* .memberName */
19448 &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], /* .memberType */
19449 offsetof(UA_DataChangeNotification, diagnosticInfosSize) - offsetof(UA_DataChangeNotification, monitoredItems) - sizeof(void *), /* .padding */
19450 true, /* .isArray */
19451 false /* .isOptional */
19452},};
19453
19454/* EventNotificationList */
19455static UA_DataTypeMember EventNotificationList_members[1] = {
19456{
19457 UA_TYPENAME("Events") /* .memberName */
19458 &UA_TYPES[UA_TYPES_EVENTFIELDLIST], /* .memberType */
19459 0, /* .padding */
19460 true, /* .isArray */
19461 false /* .isOptional */
19462},};
19463
19464/* SessionDiagnosticsDataType */
19465static UA_DataTypeMember SessionDiagnosticsDataType_members[43] = {
19466{
19467 UA_TYPENAME("SessionId") /* .memberName */
19468 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
19469 0, /* .padding */
19470 false, /* .isArray */
19471 false /* .isOptional */
19472},
19473{
19474 UA_TYPENAME("SessionName") /* .memberName */
19475 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19476 offsetof(UA_SessionDiagnosticsDataType, sessionName) - offsetof(UA_SessionDiagnosticsDataType, sessionId) - sizeof(UA_NodeId), /* .padding */
19477 false, /* .isArray */
19478 false /* .isOptional */
19479},
19480{
19481 UA_TYPENAME("ClientDescription") /* .memberName */
19482 &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION], /* .memberType */
19483 offsetof(UA_SessionDiagnosticsDataType, clientDescription) - offsetof(UA_SessionDiagnosticsDataType, sessionName) - sizeof(UA_String), /* .padding */
19484 false, /* .isArray */
19485 false /* .isOptional */
19486},
19487{
19488 UA_TYPENAME("ServerUri") /* .memberName */
19489 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19490 offsetof(UA_SessionDiagnosticsDataType, serverUri) - offsetof(UA_SessionDiagnosticsDataType, clientDescription) - sizeof(UA_ApplicationDescription), /* .padding */
19491 false, /* .isArray */
19492 false /* .isOptional */
19493},
19494{
19495 UA_TYPENAME("EndpointUrl") /* .memberName */
19496 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19497 offsetof(UA_SessionDiagnosticsDataType, endpointUrl) - offsetof(UA_SessionDiagnosticsDataType, serverUri) - sizeof(UA_String), /* .padding */
19498 false, /* .isArray */
19499 false /* .isOptional */
19500},
19501{
19502 UA_TYPENAME("LocaleIds") /* .memberName */
19503 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19504 offsetof(UA_SessionDiagnosticsDataType, localeIdsSize) - offsetof(UA_SessionDiagnosticsDataType, endpointUrl) - sizeof(UA_String), /* .padding */
19505 true, /* .isArray */
19506 false /* .isOptional */
19507},
19508{
19509 UA_TYPENAME("ActualSessionTimeout") /* .memberName */
19510 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
19511 offsetof(UA_SessionDiagnosticsDataType, actualSessionTimeout) - offsetof(UA_SessionDiagnosticsDataType, localeIds) - sizeof(void *), /* .padding */
19512 false, /* .isArray */
19513 false /* .isOptional */
19514},
19515{
19516 UA_TYPENAME("MaxResponseMessageSize") /* .memberName */
19517 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
19518 offsetof(UA_SessionDiagnosticsDataType, maxResponseMessageSize) - offsetof(UA_SessionDiagnosticsDataType, actualSessionTimeout) - sizeof(UA_Double), /* .padding */
19519 false, /* .isArray */
19520 false /* .isOptional */
19521},
19522{
19523 UA_TYPENAME("ClientConnectionTime") /* .memberName */
19524 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
19525 offsetof(UA_SessionDiagnosticsDataType, clientConnectionTime) - offsetof(UA_SessionDiagnosticsDataType, maxResponseMessageSize) - sizeof(UA_UInt32), /* .padding */
19526 false, /* .isArray */
19527 false /* .isOptional */
19528},
19529{
19530 UA_TYPENAME("ClientLastContactTime") /* .memberName */
19531 &UA_TYPES[UA_TYPES_DATETIME], /* .memberType */
19532 offsetof(UA_SessionDiagnosticsDataType, clientLastContactTime) - offsetof(UA_SessionDiagnosticsDataType, clientConnectionTime) - sizeof(UA_DateTime), /* .padding */
19533 false, /* .isArray */
19534 false /* .isOptional */
19535},
19536{
19537 UA_TYPENAME("CurrentSubscriptionsCount") /* .memberName */
19538 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
19539 offsetof(UA_SessionDiagnosticsDataType, currentSubscriptionsCount) - offsetof(UA_SessionDiagnosticsDataType, clientLastContactTime) - sizeof(UA_DateTime), /* .padding */
19540 false, /* .isArray */
19541 false /* .isOptional */
19542},
19543{
19544 UA_TYPENAME("CurrentMonitoredItemsCount") /* .memberName */
19545 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
19546 offsetof(UA_SessionDiagnosticsDataType, currentMonitoredItemsCount) - offsetof(UA_SessionDiagnosticsDataType, currentSubscriptionsCount) - sizeof(UA_UInt32), /* .padding */
19547 false, /* .isArray */
19548 false /* .isOptional */
19549},
19550{
19551 UA_TYPENAME("CurrentPublishRequestsInQueue") /* .memberName */
19552 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
19553 offsetof(UA_SessionDiagnosticsDataType, currentPublishRequestsInQueue) - offsetof(UA_SessionDiagnosticsDataType, currentMonitoredItemsCount) - sizeof(UA_UInt32), /* .padding */
19554 false, /* .isArray */
19555 false /* .isOptional */
19556},
19557{
19558 UA_TYPENAME("TotalRequestCount") /* .memberName */
19559 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19560 offsetof(UA_SessionDiagnosticsDataType, totalRequestCount) - offsetof(UA_SessionDiagnosticsDataType, currentPublishRequestsInQueue) - sizeof(UA_UInt32), /* .padding */
19561 false, /* .isArray */
19562 false /* .isOptional */
19563},
19564{
19565 UA_TYPENAME("UnauthorizedRequestCount") /* .memberName */
19566 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
19567 offsetof(UA_SessionDiagnosticsDataType, unauthorizedRequestCount) - offsetof(UA_SessionDiagnosticsDataType, totalRequestCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19568 false, /* .isArray */
19569 false /* .isOptional */
19570},
19571{
19572 UA_TYPENAME("ReadCount") /* .memberName */
19573 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19574 offsetof(UA_SessionDiagnosticsDataType, readCount) - offsetof(UA_SessionDiagnosticsDataType, unauthorizedRequestCount) - sizeof(UA_UInt32), /* .padding */
19575 false, /* .isArray */
19576 false /* .isOptional */
19577},
19578{
19579 UA_TYPENAME("HistoryReadCount") /* .memberName */
19580 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19581 offsetof(UA_SessionDiagnosticsDataType, historyReadCount) - offsetof(UA_SessionDiagnosticsDataType, readCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19582 false, /* .isArray */
19583 false /* .isOptional */
19584},
19585{
19586 UA_TYPENAME("WriteCount") /* .memberName */
19587 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19588 offsetof(UA_SessionDiagnosticsDataType, writeCount) - offsetof(UA_SessionDiagnosticsDataType, historyReadCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19589 false, /* .isArray */
19590 false /* .isOptional */
19591},
19592{
19593 UA_TYPENAME("HistoryUpdateCount") /* .memberName */
19594 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19595 offsetof(UA_SessionDiagnosticsDataType, historyUpdateCount) - offsetof(UA_SessionDiagnosticsDataType, writeCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19596 false, /* .isArray */
19597 false /* .isOptional */
19598},
19599{
19600 UA_TYPENAME("CallCount") /* .memberName */
19601 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19602 offsetof(UA_SessionDiagnosticsDataType, callCount) - offsetof(UA_SessionDiagnosticsDataType, historyUpdateCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19603 false, /* .isArray */
19604 false /* .isOptional */
19605},
19606{
19607 UA_TYPENAME("CreateMonitoredItemsCount") /* .memberName */
19608 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19609 offsetof(UA_SessionDiagnosticsDataType, createMonitoredItemsCount) - offsetof(UA_SessionDiagnosticsDataType, callCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19610 false, /* .isArray */
19611 false /* .isOptional */
19612},
19613{
19614 UA_TYPENAME("ModifyMonitoredItemsCount") /* .memberName */
19615 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19616 offsetof(UA_SessionDiagnosticsDataType, modifyMonitoredItemsCount) - offsetof(UA_SessionDiagnosticsDataType, createMonitoredItemsCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19617 false, /* .isArray */
19618 false /* .isOptional */
19619},
19620{
19621 UA_TYPENAME("SetMonitoringModeCount") /* .memberName */
19622 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19623 offsetof(UA_SessionDiagnosticsDataType, setMonitoringModeCount) - offsetof(UA_SessionDiagnosticsDataType, modifyMonitoredItemsCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19624 false, /* .isArray */
19625 false /* .isOptional */
19626},
19627{
19628 UA_TYPENAME("SetTriggeringCount") /* .memberName */
19629 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19630 offsetof(UA_SessionDiagnosticsDataType, setTriggeringCount) - offsetof(UA_SessionDiagnosticsDataType, setMonitoringModeCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19631 false, /* .isArray */
19632 false /* .isOptional */
19633},
19634{
19635 UA_TYPENAME("DeleteMonitoredItemsCount") /* .memberName */
19636 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19637 offsetof(UA_SessionDiagnosticsDataType, deleteMonitoredItemsCount) - offsetof(UA_SessionDiagnosticsDataType, setTriggeringCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19638 false, /* .isArray */
19639 false /* .isOptional */
19640},
19641{
19642 UA_TYPENAME("CreateSubscriptionCount") /* .memberName */
19643 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19644 offsetof(UA_SessionDiagnosticsDataType, createSubscriptionCount) - offsetof(UA_SessionDiagnosticsDataType, deleteMonitoredItemsCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19645 false, /* .isArray */
19646 false /* .isOptional */
19647},
19648{
19649 UA_TYPENAME("ModifySubscriptionCount") /* .memberName */
19650 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19651 offsetof(UA_SessionDiagnosticsDataType, modifySubscriptionCount) - offsetof(UA_SessionDiagnosticsDataType, createSubscriptionCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19652 false, /* .isArray */
19653 false /* .isOptional */
19654},
19655{
19656 UA_TYPENAME("SetPublishingModeCount") /* .memberName */
19657 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19658 offsetof(UA_SessionDiagnosticsDataType, setPublishingModeCount) - offsetof(UA_SessionDiagnosticsDataType, modifySubscriptionCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19659 false, /* .isArray */
19660 false /* .isOptional */
19661},
19662{
19663 UA_TYPENAME("PublishCount") /* .memberName */
19664 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19665 offsetof(UA_SessionDiagnosticsDataType, publishCount) - offsetof(UA_SessionDiagnosticsDataType, setPublishingModeCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19666 false, /* .isArray */
19667 false /* .isOptional */
19668},
19669{
19670 UA_TYPENAME("RepublishCount") /* .memberName */
19671 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19672 offsetof(UA_SessionDiagnosticsDataType, republishCount) - offsetof(UA_SessionDiagnosticsDataType, publishCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19673 false, /* .isArray */
19674 false /* .isOptional */
19675},
19676{
19677 UA_TYPENAME("TransferSubscriptionsCount") /* .memberName */
19678 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19679 offsetof(UA_SessionDiagnosticsDataType, transferSubscriptionsCount) - offsetof(UA_SessionDiagnosticsDataType, republishCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19680 false, /* .isArray */
19681 false /* .isOptional */
19682},
19683{
19684 UA_TYPENAME("DeleteSubscriptionsCount") /* .memberName */
19685 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19686 offsetof(UA_SessionDiagnosticsDataType, deleteSubscriptionsCount) - offsetof(UA_SessionDiagnosticsDataType, transferSubscriptionsCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19687 false, /* .isArray */
19688 false /* .isOptional */
19689},
19690{
19691 UA_TYPENAME("AddNodesCount") /* .memberName */
19692 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19693 offsetof(UA_SessionDiagnosticsDataType, addNodesCount) - offsetof(UA_SessionDiagnosticsDataType, deleteSubscriptionsCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19694 false, /* .isArray */
19695 false /* .isOptional */
19696},
19697{
19698 UA_TYPENAME("AddReferencesCount") /* .memberName */
19699 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19700 offsetof(UA_SessionDiagnosticsDataType, addReferencesCount) - offsetof(UA_SessionDiagnosticsDataType, addNodesCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19701 false, /* .isArray */
19702 false /* .isOptional */
19703},
19704{
19705 UA_TYPENAME("DeleteNodesCount") /* .memberName */
19706 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19707 offsetof(UA_SessionDiagnosticsDataType, deleteNodesCount) - offsetof(UA_SessionDiagnosticsDataType, addReferencesCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19708 false, /* .isArray */
19709 false /* .isOptional */
19710},
19711{
19712 UA_TYPENAME("DeleteReferencesCount") /* .memberName */
19713 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19714 offsetof(UA_SessionDiagnosticsDataType, deleteReferencesCount) - offsetof(UA_SessionDiagnosticsDataType, deleteNodesCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19715 false, /* .isArray */
19716 false /* .isOptional */
19717},
19718{
19719 UA_TYPENAME("BrowseCount") /* .memberName */
19720 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19721 offsetof(UA_SessionDiagnosticsDataType, browseCount) - offsetof(UA_SessionDiagnosticsDataType, deleteReferencesCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19722 false, /* .isArray */
19723 false /* .isOptional */
19724},
19725{
19726 UA_TYPENAME("BrowseNextCount") /* .memberName */
19727 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19728 offsetof(UA_SessionDiagnosticsDataType, browseNextCount) - offsetof(UA_SessionDiagnosticsDataType, browseCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19729 false, /* .isArray */
19730 false /* .isOptional */
19731},
19732{
19733 UA_TYPENAME("TranslateBrowsePathsToNodeIdsCount") /* .memberName */
19734 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19735 offsetof(UA_SessionDiagnosticsDataType, translateBrowsePathsToNodeIdsCount) - offsetof(UA_SessionDiagnosticsDataType, browseNextCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19736 false, /* .isArray */
19737 false /* .isOptional */
19738},
19739{
19740 UA_TYPENAME("QueryFirstCount") /* .memberName */
19741 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19742 offsetof(UA_SessionDiagnosticsDataType, queryFirstCount) - offsetof(UA_SessionDiagnosticsDataType, translateBrowsePathsToNodeIdsCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19743 false, /* .isArray */
19744 false /* .isOptional */
19745},
19746{
19747 UA_TYPENAME("QueryNextCount") /* .memberName */
19748 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19749 offsetof(UA_SessionDiagnosticsDataType, queryNextCount) - offsetof(UA_SessionDiagnosticsDataType, queryFirstCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19750 false, /* .isArray */
19751 false /* .isOptional */
19752},
19753{
19754 UA_TYPENAME("RegisterNodesCount") /* .memberName */
19755 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19756 offsetof(UA_SessionDiagnosticsDataType, registerNodesCount) - offsetof(UA_SessionDiagnosticsDataType, queryNextCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19757 false, /* .isArray */
19758 false /* .isOptional */
19759},
19760{
19761 UA_TYPENAME("UnregisterNodesCount") /* .memberName */
19762 &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], /* .memberType */
19763 offsetof(UA_SessionDiagnosticsDataType, unregisterNodesCount) - offsetof(UA_SessionDiagnosticsDataType, registerNodesCount) - sizeof(UA_ServiceCounterDataType), /* .padding */
19764 false, /* .isArray */
19765 false /* .isOptional */
19766},};
19767
19768/* EnumDescription */
19769static UA_DataTypeMember EnumDescription_members[4] = {
19770{
19771 UA_TYPENAME("DataTypeId") /* .memberName */
19772 &UA_TYPES[UA_TYPES_NODEID], /* .memberType */
19773 0, /* .padding */
19774 false, /* .isArray */
19775 false /* .isOptional */
19776},
19777{
19778 UA_TYPENAME("Name") /* .memberName */
19779 &UA_TYPES[UA_TYPES_QUALIFIEDNAME], /* .memberType */
19780 offsetof(UA_EnumDescription, name) - offsetof(UA_EnumDescription, dataTypeId) - sizeof(UA_NodeId), /* .padding */
19781 false, /* .isArray */
19782 false /* .isOptional */
19783},
19784{
19785 UA_TYPENAME("EnumDefinition") /* .memberName */
19786 &UA_TYPES[UA_TYPES_ENUMDEFINITION], /* .memberType */
19787 offsetof(UA_EnumDescription, enumDefinition) - offsetof(UA_EnumDescription, name) - sizeof(UA_QualifiedName), /* .padding */
19788 false, /* .isArray */
19789 false /* .isOptional */
19790},
19791{
19792 UA_TYPENAME("BuiltInType") /* .memberName */
19793 &UA_TYPES[UA_TYPES_BYTE], /* .memberType */
19794 offsetof(UA_EnumDescription, builtInType) - offsetof(UA_EnumDescription, enumDefinition) - sizeof(UA_EnumDefinition), /* .padding */
19795 false, /* .isArray */
19796 false /* .isOptional */
19797},};
19798
19799/* UABinaryFileDataType */
19800static UA_DataTypeMember UABinaryFileDataType_members[7] = {
19801{
19802 UA_TYPENAME("Namespaces") /* .memberName */
19803 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19804 0, /* .padding */
19805 true, /* .isArray */
19806 false /* .isOptional */
19807},
19808{
19809 UA_TYPENAME("StructureDataTypes") /* .memberName */
19810 &UA_TYPES[UA_TYPES_STRUCTUREDESCRIPTION], /* .memberType */
19811 offsetof(UA_UABinaryFileDataType, structureDataTypesSize) - offsetof(UA_UABinaryFileDataType, namespaces) - sizeof(void *), /* .padding */
19812 true, /* .isArray */
19813 false /* .isOptional */
19814},
19815{
19816 UA_TYPENAME("EnumDataTypes") /* .memberName */
19817 &UA_TYPES[UA_TYPES_ENUMDESCRIPTION], /* .memberType */
19818 offsetof(UA_UABinaryFileDataType, enumDataTypesSize) - offsetof(UA_UABinaryFileDataType, structureDataTypes) - sizeof(void *), /* .padding */
19819 true, /* .isArray */
19820 false /* .isOptional */
19821},
19822{
19823 UA_TYPENAME("SimpleDataTypes") /* .memberName */
19824 &UA_TYPES[UA_TYPES_SIMPLETYPEDESCRIPTION], /* .memberType */
19825 offsetof(UA_UABinaryFileDataType, simpleDataTypesSize) - offsetof(UA_UABinaryFileDataType, enumDataTypes) - sizeof(void *), /* .padding */
19826 true, /* .isArray */
19827 false /* .isOptional */
19828},
19829{
19830 UA_TYPENAME("SchemaLocation") /* .memberName */
19831 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19832 offsetof(UA_UABinaryFileDataType, schemaLocation) - offsetof(UA_UABinaryFileDataType, simpleDataTypes) - sizeof(void *), /* .padding */
19833 false, /* .isArray */
19834 false /* .isOptional */
19835},
19836{
19837 UA_TYPENAME("FileHeader") /* .memberName */
19838 &UA_TYPES[UA_TYPES_KEYVALUEPAIR], /* .memberType */
19839 offsetof(UA_UABinaryFileDataType, fileHeaderSize) - offsetof(UA_UABinaryFileDataType, schemaLocation) - sizeof(UA_String), /* .padding */
19840 true, /* .isArray */
19841 false /* .isOptional */
19842},
19843{
19844 UA_TYPENAME("Body") /* .memberName */
19845 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
19846 offsetof(UA_UABinaryFileDataType, body) - offsetof(UA_UABinaryFileDataType, fileHeader) - sizeof(void *), /* .padding */
19847 false, /* .isArray */
19848 false /* .isOptional */
19849},};
19850
19851/* DataSetMetaDataType */
19852static UA_DataTypeMember DataSetMetaDataType_members[9] = {
19853{
19854 UA_TYPENAME("Namespaces") /* .memberName */
19855 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19856 0, /* .padding */
19857 true, /* .isArray */
19858 false /* .isOptional */
19859},
19860{
19861 UA_TYPENAME("StructureDataTypes") /* .memberName */
19862 &UA_TYPES[UA_TYPES_STRUCTUREDESCRIPTION], /* .memberType */
19863 offsetof(UA_DataSetMetaDataType, structureDataTypesSize) - offsetof(UA_DataSetMetaDataType, namespaces) - sizeof(void *), /* .padding */
19864 true, /* .isArray */
19865 false /* .isOptional */
19866},
19867{
19868 UA_TYPENAME("EnumDataTypes") /* .memberName */
19869 &UA_TYPES[UA_TYPES_ENUMDESCRIPTION], /* .memberType */
19870 offsetof(UA_DataSetMetaDataType, enumDataTypesSize) - offsetof(UA_DataSetMetaDataType, structureDataTypes) - sizeof(void *), /* .padding */
19871 true, /* .isArray */
19872 false /* .isOptional */
19873},
19874{
19875 UA_TYPENAME("SimpleDataTypes") /* .memberName */
19876 &UA_TYPES[UA_TYPES_SIMPLETYPEDESCRIPTION], /* .memberType */
19877 offsetof(UA_DataSetMetaDataType, simpleDataTypesSize) - offsetof(UA_DataSetMetaDataType, enumDataTypes) - sizeof(void *), /* .padding */
19878 true, /* .isArray */
19879 false /* .isOptional */
19880},
19881{
19882 UA_TYPENAME("Name") /* .memberName */
19883 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19884 offsetof(UA_DataSetMetaDataType, name) - offsetof(UA_DataSetMetaDataType, simpleDataTypes) - sizeof(void *), /* .padding */
19885 false, /* .isArray */
19886 false /* .isOptional */
19887},
19888{
19889 UA_TYPENAME("Description") /* .memberName */
19890 &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], /* .memberType */
19891 offsetof(UA_DataSetMetaDataType, description) - offsetof(UA_DataSetMetaDataType, name) - sizeof(UA_String), /* .padding */
19892 false, /* .isArray */
19893 false /* .isOptional */
19894},
19895{
19896 UA_TYPENAME("Fields") /* .memberName */
19897 &UA_TYPES[UA_TYPES_FIELDMETADATA], /* .memberType */
19898 offsetof(UA_DataSetMetaDataType, fieldsSize) - offsetof(UA_DataSetMetaDataType, description) - sizeof(UA_LocalizedText), /* .padding */
19899 true, /* .isArray */
19900 false /* .isOptional */
19901},
19902{
19903 UA_TYPENAME("DataSetClassId") /* .memberName */
19904 &UA_TYPES[UA_TYPES_GUID], /* .memberType */
19905 offsetof(UA_DataSetMetaDataType, dataSetClassId) - offsetof(UA_DataSetMetaDataType, fields) - sizeof(void *), /* .padding */
19906 false, /* .isArray */
19907 false /* .isOptional */
19908},
19909{
19910 UA_TYPENAME("ConfigurationVersion") /* .memberName */
19911 &UA_TYPES[UA_TYPES_CONFIGURATIONVERSIONDATATYPE], /* .memberType */
19912 offsetof(UA_DataSetMetaDataType, configurationVersion) - offsetof(UA_DataSetMetaDataType, dataSetClassId) - sizeof(UA_Guid), /* .padding */
19913 false, /* .isArray */
19914 false /* .isOptional */
19915},};
19916
19917/* PublishedDataSetDataType */
19918static UA_DataTypeMember PublishedDataSetDataType_members[5] = {
19919{
19920 UA_TYPENAME("Name") /* .memberName */
19921 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19922 0, /* .padding */
19923 false, /* .isArray */
19924 false /* .isOptional */
19925},
19926{
19927 UA_TYPENAME("DataSetFolder") /* .memberName */
19928 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19929 offsetof(UA_PublishedDataSetDataType, dataSetFolderSize) - offsetof(UA_PublishedDataSetDataType, name) - sizeof(UA_String), /* .padding */
19930 true, /* .isArray */
19931 false /* .isOptional */
19932},
19933{
19934 UA_TYPENAME("DataSetMetaData") /* .memberName */
19935 &UA_TYPES[UA_TYPES_DATASETMETADATATYPE], /* .memberType */
19936 offsetof(UA_PublishedDataSetDataType, dataSetMetaData) - offsetof(UA_PublishedDataSetDataType, dataSetFolder) - sizeof(void *), /* .padding */
19937 false, /* .isArray */
19938 false /* .isOptional */
19939},
19940{
19941 UA_TYPENAME("ExtensionFields") /* .memberName */
19942 &UA_TYPES[UA_TYPES_KEYVALUEPAIR], /* .memberType */
19943 offsetof(UA_PublishedDataSetDataType, extensionFieldsSize) - offsetof(UA_PublishedDataSetDataType, dataSetMetaData) - sizeof(UA_DataSetMetaDataType), /* .padding */
19944 true, /* .isArray */
19945 false /* .isOptional */
19946},
19947{
19948 UA_TYPENAME("DataSetSource") /* .memberName */
19949 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
19950 offsetof(UA_PublishedDataSetDataType, dataSetSource) - offsetof(UA_PublishedDataSetDataType, extensionFields) - sizeof(void *), /* .padding */
19951 false, /* .isArray */
19952 false /* .isOptional */
19953},};
19954
19955/* DataSetReaderDataType */
19956static UA_DataTypeMember DataSetReaderDataType_members[17] = {
19957{
19958 UA_TYPENAME("Name") /* .memberName */
19959 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
19960 0, /* .padding */
19961 false, /* .isArray */
19962 false /* .isOptional */
19963},
19964{
19965 UA_TYPENAME("Enabled") /* .memberName */
19966 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
19967 offsetof(UA_DataSetReaderDataType, enabled) - offsetof(UA_DataSetReaderDataType, name) - sizeof(UA_String), /* .padding */
19968 false, /* .isArray */
19969 false /* .isOptional */
19970},
19971{
19972 UA_TYPENAME("PublisherId") /* .memberName */
19973 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
19974 offsetof(UA_DataSetReaderDataType, publisherId) - offsetof(UA_DataSetReaderDataType, enabled) - sizeof(UA_Boolean), /* .padding */
19975 false, /* .isArray */
19976 false /* .isOptional */
19977},
19978{
19979 UA_TYPENAME("WriterGroupId") /* .memberName */
19980 &UA_TYPES[UA_TYPES_UINT16], /* .memberType */
19981 offsetof(UA_DataSetReaderDataType, writerGroupId) - offsetof(UA_DataSetReaderDataType, publisherId) - sizeof(UA_Variant), /* .padding */
19982 false, /* .isArray */
19983 false /* .isOptional */
19984},
19985{
19986 UA_TYPENAME("DataSetWriterId") /* .memberName */
19987 &UA_TYPES[UA_TYPES_UINT16], /* .memberType */
19988 offsetof(UA_DataSetReaderDataType, dataSetWriterId) - offsetof(UA_DataSetReaderDataType, writerGroupId) - sizeof(UA_UInt16), /* .padding */
19989 false, /* .isArray */
19990 false /* .isOptional */
19991},
19992{
19993 UA_TYPENAME("DataSetMetaData") /* .memberName */
19994 &UA_TYPES[UA_TYPES_DATASETMETADATATYPE], /* .memberType */
19995 offsetof(UA_DataSetReaderDataType, dataSetMetaData) - offsetof(UA_DataSetReaderDataType, dataSetWriterId) - sizeof(UA_UInt16), /* .padding */
19996 false, /* .isArray */
19997 false /* .isOptional */
19998},
19999{
20000 UA_TYPENAME("DataSetFieldContentMask") /* .memberName */
20001 &UA_TYPES[UA_TYPES_DATASETFIELDCONTENTMASK], /* .memberType */
20002 offsetof(UA_DataSetReaderDataType, dataSetFieldContentMask) - offsetof(UA_DataSetReaderDataType, dataSetMetaData) - sizeof(UA_DataSetMetaDataType), /* .padding */
20003 false, /* .isArray */
20004 false /* .isOptional */
20005},
20006{
20007 UA_TYPENAME("MessageReceiveTimeout") /* .memberName */
20008 &UA_TYPES[UA_TYPES_DOUBLE], /* .memberType */
20009 offsetof(UA_DataSetReaderDataType, messageReceiveTimeout) - offsetof(UA_DataSetReaderDataType, dataSetFieldContentMask) - sizeof(UA_DataSetFieldContentMask), /* .padding */
20010 false, /* .isArray */
20011 false /* .isOptional */
20012},
20013{
20014 UA_TYPENAME("KeyFrameCount") /* .memberName */
20015 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
20016 offsetof(UA_DataSetReaderDataType, keyFrameCount) - offsetof(UA_DataSetReaderDataType, messageReceiveTimeout) - sizeof(UA_Double), /* .padding */
20017 false, /* .isArray */
20018 false /* .isOptional */
20019},
20020{
20021 UA_TYPENAME("HeaderLayoutUri") /* .memberName */
20022 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
20023 offsetof(UA_DataSetReaderDataType, headerLayoutUri) - offsetof(UA_DataSetReaderDataType, keyFrameCount) - sizeof(UA_UInt32), /* .padding */
20024 false, /* .isArray */
20025 false /* .isOptional */
20026},
20027{
20028 UA_TYPENAME("SecurityMode") /* .memberName */
20029 &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE], /* .memberType */
20030 offsetof(UA_DataSetReaderDataType, securityMode) - offsetof(UA_DataSetReaderDataType, headerLayoutUri) - sizeof(UA_String), /* .padding */
20031 false, /* .isArray */
20032 false /* .isOptional */
20033},
20034{
20035 UA_TYPENAME("SecurityGroupId") /* .memberName */
20036 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
20037 offsetof(UA_DataSetReaderDataType, securityGroupId) - offsetof(UA_DataSetReaderDataType, securityMode) - sizeof(UA_MessageSecurityMode), /* .padding */
20038 false, /* .isArray */
20039 false /* .isOptional */
20040},
20041{
20042 UA_TYPENAME("SecurityKeyServices") /* .memberName */
20043 &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION], /* .memberType */
20044 offsetof(UA_DataSetReaderDataType, securityKeyServicesSize) - offsetof(UA_DataSetReaderDataType, securityGroupId) - sizeof(UA_String), /* .padding */
20045 true, /* .isArray */
20046 false /* .isOptional */
20047},
20048{
20049 UA_TYPENAME("DataSetReaderProperties") /* .memberName */
20050 &UA_TYPES[UA_TYPES_KEYVALUEPAIR], /* .memberType */
20051 offsetof(UA_DataSetReaderDataType, dataSetReaderPropertiesSize) - offsetof(UA_DataSetReaderDataType, securityKeyServices) - sizeof(void *), /* .padding */
20052 true, /* .isArray */
20053 false /* .isOptional */
20054},
20055{
20056 UA_TYPENAME("TransportSettings") /* .memberName */
20057 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
20058 offsetof(UA_DataSetReaderDataType, transportSettings) - offsetof(UA_DataSetReaderDataType, dataSetReaderProperties) - sizeof(void *), /* .padding */
20059 false, /* .isArray */
20060 false /* .isOptional */
20061},
20062{
20063 UA_TYPENAME("MessageSettings") /* .memberName */
20064 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
20065 offsetof(UA_DataSetReaderDataType, messageSettings) - offsetof(UA_DataSetReaderDataType, transportSettings) - sizeof(UA_ExtensionObject), /* .padding */
20066 false, /* .isArray */
20067 false /* .isOptional */
20068},
20069{
20070 UA_TYPENAME("SubscribedDataSet") /* .memberName */
20071 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
20072 offsetof(UA_DataSetReaderDataType, subscribedDataSet) - offsetof(UA_DataSetReaderDataType, messageSettings) - sizeof(UA_ExtensionObject), /* .padding */
20073 false, /* .isArray */
20074 false /* .isOptional */
20075},};
20076
20077/* TargetVariablesDataType */
20078static UA_DataTypeMember TargetVariablesDataType_members[1] = {
20079{
20080 UA_TYPENAME("TargetVariables") /* .memberName */
20081 &UA_TYPES[UA_TYPES_FIELDTARGETDATATYPE], /* .memberType */
20082 0, /* .padding */
20083 true, /* .isArray */
20084 false /* .isOptional */
20085},};
20086
20087/* StandaloneSubscribedDataSetDataType */
20088static UA_DataTypeMember StandaloneSubscribedDataSetDataType_members[4] = {
20089{
20090 UA_TYPENAME("Name") /* .memberName */
20091 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
20092 0, /* .padding */
20093 false, /* .isArray */
20094 false /* .isOptional */
20095},
20096{
20097 UA_TYPENAME("DataSetFolder") /* .memberName */
20098 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
20099 offsetof(UA_StandaloneSubscribedDataSetDataType, dataSetFolderSize) - offsetof(UA_StandaloneSubscribedDataSetDataType, name) - sizeof(UA_String), /* .padding */
20100 true, /* .isArray */
20101 false /* .isOptional */
20102},
20103{
20104 UA_TYPENAME("DataSetMetaData") /* .memberName */
20105 &UA_TYPES[UA_TYPES_DATASETMETADATATYPE], /* .memberType */
20106 offsetof(UA_StandaloneSubscribedDataSetDataType, dataSetMetaData) - offsetof(UA_StandaloneSubscribedDataSetDataType, dataSetFolder) - sizeof(void *), /* .padding */
20107 false, /* .isArray */
20108 false /* .isOptional */
20109},
20110{
20111 UA_TYPENAME("SubscribedDataSet") /* .memberName */
20112 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
20113 offsetof(UA_StandaloneSubscribedDataSetDataType, subscribedDataSet) - offsetof(UA_StandaloneSubscribedDataSetDataType, dataSetMetaData) - sizeof(UA_DataSetMetaDataType), /* .padding */
20114 false, /* .isArray */
20115 false /* .isOptional */
20116},};
20117
20118/* DataTypeSchemaHeader */
20119static UA_DataTypeMember DataTypeSchemaHeader_members[4] = {
20120{
20121 UA_TYPENAME("Namespaces") /* .memberName */
20122 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
20123 0, /* .padding */
20124 true, /* .isArray */
20125 false /* .isOptional */
20126},
20127{
20128 UA_TYPENAME("StructureDataTypes") /* .memberName */
20129 &UA_TYPES[UA_TYPES_STRUCTUREDESCRIPTION], /* .memberType */
20130 offsetof(UA_DataTypeSchemaHeader, structureDataTypesSize) - offsetof(UA_DataTypeSchemaHeader, namespaces) - sizeof(void *), /* .padding */
20131 true, /* .isArray */
20132 false /* .isOptional */
20133},
20134{
20135 UA_TYPENAME("EnumDataTypes") /* .memberName */
20136 &UA_TYPES[UA_TYPES_ENUMDESCRIPTION], /* .memberType */
20137 offsetof(UA_DataTypeSchemaHeader, enumDataTypesSize) - offsetof(UA_DataTypeSchemaHeader, structureDataTypes) - sizeof(void *), /* .padding */
20138 true, /* .isArray */
20139 false /* .isOptional */
20140},
20141{
20142 UA_TYPENAME("SimpleDataTypes") /* .memberName */
20143 &UA_TYPES[UA_TYPES_SIMPLETYPEDESCRIPTION], /* .memberType */
20144 offsetof(UA_DataTypeSchemaHeader, simpleDataTypesSize) - offsetof(UA_DataTypeSchemaHeader, enumDataTypes) - sizeof(void *), /* .padding */
20145 true, /* .isArray */
20146 false /* .isOptional */
20147},};
20148
20149/* ReaderGroupDataType */
20150static UA_DataTypeMember ReaderGroupDataType_members[10] = {
20151{
20152 UA_TYPENAME("Name") /* .memberName */
20153 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
20154 0, /* .padding */
20155 false, /* .isArray */
20156 false /* .isOptional */
20157},
20158{
20159 UA_TYPENAME("Enabled") /* .memberName */
20160 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
20161 offsetof(UA_ReaderGroupDataType, enabled) - offsetof(UA_ReaderGroupDataType, name) - sizeof(UA_String), /* .padding */
20162 false, /* .isArray */
20163 false /* .isOptional */
20164},
20165{
20166 UA_TYPENAME("SecurityMode") /* .memberName */
20167 &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE], /* .memberType */
20168 offsetof(UA_ReaderGroupDataType, securityMode) - offsetof(UA_ReaderGroupDataType, enabled) - sizeof(UA_Boolean), /* .padding */
20169 false, /* .isArray */
20170 false /* .isOptional */
20171},
20172{
20173 UA_TYPENAME("SecurityGroupId") /* .memberName */
20174 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
20175 offsetof(UA_ReaderGroupDataType, securityGroupId) - offsetof(UA_ReaderGroupDataType, securityMode) - sizeof(UA_MessageSecurityMode), /* .padding */
20176 false, /* .isArray */
20177 false /* .isOptional */
20178},
20179{
20180 UA_TYPENAME("SecurityKeyServices") /* .memberName */
20181 &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION], /* .memberType */
20182 offsetof(UA_ReaderGroupDataType, securityKeyServicesSize) - offsetof(UA_ReaderGroupDataType, securityGroupId) - sizeof(UA_String), /* .padding */
20183 true, /* .isArray */
20184 false /* .isOptional */
20185},
20186{
20187 UA_TYPENAME("MaxNetworkMessageSize") /* .memberName */
20188 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
20189 offsetof(UA_ReaderGroupDataType, maxNetworkMessageSize) - offsetof(UA_ReaderGroupDataType, securityKeyServices) - sizeof(void *), /* .padding */
20190 false, /* .isArray */
20191 false /* .isOptional */
20192},
20193{
20194 UA_TYPENAME("GroupProperties") /* .memberName */
20195 &UA_TYPES[UA_TYPES_KEYVALUEPAIR], /* .memberType */
20196 offsetof(UA_ReaderGroupDataType, groupPropertiesSize) - offsetof(UA_ReaderGroupDataType, maxNetworkMessageSize) - sizeof(UA_UInt32), /* .padding */
20197 true, /* .isArray */
20198 false /* .isOptional */
20199},
20200{
20201 UA_TYPENAME("TransportSettings") /* .memberName */
20202 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
20203 offsetof(UA_ReaderGroupDataType, transportSettings) - offsetof(UA_ReaderGroupDataType, groupProperties) - sizeof(void *), /* .padding */
20204 false, /* .isArray */
20205 false /* .isOptional */
20206},
20207{
20208 UA_TYPENAME("MessageSettings") /* .memberName */
20209 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
20210 offsetof(UA_ReaderGroupDataType, messageSettings) - offsetof(UA_ReaderGroupDataType, transportSettings) - sizeof(UA_ExtensionObject), /* .padding */
20211 false, /* .isArray */
20212 false /* .isOptional */
20213},
20214{
20215 UA_TYPENAME("DataSetReaders") /* .memberName */
20216 &UA_TYPES[UA_TYPES_DATASETREADERDATATYPE], /* .memberType */
20217 offsetof(UA_ReaderGroupDataType, dataSetReadersSize) - offsetof(UA_ReaderGroupDataType, messageSettings) - sizeof(UA_ExtensionObject), /* .padding */
20218 true, /* .isArray */
20219 false /* .isOptional */
20220},};
20221
20222/* PubSubConnectionDataType */
20223static UA_DataTypeMember PubSubConnectionDataType_members[9] = {
20224{
20225 UA_TYPENAME("Name") /* .memberName */
20226 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
20227 0, /* .padding */
20228 false, /* .isArray */
20229 false /* .isOptional */
20230},
20231{
20232 UA_TYPENAME("Enabled") /* .memberName */
20233 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
20234 offsetof(UA_PubSubConnectionDataType, enabled) - offsetof(UA_PubSubConnectionDataType, name) - sizeof(UA_String), /* .padding */
20235 false, /* .isArray */
20236 false /* .isOptional */
20237},
20238{
20239 UA_TYPENAME("PublisherId") /* .memberName */
20240 &UA_TYPES[UA_TYPES_VARIANT], /* .memberType */
20241 offsetof(UA_PubSubConnectionDataType, publisherId) - offsetof(UA_PubSubConnectionDataType, enabled) - sizeof(UA_Boolean), /* .padding */
20242 false, /* .isArray */
20243 false /* .isOptional */
20244},
20245{
20246 UA_TYPENAME("TransportProfileUri") /* .memberName */
20247 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
20248 offsetof(UA_PubSubConnectionDataType, transportProfileUri) - offsetof(UA_PubSubConnectionDataType, publisherId) - sizeof(UA_Variant), /* .padding */
20249 false, /* .isArray */
20250 false /* .isOptional */
20251},
20252{
20253 UA_TYPENAME("Address") /* .memberName */
20254 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
20255 offsetof(UA_PubSubConnectionDataType, address) - offsetof(UA_PubSubConnectionDataType, transportProfileUri) - sizeof(UA_String), /* .padding */
20256 false, /* .isArray */
20257 false /* .isOptional */
20258},
20259{
20260 UA_TYPENAME("ConnectionProperties") /* .memberName */
20261 &UA_TYPES[UA_TYPES_KEYVALUEPAIR], /* .memberType */
20262 offsetof(UA_PubSubConnectionDataType, connectionPropertiesSize) - offsetof(UA_PubSubConnectionDataType, address) - sizeof(UA_ExtensionObject), /* .padding */
20263 true, /* .isArray */
20264 false /* .isOptional */
20265},
20266{
20267 UA_TYPENAME("TransportSettings") /* .memberName */
20268 &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], /* .memberType */
20269 offsetof(UA_PubSubConnectionDataType, transportSettings) - offsetof(UA_PubSubConnectionDataType, connectionProperties) - sizeof(void *), /* .padding */
20270 false, /* .isArray */
20271 false /* .isOptional */
20272},
20273{
20274 UA_TYPENAME("WriterGroups") /* .memberName */
20275 &UA_TYPES[UA_TYPES_WRITERGROUPDATATYPE], /* .memberType */
20276 offsetof(UA_PubSubConnectionDataType, writerGroupsSize) - offsetof(UA_PubSubConnectionDataType, transportSettings) - sizeof(UA_ExtensionObject), /* .padding */
20277 true, /* .isArray */
20278 false /* .isOptional */
20279},
20280{
20281 UA_TYPENAME("ReaderGroups") /* .memberName */
20282 &UA_TYPES[UA_TYPES_READERGROUPDATATYPE], /* .memberType */
20283 offsetof(UA_PubSubConnectionDataType, readerGroupsSize) - offsetof(UA_PubSubConnectionDataType, writerGroups) - sizeof(void *), /* .padding */
20284 true, /* .isArray */
20285 false /* .isOptional */
20286},};
20287
20288/* PubSubConfigurationDataType */
20289static UA_DataTypeMember PubSubConfigurationDataType_members[3] = {
20290{
20291 UA_TYPENAME("PublishedDataSets") /* .memberName */
20292 &UA_TYPES[UA_TYPES_PUBLISHEDDATASETDATATYPE], /* .memberType */
20293 0, /* .padding */
20294 true, /* .isArray */
20295 false /* .isOptional */
20296},
20297{
20298 UA_TYPENAME("Connections") /* .memberName */
20299 &UA_TYPES[UA_TYPES_PUBSUBCONNECTIONDATATYPE], /* .memberType */
20300 offsetof(UA_PubSubConfigurationDataType, connectionsSize) - offsetof(UA_PubSubConfigurationDataType, publishedDataSets) - sizeof(void *), /* .padding */
20301 true, /* .isArray */
20302 false /* .isOptional */
20303},
20304{
20305 UA_TYPENAME("Enabled") /* .memberName */
20306 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
20307 offsetof(UA_PubSubConfigurationDataType, enabled) - offsetof(UA_PubSubConfigurationDataType, connections) - sizeof(void *), /* .padding */
20308 false, /* .isArray */
20309 false /* .isOptional */
20310},};
20311
20312/* PubSubConfiguration2DataType */
20313static UA_DataTypeMember PubSubConfiguration2DataType_members[10] = {
20314{
20315 UA_TYPENAME("PublishedDataSets") /* .memberName */
20316 &UA_TYPES[UA_TYPES_PUBLISHEDDATASETDATATYPE], /* .memberType */
20317 0, /* .padding */
20318 true, /* .isArray */
20319 false /* .isOptional */
20320},
20321{
20322 UA_TYPENAME("Connections") /* .memberName */
20323 &UA_TYPES[UA_TYPES_PUBSUBCONNECTIONDATATYPE], /* .memberType */
20324 offsetof(UA_PubSubConfiguration2DataType, connectionsSize) - offsetof(UA_PubSubConfiguration2DataType, publishedDataSets) - sizeof(void *), /* .padding */
20325 true, /* .isArray */
20326 false /* .isOptional */
20327},
20328{
20329 UA_TYPENAME("Enabled") /* .memberName */
20330 &UA_TYPES[UA_TYPES_BOOLEAN], /* .memberType */
20331 offsetof(UA_PubSubConfiguration2DataType, enabled) - offsetof(UA_PubSubConfiguration2DataType, connections) - sizeof(void *), /* .padding */
20332 false, /* .isArray */
20333 false /* .isOptional */
20334},
20335{
20336 UA_TYPENAME("SubscribedDataSets") /* .memberName */
20337 &UA_TYPES[UA_TYPES_STANDALONESUBSCRIBEDDATASETDATATYPE], /* .memberType */
20338 offsetof(UA_PubSubConfiguration2DataType, subscribedDataSetsSize) - offsetof(UA_PubSubConfiguration2DataType, enabled) - sizeof(UA_Boolean), /* .padding */
20339 true, /* .isArray */
20340 false /* .isOptional */
20341},
20342{
20343 UA_TYPENAME("DataSetClasses") /* .memberName */
20344 &UA_TYPES[UA_TYPES_DATASETMETADATATYPE], /* .memberType */
20345 offsetof(UA_PubSubConfiguration2DataType, dataSetClassesSize) - offsetof(UA_PubSubConfiguration2DataType, subscribedDataSets) - sizeof(void *), /* .padding */
20346 true, /* .isArray */
20347 false /* .isOptional */
20348},
20349{
20350 UA_TYPENAME("DefaultSecurityKeyServices") /* .memberName */
20351 &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION], /* .memberType */
20352 offsetof(UA_PubSubConfiguration2DataType, defaultSecurityKeyServicesSize) - offsetof(UA_PubSubConfiguration2DataType, dataSetClasses) - sizeof(void *), /* .padding */
20353 true, /* .isArray */
20354 false /* .isOptional */
20355},
20356{
20357 UA_TYPENAME("SecurityGroups") /* .memberName */
20358 &UA_TYPES[UA_TYPES_SECURITYGROUPDATATYPE], /* .memberType */
20359 offsetof(UA_PubSubConfiguration2DataType, securityGroupsSize) - offsetof(UA_PubSubConfiguration2DataType, defaultSecurityKeyServices) - sizeof(void *), /* .padding */
20360 true, /* .isArray */
20361 false /* .isOptional */
20362},
20363{
20364 UA_TYPENAME("PubSubKeyPushTargets") /* .memberName */
20365 &UA_TYPES[UA_TYPES_PUBSUBKEYPUSHTARGETDATATYPE], /* .memberType */
20366 offsetof(UA_PubSubConfiguration2DataType, pubSubKeyPushTargetsSize) - offsetof(UA_PubSubConfiguration2DataType, securityGroups) - sizeof(void *), /* .padding */
20367 true, /* .isArray */
20368 false /* .isOptional */
20369},
20370{
20371 UA_TYPENAME("ConfigurationVersion") /* .memberName */
20372 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
20373 offsetof(UA_PubSubConfiguration2DataType, configurationVersion) - offsetof(UA_PubSubConfiguration2DataType, pubSubKeyPushTargets) - sizeof(void *), /* .padding */
20374 false, /* .isArray */
20375 false /* .isOptional */
20376},
20377{
20378 UA_TYPENAME("ConfigurationProperties") /* .memberName */
20379 &UA_TYPES[UA_TYPES_KEYVALUEPAIR], /* .memberType */
20380 offsetof(UA_PubSubConfiguration2DataType, configurationPropertiesSize) - offsetof(UA_PubSubConfiguration2DataType, configurationVersion) - sizeof(UA_UInt32), /* .padding */
20381 true, /* .isArray */
20382 false /* .isOptional */
20383},};
20384UA_DataType UA_TYPES[UA_TYPES_COUNT] = {
20385/* Boolean */
20386{
20387 UA_TYPENAME("Boolean") /* .typeName */
20388 {0, UA_NODEIDTYPE_NUMERIC, {1LU}}, /* .typeId */
20389 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20390 sizeof(UA_Boolean), /* .memSize */
20391 UA_DATATYPEKIND_BOOLEAN, /* .typeKind */
20392 true, /* .pointerFree */
20393 false, /* .overlayable */
20394 0, /* .membersSize */
20395 Boolean_members /* .members */
20396},
20397/* SByte */
20398{
20399 UA_TYPENAME("SByte") /* .typeName */
20400 {0, UA_NODEIDTYPE_NUMERIC, {2LU}}, /* .typeId */
20401 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20402 sizeof(UA_SByte), /* .memSize */
20403 UA_DATATYPEKIND_SBYTE, /* .typeKind */
20404 true, /* .pointerFree */
20405 true, /* .overlayable */
20406 0, /* .membersSize */
20407 SByte_members /* .members */
20408},
20409/* Byte */
20410{
20411 UA_TYPENAME("Byte") /* .typeName */
20412 {0, UA_NODEIDTYPE_NUMERIC, {3LU}}, /* .typeId */
20413 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20414 sizeof(UA_Byte), /* .memSize */
20415 UA_DATATYPEKIND_BYTE, /* .typeKind */
20416 true, /* .pointerFree */
20417 true, /* .overlayable */
20418 0, /* .membersSize */
20419 Byte_members /* .members */
20420},
20421/* Int16 */
20422{
20423 UA_TYPENAME("Int16") /* .typeName */
20424 {0, UA_NODEIDTYPE_NUMERIC, {4LU}}, /* .typeId */
20425 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20426 sizeof(UA_Int16), /* .memSize */
20427 UA_DATATYPEKIND_INT16, /* .typeKind */
20428 true, /* .pointerFree */
20429 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
20430 0, /* .membersSize */
20431 Int16_members /* .members */
20432},
20433/* UInt16 */
20434{
20435 UA_TYPENAME("UInt16") /* .typeName */
20436 {0, UA_NODEIDTYPE_NUMERIC, {5LU}}, /* .typeId */
20437 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20438 sizeof(UA_UInt16), /* .memSize */
20439 UA_DATATYPEKIND_UINT16, /* .typeKind */
20440 true, /* .pointerFree */
20441 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
20442 0, /* .membersSize */
20443 UInt16_members /* .members */
20444},
20445/* Int32 */
20446{
20447 UA_TYPENAME("Int32") /* .typeName */
20448 {0, UA_NODEIDTYPE_NUMERIC, {6LU}}, /* .typeId */
20449 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20450 sizeof(UA_Int32), /* .memSize */
20451 UA_DATATYPEKIND_INT32, /* .typeKind */
20452 true, /* .pointerFree */
20453 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
20454 0, /* .membersSize */
20455 Int32_members /* .members */
20456},
20457/* UInt32 */
20458{
20459 UA_TYPENAME("UInt32") /* .typeName */
20460 {0, UA_NODEIDTYPE_NUMERIC, {7LU}}, /* .typeId */
20461 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20462 sizeof(UA_UInt32), /* .memSize */
20463 UA_DATATYPEKIND_UINT32, /* .typeKind */
20464 true, /* .pointerFree */
20465 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
20466 0, /* .membersSize */
20467 UInt32_members /* .members */
20468},
20469/* Int64 */
20470{
20471 UA_TYPENAME("Int64") /* .typeName */
20472 {0, UA_NODEIDTYPE_NUMERIC, {8LU}}, /* .typeId */
20473 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20474 sizeof(UA_Int64), /* .memSize */
20475 UA_DATATYPEKIND_INT64, /* .typeKind */
20476 true, /* .pointerFree */
20477 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
20478 0, /* .membersSize */
20479 Int64_members /* .members */
20480},
20481/* UInt64 */
20482{
20483 UA_TYPENAME("UInt64") /* .typeName */
20484 {0, UA_NODEIDTYPE_NUMERIC, {9LU}}, /* .typeId */
20485 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20486 sizeof(UA_UInt64), /* .memSize */
20487 UA_DATATYPEKIND_UINT64, /* .typeKind */
20488 true, /* .pointerFree */
20489 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
20490 0, /* .membersSize */
20491 UInt64_members /* .members */
20492},
20493/* Float */
20494{
20495 UA_TYPENAME("Float") /* .typeName */
20496 {0, UA_NODEIDTYPE_NUMERIC, {10LU}}, /* .typeId */
20497 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20498 sizeof(UA_Float), /* .memSize */
20499 UA_DATATYPEKIND_FLOAT, /* .typeKind */
20500 true, /* .pointerFree */
20501 UA_BINARY_OVERLAYABLE_FLOAT, /* .overlayable */
20502 0, /* .membersSize */
20503 Float_members /* .members */
20504},
20505/* Double */
20506{
20507 UA_TYPENAME("Double") /* .typeName */
20508 {0, UA_NODEIDTYPE_NUMERIC, {11LU}}, /* .typeId */
20509 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20510 sizeof(UA_Double), /* .memSize */
20511 UA_DATATYPEKIND_DOUBLE, /* .typeKind */
20512 true, /* .pointerFree */
20513 UA_BINARY_OVERLAYABLE_FLOAT, /* .overlayable */
20514 0, /* .membersSize */
20515 Double_members /* .members */
20516},
20517/* String */
20518{
20519 UA_TYPENAME("String") /* .typeName */
20520 {0, UA_NODEIDTYPE_NUMERIC, {12LU}}, /* .typeId */
20521 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20522 sizeof(UA_String), /* .memSize */
20523 UA_DATATYPEKIND_STRING, /* .typeKind */
20524 false, /* .pointerFree */
20525 false, /* .overlayable */
20526 0, /* .membersSize */
20527 String_members /* .members */
20528},
20529/* DateTime */
20530{
20531 UA_TYPENAME("DateTime") /* .typeName */
20532 {0, UA_NODEIDTYPE_NUMERIC, {13LU}}, /* .typeId */
20533 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20534 sizeof(UA_DateTime), /* .memSize */
20535 UA_DATATYPEKIND_DATETIME, /* .typeKind */
20536 true, /* .pointerFree */
20537 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
20538 0, /* .membersSize */
20539 DateTime_members /* .members */
20540},
20541/* Guid */
20542{
20543 UA_TYPENAME("Guid") /* .typeName */
20544 {0, UA_NODEIDTYPE_NUMERIC, {14LU}}, /* .typeId */
20545 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20546 sizeof(UA_Guid), /* .memSize */
20547 UA_DATATYPEKIND_GUID, /* .typeKind */
20548 true, /* .pointerFree */
20549 (UA_BINARY_OVERLAYABLE_INTEGER && offsetof(UA_Guid, data2) == sizeof(UA_UInt32) && offsetof(UA_Guid, data3) == (sizeof(UA_UInt16) + sizeof(UA_UInt32)) && offsetof(UA_Guid, data4) == (2*sizeof(UA_UInt32))), /* .overlayable */
20550 0, /* .membersSize */
20551 Guid_members /* .members */
20552},
20553/* ByteString */
20554{
20555 UA_TYPENAME("ByteString") /* .typeName */
20556 {0, UA_NODEIDTYPE_NUMERIC, {15LU}}, /* .typeId */
20557 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20558 sizeof(UA_ByteString), /* .memSize */
20559 UA_DATATYPEKIND_BYTESTRING, /* .typeKind */
20560 false, /* .pointerFree */
20561 false, /* .overlayable */
20562 0, /* .membersSize */
20563 ByteString_members /* .members */
20564},
20565/* XmlElement */
20566{
20567 UA_TYPENAME("XmlElement") /* .typeName */
20568 {0, UA_NODEIDTYPE_NUMERIC, {16LU}}, /* .typeId */
20569 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20570 sizeof(UA_XmlElement), /* .memSize */
20571 UA_DATATYPEKIND_XMLELEMENT, /* .typeKind */
20572 false, /* .pointerFree */
20573 false, /* .overlayable */
20574 0, /* .membersSize */
20575 XmlElement_members /* .members */
20576},
20577/* NodeId */
20578{
20579 UA_TYPENAME("NodeId") /* .typeName */
20580 {0, UA_NODEIDTYPE_NUMERIC, {17LU}}, /* .typeId */
20581 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20582 sizeof(UA_NodeId), /* .memSize */
20583 UA_DATATYPEKIND_NODEID, /* .typeKind */
20584 false, /* .pointerFree */
20585 false, /* .overlayable */
20586 0, /* .membersSize */
20587 NodeId_members /* .members */
20588},
20589/* ExpandedNodeId */
20590{
20591 UA_TYPENAME("ExpandedNodeId") /* .typeName */
20592 {0, UA_NODEIDTYPE_NUMERIC, {18LU}}, /* .typeId */
20593 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20594 sizeof(UA_ExpandedNodeId), /* .memSize */
20595 UA_DATATYPEKIND_EXPANDEDNODEID, /* .typeKind */
20596 false, /* .pointerFree */
20597 false, /* .overlayable */
20598 0, /* .membersSize */
20599 ExpandedNodeId_members /* .members */
20600},
20601/* StatusCode */
20602{
20603 UA_TYPENAME("StatusCode") /* .typeName */
20604 {0, UA_NODEIDTYPE_NUMERIC, {19LU}}, /* .typeId */
20605 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20606 sizeof(UA_StatusCode), /* .memSize */
20607 UA_DATATYPEKIND_STATUSCODE, /* .typeKind */
20608 true, /* .pointerFree */
20609 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
20610 0, /* .membersSize */
20611 StatusCode_members /* .members */
20612},
20613/* QualifiedName */
20614{
20615 UA_TYPENAME("QualifiedName") /* .typeName */
20616 {0, UA_NODEIDTYPE_NUMERIC, {20LU}}, /* .typeId */
20617 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20618 sizeof(UA_QualifiedName), /* .memSize */
20619 UA_DATATYPEKIND_QUALIFIEDNAME, /* .typeKind */
20620 false, /* .pointerFree */
20621 false, /* .overlayable */
20622 0, /* .membersSize */
20623 QualifiedName_members /* .members */
20624},
20625/* LocalizedText */
20626{
20627 UA_TYPENAME("LocalizedText") /* .typeName */
20628 {0, UA_NODEIDTYPE_NUMERIC, {21LU}}, /* .typeId */
20629 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20630 sizeof(UA_LocalizedText), /* .memSize */
20631 UA_DATATYPEKIND_LOCALIZEDTEXT, /* .typeKind */
20632 false, /* .pointerFree */
20633 false, /* .overlayable */
20634 0, /* .membersSize */
20635 LocalizedText_members /* .members */
20636},
20637/* ExtensionObject */
20638{
20639 UA_TYPENAME("ExtensionObject") /* .typeName */
20640 {0, UA_NODEIDTYPE_NUMERIC, {22LU}}, /* .typeId */
20641 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20642 sizeof(UA_ExtensionObject), /* .memSize */
20643 UA_DATATYPEKIND_EXTENSIONOBJECT, /* .typeKind */
20644 false, /* .pointerFree */
20645 false, /* .overlayable */
20646 0, /* .membersSize */
20647 ExtensionObject_members /* .members */
20648},
20649/* DataValue */
20650{
20651 UA_TYPENAME("DataValue") /* .typeName */
20652 {0, UA_NODEIDTYPE_NUMERIC, {23LU}}, /* .typeId */
20653 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20654 sizeof(UA_DataValue), /* .memSize */
20655 UA_DATATYPEKIND_DATAVALUE, /* .typeKind */
20656 false, /* .pointerFree */
20657 false, /* .overlayable */
20658 0, /* .membersSize */
20659 DataValue_members /* .members */
20660},
20661/* Variant */
20662{
20663 UA_TYPENAME("Variant") /* .typeName */
20664 {0, UA_NODEIDTYPE_NUMERIC, {24LU}}, /* .typeId */
20665 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20666 sizeof(UA_Variant), /* .memSize */
20667 UA_DATATYPEKIND_VARIANT, /* .typeKind */
20668 false, /* .pointerFree */
20669 false, /* .overlayable */
20670 0, /* .membersSize */
20671 Variant_members /* .members */
20672},
20673/* DiagnosticInfo */
20674{
20675 UA_TYPENAME("DiagnosticInfo") /* .typeName */
20676 {0, UA_NODEIDTYPE_NUMERIC, {25LU}}, /* .typeId */
20677 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20678 sizeof(UA_DiagnosticInfo), /* .memSize */
20679 UA_DATATYPEKIND_DIAGNOSTICINFO, /* .typeKind */
20680 false, /* .pointerFree */
20681 false, /* .overlayable */
20682 0, /* .membersSize */
20683 DiagnosticInfo_members /* .members */
20684},
20685/* NamingRuleType */
20686{
20687 UA_TYPENAME("NamingRuleType") /* .typeName */
20688 {0, UA_NODEIDTYPE_NUMERIC, {120LU}}, /* .typeId */
20689 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20690 sizeof(UA_NamingRuleType), /* .memSize */
20691 UA_DATATYPEKIND_ENUM, /* .typeKind */
20692 true, /* .pointerFree */
20693 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
20694 0, /* .membersSize */
20695 NamingRuleType_members /* .members */
20696},
20697/* Enumeration */
20698{
20699 UA_TYPENAME("Enumeration") /* .typeName */
20700 {0, UA_NODEIDTYPE_NUMERIC, {29LU}}, /* .typeId */
20701 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20702 sizeof(UA_Enumeration), /* .memSize */
20703 UA_DATATYPEKIND_ENUM, /* .typeKind */
20704 true, /* .pointerFree */
20705 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
20706 0, /* .membersSize */
20707 Enumeration_members /* .members */
20708},
20709/* ImageBMP */
20710{
20711 UA_TYPENAME("ImageBMP") /* .typeName */
20712 {0, UA_NODEIDTYPE_NUMERIC, {2000LU}}, /* .typeId */
20713 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20714 sizeof(UA_ImageBMP), /* .memSize */
20715 UA_DATATYPEKIND_BYTESTRING, /* .typeKind */
20716 false, /* .pointerFree */
20717 false, /* .overlayable */
20718 0, /* .membersSize */
20719 ImageBMP_members /* .members */
20720},
20721/* ImageGIF */
20722{
20723 UA_TYPENAME("ImageGIF") /* .typeName */
20724 {0, UA_NODEIDTYPE_NUMERIC, {2001LU}}, /* .typeId */
20725 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20726 sizeof(UA_ImageGIF), /* .memSize */
20727 UA_DATATYPEKIND_BYTESTRING, /* .typeKind */
20728 false, /* .pointerFree */
20729 false, /* .overlayable */
20730 0, /* .membersSize */
20731 ImageGIF_members /* .members */
20732},
20733/* ImageJPG */
20734{
20735 UA_TYPENAME("ImageJPG") /* .typeName */
20736 {0, UA_NODEIDTYPE_NUMERIC, {2002LU}}, /* .typeId */
20737 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20738 sizeof(UA_ImageJPG), /* .memSize */
20739 UA_DATATYPEKIND_BYTESTRING, /* .typeKind */
20740 false, /* .pointerFree */
20741 false, /* .overlayable */
20742 0, /* .membersSize */
20743 ImageJPG_members /* .members */
20744},
20745/* ImagePNG */
20746{
20747 UA_TYPENAME("ImagePNG") /* .typeName */
20748 {0, UA_NODEIDTYPE_NUMERIC, {2003LU}}, /* .typeId */
20749 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20750 sizeof(UA_ImagePNG), /* .memSize */
20751 UA_DATATYPEKIND_BYTESTRING, /* .typeKind */
20752 false, /* .pointerFree */
20753 false, /* .overlayable */
20754 0, /* .membersSize */
20755 ImagePNG_members /* .members */
20756},
20757/* AudioDataType */
20758{
20759 UA_TYPENAME("AudioDataType") /* .typeName */
20760 {0, UA_NODEIDTYPE_NUMERIC, {16307LU}}, /* .typeId */
20761 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20762 sizeof(UA_AudioDataType), /* .memSize */
20763 UA_DATATYPEKIND_BYTESTRING, /* .typeKind */
20764 false, /* .pointerFree */
20765 false, /* .overlayable */
20766 0, /* .membersSize */
20767 AudioDataType_members /* .members */
20768},
20769/* UriString */
20770{
20771 UA_TYPENAME("UriString") /* .typeName */
20772 {0, UA_NODEIDTYPE_NUMERIC, {23751LU}}, /* .typeId */
20773 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20774 sizeof(UA_UriString), /* .memSize */
20775 UA_DATATYPEKIND_STRING, /* .typeKind */
20776 false, /* .pointerFree */
20777 false, /* .overlayable */
20778 0, /* .membersSize */
20779 UriString_members /* .members */
20780},
20781/* BitFieldMaskDataType */
20782{
20783 UA_TYPENAME("BitFieldMaskDataType") /* .typeName */
20784 {0, UA_NODEIDTYPE_NUMERIC, {11737LU}}, /* .typeId */
20785 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20786 sizeof(UA_BitFieldMaskDataType), /* .memSize */
20787 UA_DATATYPEKIND_UINT64, /* .typeKind */
20788 false, /* .pointerFree */
20789 false, /* .overlayable */
20790 0, /* .membersSize */
20791 BitFieldMaskDataType_members /* .members */
20792},
20793/* SemanticVersionString */
20794{
20795 UA_TYPENAME("SemanticVersionString") /* .typeName */
20796 {0, UA_NODEIDTYPE_NUMERIC, {24263LU}}, /* .typeId */
20797 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20798 sizeof(UA_SemanticVersionString), /* .memSize */
20799 UA_DATATYPEKIND_STRING, /* .typeKind */
20800 false, /* .pointerFree */
20801 false, /* .overlayable */
20802 0, /* .membersSize */
20803 SemanticVersionString_members /* .members */
20804},
20805/* KeyValuePair */
20806{
20807 UA_TYPENAME("KeyValuePair") /* .typeName */
20808 {0, UA_NODEIDTYPE_NUMERIC, {14533LU}}, /* .typeId */
20809 {0, UA_NODEIDTYPE_NUMERIC, {14846LU}}, /* .binaryEncodingId */
20810 sizeof(UA_KeyValuePair), /* .memSize */
20811 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
20812 false, /* .pointerFree */
20813 false, /* .overlayable */
20814 2, /* .membersSize */
20815 KeyValuePair_members /* .members */
20816},
20817/* AdditionalParametersType */
20818{
20819 UA_TYPENAME("AdditionalParametersType") /* .typeName */
20820 {0, UA_NODEIDTYPE_NUMERIC, {16313LU}}, /* .typeId */
20821 {0, UA_NODEIDTYPE_NUMERIC, {17537LU}}, /* .binaryEncodingId */
20822 sizeof(UA_AdditionalParametersType), /* .memSize */
20823 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
20824 false, /* .pointerFree */
20825 false, /* .overlayable */
20826 1, /* .membersSize */
20827 AdditionalParametersType_members /* .members */
20828},
20829/* EphemeralKeyType */
20830{
20831 UA_TYPENAME("EphemeralKeyType") /* .typeName */
20832 {0, UA_NODEIDTYPE_NUMERIC, {17548LU}}, /* .typeId */
20833 {0, UA_NODEIDTYPE_NUMERIC, {17549LU}}, /* .binaryEncodingId */
20834 sizeof(UA_EphemeralKeyType), /* .memSize */
20835 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
20836 false, /* .pointerFree */
20837 false, /* .overlayable */
20838 2, /* .membersSize */
20839 EphemeralKeyType_members /* .members */
20840},
20841/* RationalNumber */
20842{
20843 UA_TYPENAME("RationalNumber") /* .typeName */
20844 {0, UA_NODEIDTYPE_NUMERIC, {18806LU}}, /* .typeId */
20845 {0, UA_NODEIDTYPE_NUMERIC, {18815LU}}, /* .binaryEncodingId */
20846 sizeof(UA_RationalNumber), /* .memSize */
20847 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
20848 true, /* .pointerFree */
20849 false, /* .overlayable */
20850 2, /* .membersSize */
20851 RationalNumber_members /* .members */
20852},
20853/* ThreeDVector */
20854{
20855 UA_TYPENAME("ThreeDVector") /* .typeName */
20856 {0, UA_NODEIDTYPE_NUMERIC, {18808LU}}, /* .typeId */
20857 {0, UA_NODEIDTYPE_NUMERIC, {18817LU}}, /* .binaryEncodingId */
20858 sizeof(UA_ThreeDVector), /* .memSize */
20859 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
20860 true, /* .pointerFree */
20861 false, /* .overlayable */
20862 3, /* .membersSize */
20863 ThreeDVector_members /* .members */
20864},
20865/* ThreeDCartesianCoordinates */
20866{
20867 UA_TYPENAME("ThreeDCartesianCoordinates") /* .typeName */
20868 {0, UA_NODEIDTYPE_NUMERIC, {18810LU}}, /* .typeId */
20869 {0, UA_NODEIDTYPE_NUMERIC, {18819LU}}, /* .binaryEncodingId */
20870 sizeof(UA_ThreeDCartesianCoordinates), /* .memSize */
20871 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
20872 true, /* .pointerFree */
20873 false, /* .overlayable */
20874 3, /* .membersSize */
20875 ThreeDCartesianCoordinates_members /* .members */
20876},
20877/* ThreeDOrientation */
20878{
20879 UA_TYPENAME("ThreeDOrientation") /* .typeName */
20880 {0, UA_NODEIDTYPE_NUMERIC, {18812LU}}, /* .typeId */
20881 {0, UA_NODEIDTYPE_NUMERIC, {18821LU}}, /* .binaryEncodingId */
20882 sizeof(UA_ThreeDOrientation), /* .memSize */
20883 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
20884 true, /* .pointerFree */
20885 false, /* .overlayable */
20886 3, /* .membersSize */
20887 ThreeDOrientation_members /* .members */
20888},
20889/* ThreeDFrame */
20890{
20891 UA_TYPENAME("ThreeDFrame") /* .typeName */
20892 {0, UA_NODEIDTYPE_NUMERIC, {18814LU}}, /* .typeId */
20893 {0, UA_NODEIDTYPE_NUMERIC, {18823LU}}, /* .binaryEncodingId */
20894 sizeof(UA_ThreeDFrame), /* .memSize */
20895 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
20896 true, /* .pointerFree */
20897 false, /* .overlayable */
20898 2, /* .membersSize */
20899 ThreeDFrame_members /* .members */
20900},
20901/* OpenFileMode */
20902{
20903 UA_TYPENAME("OpenFileMode") /* .typeName */
20904 {0, UA_NODEIDTYPE_NUMERIC, {11939LU}}, /* .typeId */
20905 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20906 sizeof(UA_OpenFileMode), /* .memSize */
20907 UA_DATATYPEKIND_ENUM, /* .typeKind */
20908 true, /* .pointerFree */
20909 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
20910 0, /* .membersSize */
20911 OpenFileMode_members /* .members */
20912},
20913/* IdentityCriteriaType */
20914{
20915 UA_TYPENAME("IdentityCriteriaType") /* .typeName */
20916 {0, UA_NODEIDTYPE_NUMERIC, {15632LU}}, /* .typeId */
20917 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20918 sizeof(UA_IdentityCriteriaType), /* .memSize */
20919 UA_DATATYPEKIND_ENUM, /* .typeKind */
20920 true, /* .pointerFree */
20921 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
20922 0, /* .membersSize */
20923 IdentityCriteriaType_members /* .members */
20924},
20925/* IdentityMappingRuleType */
20926{
20927 UA_TYPENAME("IdentityMappingRuleType") /* .typeName */
20928 {0, UA_NODEIDTYPE_NUMERIC, {15634LU}}, /* .typeId */
20929 {0, UA_NODEIDTYPE_NUMERIC, {15736LU}}, /* .binaryEncodingId */
20930 sizeof(UA_IdentityMappingRuleType), /* .memSize */
20931 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
20932 false, /* .pointerFree */
20933 false, /* .overlayable */
20934 2, /* .membersSize */
20935 IdentityMappingRuleType_members /* .members */
20936},
20937/* CurrencyUnitType */
20938{
20939 UA_TYPENAME("CurrencyUnitType") /* .typeName */
20940 {0, UA_NODEIDTYPE_NUMERIC, {23498LU}}, /* .typeId */
20941 {0, UA_NODEIDTYPE_NUMERIC, {23507LU}}, /* .binaryEncodingId */
20942 sizeof(UA_CurrencyUnitType), /* .memSize */
20943 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
20944 false, /* .pointerFree */
20945 false, /* .overlayable */
20946 4, /* .membersSize */
20947 CurrencyUnitType_members /* .members */
20948},
20949/* TrustListMasks */
20950{
20951 UA_TYPENAME("TrustListMasks") /* .typeName */
20952 {0, UA_NODEIDTYPE_NUMERIC, {12552LU}}, /* .typeId */
20953 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
20954 sizeof(UA_TrustListMasks), /* .memSize */
20955 UA_DATATYPEKIND_ENUM, /* .typeKind */
20956 true, /* .pointerFree */
20957 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
20958 0, /* .membersSize */
20959 TrustListMasks_members /* .members */
20960},
20961/* TrustListDataType */
20962{
20963 UA_TYPENAME("TrustListDataType") /* .typeName */
20964 {0, UA_NODEIDTYPE_NUMERIC, {12554LU}}, /* .typeId */
20965 {0, UA_NODEIDTYPE_NUMERIC, {12680LU}}, /* .binaryEncodingId */
20966 sizeof(UA_TrustListDataType), /* .memSize */
20967 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
20968 false, /* .pointerFree */
20969 false, /* .overlayable */
20970 5, /* .membersSize */
20971 TrustListDataType_members /* .members */
20972},
20973/* DecimalDataType */
20974{
20975 UA_TYPENAME("DecimalDataType") /* .typeName */
20976 {0, UA_NODEIDTYPE_NUMERIC, {17861LU}}, /* .typeId */
20977 {0, UA_NODEIDTYPE_NUMERIC, {17863LU}}, /* .binaryEncodingId */
20978 sizeof(UA_DecimalDataType), /* .memSize */
20979 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
20980 false, /* .pointerFree */
20981 false, /* .overlayable */
20982 2, /* .membersSize */
20983 DecimalDataType_members /* .members */
20984},
20985/* DataTypeDescription */
20986{
20987 UA_TYPENAME("DataTypeDescription") /* .typeName */
20988 {0, UA_NODEIDTYPE_NUMERIC, {14525LU}}, /* .typeId */
20989 {0, UA_NODEIDTYPE_NUMERIC, {125LU}}, /* .binaryEncodingId */
20990 sizeof(UA_DataTypeDescription), /* .memSize */
20991 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
20992 false, /* .pointerFree */
20993 false, /* .overlayable */
20994 2, /* .membersSize */
20995 DataTypeDescription_members /* .members */
20996},
20997/* SimpleTypeDescription */
20998{
20999 UA_TYPENAME("SimpleTypeDescription") /* .typeName */
21000 {0, UA_NODEIDTYPE_NUMERIC, {15005LU}}, /* .typeId */
21001 {0, UA_NODEIDTYPE_NUMERIC, {15421LU}}, /* .binaryEncodingId */
21002 sizeof(UA_SimpleTypeDescription), /* .memSize */
21003 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21004 false, /* .pointerFree */
21005 false, /* .overlayable */
21006 4, /* .membersSize */
21007 SimpleTypeDescription_members /* .members */
21008},
21009/* PortableQualifiedName */
21010{
21011 UA_TYPENAME("PortableQualifiedName") /* .typeName */
21012 {0, UA_NODEIDTYPE_NUMERIC, {24105LU}}, /* .typeId */
21013 {0, UA_NODEIDTYPE_NUMERIC, {24108LU}}, /* .binaryEncodingId */
21014 sizeof(UA_PortableQualifiedName), /* .memSize */
21015 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21016 false, /* .pointerFree */
21017 false, /* .overlayable */
21018 2, /* .membersSize */
21019 PortableQualifiedName_members /* .members */
21020},
21021/* PortableNodeId */
21022{
21023 UA_TYPENAME("PortableNodeId") /* .typeName */
21024 {0, UA_NODEIDTYPE_NUMERIC, {24106LU}}, /* .typeId */
21025 {0, UA_NODEIDTYPE_NUMERIC, {24109LU}}, /* .binaryEncodingId */
21026 sizeof(UA_PortableNodeId), /* .memSize */
21027 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21028 false, /* .pointerFree */
21029 false, /* .overlayable */
21030 2, /* .membersSize */
21031 PortableNodeId_members /* .members */
21032},
21033/* UnsignedRationalNumber */
21034{
21035 UA_TYPENAME("UnsignedRationalNumber") /* .typeName */
21036 {0, UA_NODEIDTYPE_NUMERIC, {24107LU}}, /* .typeId */
21037 {0, UA_NODEIDTYPE_NUMERIC, {24110LU}}, /* .binaryEncodingId */
21038 sizeof(UA_UnsignedRationalNumber), /* .memSize */
21039 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21040 true, /* .pointerFree */
21041 false, /* .overlayable */
21042 2, /* .membersSize */
21043 UnsignedRationalNumber_members /* .members */
21044},
21045/* PubSubState */
21046{
21047 UA_TYPENAME("PubSubState") /* .typeName */
21048 {0, UA_NODEIDTYPE_NUMERIC, {14647LU}}, /* .typeId */
21049 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21050 sizeof(UA_PubSubState), /* .memSize */
21051 UA_DATATYPEKIND_ENUM, /* .typeKind */
21052 true, /* .pointerFree */
21053 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21054 0, /* .membersSize */
21055 PubSubState_members /* .members */
21056},
21057/* DataSetFieldFlags */
21058{
21059 UA_TYPENAME("DataSetFieldFlags") /* .typeName */
21060 {0, UA_NODEIDTYPE_NUMERIC, {15904LU}}, /* .typeId */
21061 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21062 sizeof(UA_DataSetFieldFlags), /* .memSize */
21063 UA_DATATYPEKIND_UINT16, /* .typeKind */
21064 true, /* .pointerFree */
21065 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21066 0, /* .membersSize */
21067 DataSetFieldFlags_members /* .members */
21068},
21069/* ConfigurationVersionDataType */
21070{
21071 UA_TYPENAME("ConfigurationVersionDataType") /* .typeName */
21072 {0, UA_NODEIDTYPE_NUMERIC, {14593LU}}, /* .typeId */
21073 {0, UA_NODEIDTYPE_NUMERIC, {14847LU}}, /* .binaryEncodingId */
21074 sizeof(UA_ConfigurationVersionDataType), /* .memSize */
21075 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21076 true, /* .pointerFree */
21077 false, /* .overlayable */
21078 2, /* .membersSize */
21079 ConfigurationVersionDataType_members /* .members */
21080},
21081/* PublishedVariableDataType */
21082{
21083 UA_TYPENAME("PublishedVariableDataType") /* .typeName */
21084 {0, UA_NODEIDTYPE_NUMERIC, {14273LU}}, /* .typeId */
21085 {0, UA_NODEIDTYPE_NUMERIC, {14323LU}}, /* .binaryEncodingId */
21086 sizeof(UA_PublishedVariableDataType), /* .memSize */
21087 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21088 false, /* .pointerFree */
21089 false, /* .overlayable */
21090 8, /* .membersSize */
21091 PublishedVariableDataType_members /* .members */
21092},
21093/* PublishedDataItemsDataType */
21094{
21095 UA_TYPENAME("PublishedDataItemsDataType") /* .typeName */
21096 {0, UA_NODEIDTYPE_NUMERIC, {15581LU}}, /* .typeId */
21097 {0, UA_NODEIDTYPE_NUMERIC, {15679LU}}, /* .binaryEncodingId */
21098 sizeof(UA_PublishedDataItemsDataType), /* .memSize */
21099 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21100 false, /* .pointerFree */
21101 false, /* .overlayable */
21102 1, /* .membersSize */
21103 PublishedDataItemsDataType_members /* .members */
21104},
21105/* PublishedDataSetCustomSourceDataType */
21106{
21107 UA_TYPENAME("PublishedDataSetCustomSourceDataType") /* .typeName */
21108 {0, UA_NODEIDTYPE_NUMERIC, {25269LU}}, /* .typeId */
21109 {0, UA_NODEIDTYPE_NUMERIC, {25529LU}}, /* .binaryEncodingId */
21110 sizeof(UA_PublishedDataSetCustomSourceDataType), /* .memSize */
21111 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21112 true, /* .pointerFree */
21113 false, /* .overlayable */
21114 1, /* .membersSize */
21115 PublishedDataSetCustomSourceDataType_members /* .members */
21116},
21117/* DataSetFieldContentMask */
21118{
21119 UA_TYPENAME("DataSetFieldContentMask") /* .typeName */
21120 {0, UA_NODEIDTYPE_NUMERIC, {15583LU}}, /* .typeId */
21121 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21122 sizeof(UA_DataSetFieldContentMask), /* .memSize */
21123 UA_DATATYPEKIND_UINT32, /* .typeKind */
21124 true, /* .pointerFree */
21125 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21126 0, /* .membersSize */
21127 DataSetFieldContentMask_members /* .members */
21128},
21129/* DataSetWriterDataType */
21130{
21131 UA_TYPENAME("DataSetWriterDataType") /* .typeName */
21132 {0, UA_NODEIDTYPE_NUMERIC, {15597LU}}, /* .typeId */
21133 {0, UA_NODEIDTYPE_NUMERIC, {15682LU}}, /* .binaryEncodingId */
21134 sizeof(UA_DataSetWriterDataType), /* .memSize */
21135 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21136 false, /* .pointerFree */
21137 false, /* .overlayable */
21138 9, /* .membersSize */
21139 DataSetWriterDataType_members /* .members */
21140},
21141/* NetworkAddressDataType */
21142{
21143 UA_TYPENAME("NetworkAddressDataType") /* .typeName */
21144 {0, UA_NODEIDTYPE_NUMERIC, {15502LU}}, /* .typeId */
21145 {0, UA_NODEIDTYPE_NUMERIC, {21151LU}}, /* .binaryEncodingId */
21146 sizeof(UA_NetworkAddressDataType), /* .memSize */
21147 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21148 false, /* .pointerFree */
21149 false, /* .overlayable */
21150 1, /* .membersSize */
21151 NetworkAddressDataType_members /* .members */
21152},
21153/* NetworkAddressUrlDataType */
21154{
21155 UA_TYPENAME("NetworkAddressUrlDataType") /* .typeName */
21156 {0, UA_NODEIDTYPE_NUMERIC, {15510LU}}, /* .typeId */
21157 {0, UA_NODEIDTYPE_NUMERIC, {21152LU}}, /* .binaryEncodingId */
21158 sizeof(UA_NetworkAddressUrlDataType), /* .memSize */
21159 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21160 false, /* .pointerFree */
21161 false, /* .overlayable */
21162 2, /* .membersSize */
21163 NetworkAddressUrlDataType_members /* .members */
21164},
21165/* OverrideValueHandling */
21166{
21167 UA_TYPENAME("OverrideValueHandling") /* .typeName */
21168 {0, UA_NODEIDTYPE_NUMERIC, {15874LU}}, /* .typeId */
21169 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21170 sizeof(UA_OverrideValueHandling), /* .memSize */
21171 UA_DATATYPEKIND_ENUM, /* .typeKind */
21172 true, /* .pointerFree */
21173 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21174 0, /* .membersSize */
21175 OverrideValueHandling_members /* .members */
21176},
21177/* StandaloneSubscribedDataSetRefDataType */
21178{
21179 UA_TYPENAME("StandaloneSubscribedDataSetRefDataType") /* .typeName */
21180 {0, UA_NODEIDTYPE_NUMERIC, {23599LU}}, /* .typeId */
21181 {0, UA_NODEIDTYPE_NUMERIC, {23851LU}}, /* .binaryEncodingId */
21182 sizeof(UA_StandaloneSubscribedDataSetRefDataType), /* .memSize */
21183 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21184 false, /* .pointerFree */
21185 false, /* .overlayable */
21186 1, /* .membersSize */
21187 StandaloneSubscribedDataSetRefDataType_members /* .members */
21188},
21189/* DataSetOrderingType */
21190{
21191 UA_TYPENAME("DataSetOrderingType") /* .typeName */
21192 {0, UA_NODEIDTYPE_NUMERIC, {20408LU}}, /* .typeId */
21193 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21194 sizeof(UA_DataSetOrderingType), /* .memSize */
21195 UA_DATATYPEKIND_ENUM, /* .typeKind */
21196 true, /* .pointerFree */
21197 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21198 0, /* .membersSize */
21199 DataSetOrderingType_members /* .members */
21200},
21201/* UadpNetworkMessageContentMask */
21202{
21203 UA_TYPENAME("UadpNetworkMessageContentMask") /* .typeName */
21204 {0, UA_NODEIDTYPE_NUMERIC, {15642LU}}, /* .typeId */
21205 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21206 sizeof(UA_UadpNetworkMessageContentMask), /* .memSize */
21207 UA_DATATYPEKIND_UINT32, /* .typeKind */
21208 true, /* .pointerFree */
21209 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21210 0, /* .membersSize */
21211 UadpNetworkMessageContentMask_members /* .members */
21212},
21213/* UadpWriterGroupMessageDataType */
21214{
21215 UA_TYPENAME("UadpWriterGroupMessageDataType") /* .typeName */
21216 {0, UA_NODEIDTYPE_NUMERIC, {15645LU}}, /* .typeId */
21217 {0, UA_NODEIDTYPE_NUMERIC, {15715LU}}, /* .binaryEncodingId */
21218 sizeof(UA_UadpWriterGroupMessageDataType), /* .memSize */
21219 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21220 false, /* .pointerFree */
21221 false, /* .overlayable */
21222 5, /* .membersSize */
21223 UadpWriterGroupMessageDataType_members /* .members */
21224},
21225/* UadpDataSetMessageContentMask */
21226{
21227 UA_TYPENAME("UadpDataSetMessageContentMask") /* .typeName */
21228 {0, UA_NODEIDTYPE_NUMERIC, {15646LU}}, /* .typeId */
21229 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21230 sizeof(UA_UadpDataSetMessageContentMask), /* .memSize */
21231 UA_DATATYPEKIND_UINT32, /* .typeKind */
21232 true, /* .pointerFree */
21233 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21234 0, /* .membersSize */
21235 UadpDataSetMessageContentMask_members /* .members */
21236},
21237/* UadpDataSetWriterMessageDataType */
21238{
21239 UA_TYPENAME("UadpDataSetWriterMessageDataType") /* .typeName */
21240 {0, UA_NODEIDTYPE_NUMERIC, {15652LU}}, /* .typeId */
21241 {0, UA_NODEIDTYPE_NUMERIC, {15717LU}}, /* .binaryEncodingId */
21242 sizeof(UA_UadpDataSetWriterMessageDataType), /* .memSize */
21243 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21244 true, /* .pointerFree */
21245 false, /* .overlayable */
21246 4, /* .membersSize */
21247 UadpDataSetWriterMessageDataType_members /* .members */
21248},
21249/* UadpDataSetReaderMessageDataType */
21250{
21251 UA_TYPENAME("UadpDataSetReaderMessageDataType") /* .typeName */
21252 {0, UA_NODEIDTYPE_NUMERIC, {15653LU}}, /* .typeId */
21253 {0, UA_NODEIDTYPE_NUMERIC, {15718LU}}, /* .binaryEncodingId */
21254 sizeof(UA_UadpDataSetReaderMessageDataType), /* .memSize */
21255 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21256 true, /* .pointerFree */
21257 false, /* .overlayable */
21258 9, /* .membersSize */
21259 UadpDataSetReaderMessageDataType_members /* .members */
21260},
21261/* JsonNetworkMessageContentMask */
21262{
21263 UA_TYPENAME("JsonNetworkMessageContentMask") /* .typeName */
21264 {0, UA_NODEIDTYPE_NUMERIC, {15654LU}}, /* .typeId */
21265 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21266 sizeof(UA_JsonNetworkMessageContentMask), /* .memSize */
21267 UA_DATATYPEKIND_UINT32, /* .typeKind */
21268 true, /* .pointerFree */
21269 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21270 0, /* .membersSize */
21271 JsonNetworkMessageContentMask_members /* .members */
21272},
21273/* JsonWriterGroupMessageDataType */
21274{
21275 UA_TYPENAME("JsonWriterGroupMessageDataType") /* .typeName */
21276 {0, UA_NODEIDTYPE_NUMERIC, {15657LU}}, /* .typeId */
21277 {0, UA_NODEIDTYPE_NUMERIC, {15719LU}}, /* .binaryEncodingId */
21278 sizeof(UA_JsonWriterGroupMessageDataType), /* .memSize */
21279 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21280 true, /* .pointerFree */
21281 false, /* .overlayable */
21282 1, /* .membersSize */
21283 JsonWriterGroupMessageDataType_members /* .members */
21284},
21285/* JsonDataSetMessageContentMask */
21286{
21287 UA_TYPENAME("JsonDataSetMessageContentMask") /* .typeName */
21288 {0, UA_NODEIDTYPE_NUMERIC, {15658LU}}, /* .typeId */
21289 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21290 sizeof(UA_JsonDataSetMessageContentMask), /* .memSize */
21291 UA_DATATYPEKIND_UINT32, /* .typeKind */
21292 true, /* .pointerFree */
21293 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21294 0, /* .membersSize */
21295 JsonDataSetMessageContentMask_members /* .members */
21296},
21297/* JsonDataSetWriterMessageDataType */
21298{
21299 UA_TYPENAME("JsonDataSetWriterMessageDataType") /* .typeName */
21300 {0, UA_NODEIDTYPE_NUMERIC, {15664LU}}, /* .typeId */
21301 {0, UA_NODEIDTYPE_NUMERIC, {15724LU}}, /* .binaryEncodingId */
21302 sizeof(UA_JsonDataSetWriterMessageDataType), /* .memSize */
21303 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21304 true, /* .pointerFree */
21305 false, /* .overlayable */
21306 1, /* .membersSize */
21307 JsonDataSetWriterMessageDataType_members /* .members */
21308},
21309/* JsonDataSetReaderMessageDataType */
21310{
21311 UA_TYPENAME("JsonDataSetReaderMessageDataType") /* .typeName */
21312 {0, UA_NODEIDTYPE_NUMERIC, {15665LU}}, /* .typeId */
21313 {0, UA_NODEIDTYPE_NUMERIC, {15725LU}}, /* .binaryEncodingId */
21314 sizeof(UA_JsonDataSetReaderMessageDataType), /* .memSize */
21315 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21316 true, /* .pointerFree */
21317 false, /* .overlayable */
21318 2, /* .membersSize */
21319 JsonDataSetReaderMessageDataType_members /* .members */
21320},
21321/* TransmitQosPriorityDataType */
21322{
21323 UA_TYPENAME("TransmitQosPriorityDataType") /* .typeName */
21324 {0, UA_NODEIDTYPE_NUMERIC, {23605LU}}, /* .typeId */
21325 {0, UA_NODEIDTYPE_NUMERIC, {23857LU}}, /* .binaryEncodingId */
21326 sizeof(UA_TransmitQosPriorityDataType), /* .memSize */
21327 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21328 false, /* .pointerFree */
21329 false, /* .overlayable */
21330 1, /* .membersSize */
21331 TransmitQosPriorityDataType_members /* .members */
21332},
21333/* ReceiveQosPriorityDataType */
21334{
21335 UA_TYPENAME("ReceiveQosPriorityDataType") /* .typeName */
21336 {0, UA_NODEIDTYPE_NUMERIC, {23609LU}}, /* .typeId */
21337 {0, UA_NODEIDTYPE_NUMERIC, {23861LU}}, /* .binaryEncodingId */
21338 sizeof(UA_ReceiveQosPriorityDataType), /* .memSize */
21339 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21340 false, /* .pointerFree */
21341 false, /* .overlayable */
21342 1, /* .membersSize */
21343 ReceiveQosPriorityDataType_members /* .members */
21344},
21345/* DatagramConnectionTransportDataType */
21346{
21347 UA_TYPENAME("DatagramConnectionTransportDataType") /* .typeName */
21348 {0, UA_NODEIDTYPE_NUMERIC, {17467LU}}, /* .typeId */
21349 {0, UA_NODEIDTYPE_NUMERIC, {17468LU}}, /* .binaryEncodingId */
21350 sizeof(UA_DatagramConnectionTransportDataType), /* .memSize */
21351 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21352 false, /* .pointerFree */
21353 false, /* .overlayable */
21354 1, /* .membersSize */
21355 DatagramConnectionTransportDataType_members /* .members */
21356},
21357/* DatagramConnectionTransport2DataType */
21358{
21359 UA_TYPENAME("DatagramConnectionTransport2DataType") /* .typeName */
21360 {0, UA_NODEIDTYPE_NUMERIC, {23612LU}}, /* .typeId */
21361 {0, UA_NODEIDTYPE_NUMERIC, {23864LU}}, /* .binaryEncodingId */
21362 sizeof(UA_DatagramConnectionTransport2DataType), /* .memSize */
21363 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21364 false, /* .pointerFree */
21365 false, /* .overlayable */
21366 5, /* .membersSize */
21367 DatagramConnectionTransport2DataType_members /* .members */
21368},
21369/* DatagramWriterGroupTransportDataType */
21370{
21371 UA_TYPENAME("DatagramWriterGroupTransportDataType") /* .typeName */
21372 {0, UA_NODEIDTYPE_NUMERIC, {15532LU}}, /* .typeId */
21373 {0, UA_NODEIDTYPE_NUMERIC, {21155LU}}, /* .binaryEncodingId */
21374 sizeof(UA_DatagramWriterGroupTransportDataType), /* .memSize */
21375 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21376 true, /* .pointerFree */
21377 false, /* .overlayable */
21378 2, /* .membersSize */
21379 DatagramWriterGroupTransportDataType_members /* .members */
21380},
21381/* DatagramWriterGroupTransport2DataType */
21382{
21383 UA_TYPENAME("DatagramWriterGroupTransport2DataType") /* .typeName */
21384 {0, UA_NODEIDTYPE_NUMERIC, {23613LU}}, /* .typeId */
21385 {0, UA_NODEIDTYPE_NUMERIC, {23865LU}}, /* .binaryEncodingId */
21386 sizeof(UA_DatagramWriterGroupTransport2DataType), /* .memSize */
21387 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21388 false, /* .pointerFree */
21389 false, /* .overlayable */
21390 7, /* .membersSize */
21391 DatagramWriterGroupTransport2DataType_members /* .members */
21392},
21393/* DatagramDataSetReaderTransportDataType */
21394{
21395 UA_TYPENAME("DatagramDataSetReaderTransportDataType") /* .typeName */
21396 {0, UA_NODEIDTYPE_NUMERIC, {23614LU}}, /* .typeId */
21397 {0, UA_NODEIDTYPE_NUMERIC, {23866LU}}, /* .binaryEncodingId */
21398 sizeof(UA_DatagramDataSetReaderTransportDataType), /* .memSize */
21399 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21400 false, /* .pointerFree */
21401 false, /* .overlayable */
21402 4, /* .membersSize */
21403 DatagramDataSetReaderTransportDataType_members /* .members */
21404},
21405/* BrokerConnectionTransportDataType */
21406{
21407 UA_TYPENAME("BrokerConnectionTransportDataType") /* .typeName */
21408 {0, UA_NODEIDTYPE_NUMERIC, {15007LU}}, /* .typeId */
21409 {0, UA_NODEIDTYPE_NUMERIC, {15479LU}}, /* .binaryEncodingId */
21410 sizeof(UA_BrokerConnectionTransportDataType), /* .memSize */
21411 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21412 false, /* .pointerFree */
21413 false, /* .overlayable */
21414 2, /* .membersSize */
21415 BrokerConnectionTransportDataType_members /* .members */
21416},
21417/* BrokerTransportQualityOfService */
21418{
21419 UA_TYPENAME("BrokerTransportQualityOfService") /* .typeName */
21420 {0, UA_NODEIDTYPE_NUMERIC, {15008LU}}, /* .typeId */
21421 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21422 sizeof(UA_BrokerTransportQualityOfService), /* .memSize */
21423 UA_DATATYPEKIND_ENUM, /* .typeKind */
21424 true, /* .pointerFree */
21425 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21426 0, /* .membersSize */
21427 BrokerTransportQualityOfService_members /* .members */
21428},
21429/* BrokerWriterGroupTransportDataType */
21430{
21431 UA_TYPENAME("BrokerWriterGroupTransportDataType") /* .typeName */
21432 {0, UA_NODEIDTYPE_NUMERIC, {15667LU}}, /* .typeId */
21433 {0, UA_NODEIDTYPE_NUMERIC, {15727LU}}, /* .binaryEncodingId */
21434 sizeof(UA_BrokerWriterGroupTransportDataType), /* .memSize */
21435 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21436 false, /* .pointerFree */
21437 false, /* .overlayable */
21438 4, /* .membersSize */
21439 BrokerWriterGroupTransportDataType_members /* .members */
21440},
21441/* BrokerDataSetWriterTransportDataType */
21442{
21443 UA_TYPENAME("BrokerDataSetWriterTransportDataType") /* .typeName */
21444 {0, UA_NODEIDTYPE_NUMERIC, {15669LU}}, /* .typeId */
21445 {0, UA_NODEIDTYPE_NUMERIC, {15729LU}}, /* .binaryEncodingId */
21446 sizeof(UA_BrokerDataSetWriterTransportDataType), /* .memSize */
21447 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21448 false, /* .pointerFree */
21449 false, /* .overlayable */
21450 6, /* .membersSize */
21451 BrokerDataSetWriterTransportDataType_members /* .members */
21452},
21453/* BrokerDataSetReaderTransportDataType */
21454{
21455 UA_TYPENAME("BrokerDataSetReaderTransportDataType") /* .typeName */
21456 {0, UA_NODEIDTYPE_NUMERIC, {15670LU}}, /* .typeId */
21457 {0, UA_NODEIDTYPE_NUMERIC, {15733LU}}, /* .binaryEncodingId */
21458 sizeof(UA_BrokerDataSetReaderTransportDataType), /* .memSize */
21459 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21460 false, /* .pointerFree */
21461 false, /* .overlayable */
21462 5, /* .membersSize */
21463 BrokerDataSetReaderTransportDataType_members /* .members */
21464},
21465/* PubSubConfigurationRefMask */
21466{
21467 UA_TYPENAME("PubSubConfigurationRefMask") /* .typeName */
21468 {0, UA_NODEIDTYPE_NUMERIC, {25517LU}}, /* .typeId */
21469 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21470 sizeof(UA_PubSubConfigurationRefMask), /* .memSize */
21471 UA_DATATYPEKIND_UINT32, /* .typeKind */
21472 true, /* .pointerFree */
21473 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21474 0, /* .membersSize */
21475 PubSubConfigurationRefMask_members /* .members */
21476},
21477/* PubSubConfigurationRefDataType */
21478{
21479 UA_TYPENAME("PubSubConfigurationRefDataType") /* .typeName */
21480 {0, UA_NODEIDTYPE_NUMERIC, {25519LU}}, /* .typeId */
21481 {0, UA_NODEIDTYPE_NUMERIC, {25531LU}}, /* .binaryEncodingId */
21482 sizeof(UA_PubSubConfigurationRefDataType), /* .memSize */
21483 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21484 true, /* .pointerFree */
21485 false, /* .overlayable */
21486 4, /* .membersSize */
21487 PubSubConfigurationRefDataType_members /* .members */
21488},
21489/* PubSubConfigurationValueDataType */
21490{
21491 UA_TYPENAME("PubSubConfigurationValueDataType") /* .typeName */
21492 {0, UA_NODEIDTYPE_NUMERIC, {25520LU}}, /* .typeId */
21493 {0, UA_NODEIDTYPE_NUMERIC, {25532LU}}, /* .binaryEncodingId */
21494 sizeof(UA_PubSubConfigurationValueDataType), /* .memSize */
21495 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21496 false, /* .pointerFree */
21497 false, /* .overlayable */
21498 3, /* .membersSize */
21499 PubSubConfigurationValueDataType_members /* .members */
21500},
21501/* DiagnosticsLevel */
21502{
21503 UA_TYPENAME("DiagnosticsLevel") /* .typeName */
21504 {0, UA_NODEIDTYPE_NUMERIC, {19723LU}}, /* .typeId */
21505 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21506 sizeof(UA_DiagnosticsLevel), /* .memSize */
21507 UA_DATATYPEKIND_ENUM, /* .typeKind */
21508 true, /* .pointerFree */
21509 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21510 0, /* .membersSize */
21511 DiagnosticsLevel_members /* .members */
21512},
21513/* PubSubDiagnosticsCounterClassification */
21514{
21515 UA_TYPENAME("PubSubDiagnosticsCounterClassification") /* .typeName */
21516 {0, UA_NODEIDTYPE_NUMERIC, {19730LU}}, /* .typeId */
21517 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21518 sizeof(UA_PubSubDiagnosticsCounterClassification), /* .memSize */
21519 UA_DATATYPEKIND_ENUM, /* .typeKind */
21520 true, /* .pointerFree */
21521 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21522 0, /* .membersSize */
21523 PubSubDiagnosticsCounterClassification_members /* .members */
21524},
21525/* AliasNameDataType */
21526{
21527 UA_TYPENAME("AliasNameDataType") /* .typeName */
21528 {0, UA_NODEIDTYPE_NUMERIC, {23468LU}}, /* .typeId */
21529 {0, UA_NODEIDTYPE_NUMERIC, {23499LU}}, /* .binaryEncodingId */
21530 sizeof(UA_AliasNameDataType), /* .memSize */
21531 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21532 false, /* .pointerFree */
21533 false, /* .overlayable */
21534 2, /* .membersSize */
21535 AliasNameDataType_members /* .members */
21536},
21537/* PasswordOptionsMask */
21538{
21539 UA_TYPENAME("PasswordOptionsMask") /* .typeName */
21540 {0, UA_NODEIDTYPE_NUMERIC, {24277LU}}, /* .typeId */
21541 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21542 sizeof(UA_PasswordOptionsMask), /* .memSize */
21543 UA_DATATYPEKIND_UINT32, /* .typeKind */
21544 true, /* .pointerFree */
21545 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21546 0, /* .membersSize */
21547 PasswordOptionsMask_members /* .members */
21548},
21549/* UserConfigurationMask */
21550{
21551 UA_TYPENAME("UserConfigurationMask") /* .typeName */
21552 {0, UA_NODEIDTYPE_NUMERIC, {24279LU}}, /* .typeId */
21553 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21554 sizeof(UA_UserConfigurationMask), /* .memSize */
21555 UA_DATATYPEKIND_UINT32, /* .typeKind */
21556 true, /* .pointerFree */
21557 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21558 0, /* .membersSize */
21559 UserConfigurationMask_members /* .members */
21560},
21561/* UserManagementDataType */
21562{
21563 UA_TYPENAME("UserManagementDataType") /* .typeName */
21564 {0, UA_NODEIDTYPE_NUMERIC, {24281LU}}, /* .typeId */
21565 {0, UA_NODEIDTYPE_NUMERIC, {24292LU}}, /* .binaryEncodingId */
21566 sizeof(UA_UserManagementDataType), /* .memSize */
21567 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21568 false, /* .pointerFree */
21569 false, /* .overlayable */
21570 3, /* .membersSize */
21571 UserManagementDataType_members /* .members */
21572},
21573/* Duplex */
21574{
21575 UA_TYPENAME("Duplex") /* .typeName */
21576 {0, UA_NODEIDTYPE_NUMERIC, {24210LU}}, /* .typeId */
21577 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21578 sizeof(UA_Duplex), /* .memSize */
21579 UA_DATATYPEKIND_ENUM, /* .typeKind */
21580 true, /* .pointerFree */
21581 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21582 0, /* .membersSize */
21583 Duplex_members /* .members */
21584},
21585/* InterfaceAdminStatus */
21586{
21587 UA_TYPENAME("InterfaceAdminStatus") /* .typeName */
21588 {0, UA_NODEIDTYPE_NUMERIC, {24212LU}}, /* .typeId */
21589 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21590 sizeof(UA_InterfaceAdminStatus), /* .memSize */
21591 UA_DATATYPEKIND_ENUM, /* .typeKind */
21592 true, /* .pointerFree */
21593 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21594 0, /* .membersSize */
21595 InterfaceAdminStatus_members /* .members */
21596},
21597/* InterfaceOperStatus */
21598{
21599 UA_TYPENAME("InterfaceOperStatus") /* .typeName */
21600 {0, UA_NODEIDTYPE_NUMERIC, {24214LU}}, /* .typeId */
21601 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21602 sizeof(UA_InterfaceOperStatus), /* .memSize */
21603 UA_DATATYPEKIND_ENUM, /* .typeKind */
21604 true, /* .pointerFree */
21605 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21606 0, /* .membersSize */
21607 InterfaceOperStatus_members /* .members */
21608},
21609/* NegotiationStatus */
21610{
21611 UA_TYPENAME("NegotiationStatus") /* .typeName */
21612 {0, UA_NODEIDTYPE_NUMERIC, {24216LU}}, /* .typeId */
21613 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21614 sizeof(UA_NegotiationStatus), /* .memSize */
21615 UA_DATATYPEKIND_ENUM, /* .typeKind */
21616 true, /* .pointerFree */
21617 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21618 0, /* .membersSize */
21619 NegotiationStatus_members /* .members */
21620},
21621/* TsnFailureCode */
21622{
21623 UA_TYPENAME("TsnFailureCode") /* .typeName */
21624 {0, UA_NODEIDTYPE_NUMERIC, {24218LU}}, /* .typeId */
21625 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21626 sizeof(UA_TsnFailureCode), /* .memSize */
21627 UA_DATATYPEKIND_ENUM, /* .typeKind */
21628 true, /* .pointerFree */
21629 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21630 0, /* .membersSize */
21631 TsnFailureCode_members /* .members */
21632},
21633/* TsnStreamState */
21634{
21635 UA_TYPENAME("TsnStreamState") /* .typeName */
21636 {0, UA_NODEIDTYPE_NUMERIC, {24220LU}}, /* .typeId */
21637 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21638 sizeof(UA_TsnStreamState), /* .memSize */
21639 UA_DATATYPEKIND_ENUM, /* .typeKind */
21640 true, /* .pointerFree */
21641 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21642 0, /* .membersSize */
21643 TsnStreamState_members /* .members */
21644},
21645/* TsnTalkerStatus */
21646{
21647 UA_TYPENAME("TsnTalkerStatus") /* .typeName */
21648 {0, UA_NODEIDTYPE_NUMERIC, {24222LU}}, /* .typeId */
21649 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21650 sizeof(UA_TsnTalkerStatus), /* .memSize */
21651 UA_DATATYPEKIND_ENUM, /* .typeKind */
21652 true, /* .pointerFree */
21653 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21654 0, /* .membersSize */
21655 TsnTalkerStatus_members /* .members */
21656},
21657/* TsnListenerStatus */
21658{
21659 UA_TYPENAME("TsnListenerStatus") /* .typeName */
21660 {0, UA_NODEIDTYPE_NUMERIC, {24224LU}}, /* .typeId */
21661 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21662 sizeof(UA_TsnListenerStatus), /* .memSize */
21663 UA_DATATYPEKIND_ENUM, /* .typeKind */
21664 true, /* .pointerFree */
21665 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21666 0, /* .membersSize */
21667 TsnListenerStatus_members /* .members */
21668},
21669/* PriorityMappingEntryType */
21670{
21671 UA_TYPENAME("PriorityMappingEntryType") /* .typeName */
21672 {0, UA_NODEIDTYPE_NUMERIC, {25220LU}}, /* .typeId */
21673 {0, UA_NODEIDTYPE_NUMERIC, {25239LU}}, /* .binaryEncodingId */
21674 sizeof(UA_PriorityMappingEntryType), /* .memSize */
21675 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21676 false, /* .pointerFree */
21677 false, /* .overlayable */
21678 4, /* .membersSize */
21679 PriorityMappingEntryType_members /* .members */
21680},
21681/* IdType */
21682{
21683 UA_TYPENAME("IdType") /* .typeName */
21684 {0, UA_NODEIDTYPE_NUMERIC, {256LU}}, /* .typeId */
21685 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21686 sizeof(UA_IdType), /* .memSize */
21687 UA_DATATYPEKIND_ENUM, /* .typeKind */
21688 true, /* .pointerFree */
21689 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21690 0, /* .membersSize */
21691 IdType_members /* .members */
21692},
21693/* NodeClass */
21694{
21695 UA_TYPENAME("NodeClass") /* .typeName */
21696 {0, UA_NODEIDTYPE_NUMERIC, {257LU}}, /* .typeId */
21697 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21698 sizeof(UA_NodeClass), /* .memSize */
21699 UA_DATATYPEKIND_ENUM, /* .typeKind */
21700 true, /* .pointerFree */
21701 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21702 0, /* .membersSize */
21703 NodeClass_members /* .members */
21704},
21705/* PermissionType */
21706{
21707 UA_TYPENAME("PermissionType") /* .typeName */
21708 {0, UA_NODEIDTYPE_NUMERIC, {94LU}}, /* .typeId */
21709 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21710 sizeof(UA_PermissionType), /* .memSize */
21711 UA_DATATYPEKIND_UINT32, /* .typeKind */
21712 true, /* .pointerFree */
21713 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21714 0, /* .membersSize */
21715 PermissionType_members /* .members */
21716},
21717/* AccessLevelType */
21718{
21719 UA_TYPENAME("AccessLevelType") /* .typeName */
21720 {0, UA_NODEIDTYPE_NUMERIC, {15031LU}}, /* .typeId */
21721 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21722 sizeof(UA_AccessLevelType), /* .memSize */
21723 UA_DATATYPEKIND_BYTE, /* .typeKind */
21724 true, /* .pointerFree */
21725 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21726 0, /* .membersSize */
21727 AccessLevelType_members /* .members */
21728},
21729/* AccessLevelExType */
21730{
21731 UA_TYPENAME("AccessLevelExType") /* .typeName */
21732 {0, UA_NODEIDTYPE_NUMERIC, {15406LU}}, /* .typeId */
21733 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21734 sizeof(UA_AccessLevelExType), /* .memSize */
21735 UA_DATATYPEKIND_UINT32, /* .typeKind */
21736 true, /* .pointerFree */
21737 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21738 0, /* .membersSize */
21739 AccessLevelExType_members /* .members */
21740},
21741/* EventNotifierType */
21742{
21743 UA_TYPENAME("EventNotifierType") /* .typeName */
21744 {0, UA_NODEIDTYPE_NUMERIC, {15033LU}}, /* .typeId */
21745 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21746 sizeof(UA_EventNotifierType), /* .memSize */
21747 UA_DATATYPEKIND_BYTE, /* .typeKind */
21748 true, /* .pointerFree */
21749 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21750 0, /* .membersSize */
21751 EventNotifierType_members /* .members */
21752},
21753/* AccessRestrictionType */
21754{
21755 UA_TYPENAME("AccessRestrictionType") /* .typeName */
21756 {0, UA_NODEIDTYPE_NUMERIC, {95LU}}, /* .typeId */
21757 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21758 sizeof(UA_AccessRestrictionType), /* .memSize */
21759 UA_DATATYPEKIND_UINT16, /* .typeKind */
21760 true, /* .pointerFree */
21761 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21762 0, /* .membersSize */
21763 AccessRestrictionType_members /* .members */
21764},
21765/* RolePermissionType */
21766{
21767 UA_TYPENAME("RolePermissionType") /* .typeName */
21768 {0, UA_NODEIDTYPE_NUMERIC, {96LU}}, /* .typeId */
21769 {0, UA_NODEIDTYPE_NUMERIC, {128LU}}, /* .binaryEncodingId */
21770 sizeof(UA_RolePermissionType), /* .memSize */
21771 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21772 false, /* .pointerFree */
21773 false, /* .overlayable */
21774 2, /* .membersSize */
21775 RolePermissionType_members /* .members */
21776},
21777/* StructureType */
21778{
21779 UA_TYPENAME("StructureType") /* .typeName */
21780 {0, UA_NODEIDTYPE_NUMERIC, {98LU}}, /* .typeId */
21781 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21782 sizeof(UA_StructureType), /* .memSize */
21783 UA_DATATYPEKIND_ENUM, /* .typeKind */
21784 true, /* .pointerFree */
21785 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
21786 0, /* .membersSize */
21787 StructureType_members /* .members */
21788},
21789/* StructureField */
21790{
21791 UA_TYPENAME("StructureField") /* .typeName */
21792 {0, UA_NODEIDTYPE_NUMERIC, {101LU}}, /* .typeId */
21793 {0, UA_NODEIDTYPE_NUMERIC, {14844LU}}, /* .binaryEncodingId */
21794 sizeof(UA_StructureField), /* .memSize */
21795 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21796 false, /* .pointerFree */
21797 false, /* .overlayable */
21798 7, /* .membersSize */
21799 StructureField_members /* .members */
21800},
21801/* StructureDefinition */
21802{
21803 UA_TYPENAME("StructureDefinition") /* .typeName */
21804 {0, UA_NODEIDTYPE_NUMERIC, {99LU}}, /* .typeId */
21805 {0, UA_NODEIDTYPE_NUMERIC, {122LU}}, /* .binaryEncodingId */
21806 sizeof(UA_StructureDefinition), /* .memSize */
21807 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21808 false, /* .pointerFree */
21809 false, /* .overlayable */
21810 4, /* .membersSize */
21811 StructureDefinition_members /* .members */
21812},
21813/* ReferenceNode */
21814{
21815 UA_TYPENAME("ReferenceNode") /* .typeName */
21816 {0, UA_NODEIDTYPE_NUMERIC, {285LU}}, /* .typeId */
21817 {0, UA_NODEIDTYPE_NUMERIC, {287LU}}, /* .binaryEncodingId */
21818 sizeof(UA_ReferenceNode), /* .memSize */
21819 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21820 false, /* .pointerFree */
21821 false, /* .overlayable */
21822 3, /* .membersSize */
21823 ReferenceNode_members /* .members */
21824},
21825/* Argument */
21826{
21827 UA_TYPENAME("Argument") /* .typeName */
21828 {0, UA_NODEIDTYPE_NUMERIC, {296LU}}, /* .typeId */
21829 {0, UA_NODEIDTYPE_NUMERIC, {298LU}}, /* .binaryEncodingId */
21830 sizeof(UA_Argument), /* .memSize */
21831 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21832 false, /* .pointerFree */
21833 false, /* .overlayable */
21834 5, /* .membersSize */
21835 Argument_members /* .members */
21836},
21837/* EnumValueType */
21838{
21839 UA_TYPENAME("EnumValueType") /* .typeName */
21840 {0, UA_NODEIDTYPE_NUMERIC, {7594LU}}, /* .typeId */
21841 {0, UA_NODEIDTYPE_NUMERIC, {8251LU}}, /* .binaryEncodingId */
21842 sizeof(UA_EnumValueType), /* .memSize */
21843 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21844 false, /* .pointerFree */
21845 false, /* .overlayable */
21846 3, /* .membersSize */
21847 EnumValueType_members /* .members */
21848},
21849/* EnumField */
21850{
21851 UA_TYPENAME("EnumField") /* .typeName */
21852 {0, UA_NODEIDTYPE_NUMERIC, {102LU}}, /* .typeId */
21853 {0, UA_NODEIDTYPE_NUMERIC, {14845LU}}, /* .binaryEncodingId */
21854 sizeof(UA_EnumField), /* .memSize */
21855 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21856 false, /* .pointerFree */
21857 false, /* .overlayable */
21858 4, /* .membersSize */
21859 EnumField_members /* .members */
21860},
21861/* OptionSet */
21862{
21863 UA_TYPENAME("OptionSet") /* .typeName */
21864 {0, UA_NODEIDTYPE_NUMERIC, {12755LU}}, /* .typeId */
21865 {0, UA_NODEIDTYPE_NUMERIC, {12765LU}}, /* .binaryEncodingId */
21866 sizeof(UA_OptionSet), /* .memSize */
21867 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21868 false, /* .pointerFree */
21869 false, /* .overlayable */
21870 2, /* .membersSize */
21871 OptionSet_members /* .members */
21872},
21873/* NormalizedString */
21874{
21875 UA_TYPENAME("NormalizedString") /* .typeName */
21876 {0, UA_NODEIDTYPE_NUMERIC, {12877LU}}, /* .typeId */
21877 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21878 sizeof(UA_NormalizedString), /* .memSize */
21879 UA_DATATYPEKIND_STRING, /* .typeKind */
21880 false, /* .pointerFree */
21881 false, /* .overlayable */
21882 0, /* .membersSize */
21883 NormalizedString_members /* .members */
21884},
21885/* DecimalString */
21886{
21887 UA_TYPENAME("DecimalString") /* .typeName */
21888 {0, UA_NODEIDTYPE_NUMERIC, {12878LU}}, /* .typeId */
21889 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21890 sizeof(UA_DecimalString), /* .memSize */
21891 UA_DATATYPEKIND_STRING, /* .typeKind */
21892 false, /* .pointerFree */
21893 false, /* .overlayable */
21894 0, /* .membersSize */
21895 DecimalString_members /* .members */
21896},
21897/* DurationString */
21898{
21899 UA_TYPENAME("DurationString") /* .typeName */
21900 {0, UA_NODEIDTYPE_NUMERIC, {12879LU}}, /* .typeId */
21901 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21902 sizeof(UA_DurationString), /* .memSize */
21903 UA_DATATYPEKIND_STRING, /* .typeKind */
21904 false, /* .pointerFree */
21905 false, /* .overlayable */
21906 0, /* .membersSize */
21907 DurationString_members /* .members */
21908},
21909/* TimeString */
21910{
21911 UA_TYPENAME("TimeString") /* .typeName */
21912 {0, UA_NODEIDTYPE_NUMERIC, {12880LU}}, /* .typeId */
21913 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21914 sizeof(UA_TimeString), /* .memSize */
21915 UA_DATATYPEKIND_STRING, /* .typeKind */
21916 false, /* .pointerFree */
21917 false, /* .overlayable */
21918 0, /* .membersSize */
21919 TimeString_members /* .members */
21920},
21921/* DateString */
21922{
21923 UA_TYPENAME("DateString") /* .typeName */
21924 {0, UA_NODEIDTYPE_NUMERIC, {12881LU}}, /* .typeId */
21925 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21926 sizeof(UA_DateString), /* .memSize */
21927 UA_DATATYPEKIND_STRING, /* .typeKind */
21928 false, /* .pointerFree */
21929 false, /* .overlayable */
21930 0, /* .membersSize */
21931 DateString_members /* .members */
21932},
21933/* Duration */
21934{
21935 UA_TYPENAME("Duration") /* .typeName */
21936 {0, UA_NODEIDTYPE_NUMERIC, {290LU}}, /* .typeId */
21937 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21938 sizeof(UA_Duration), /* .memSize */
21939 UA_DATATYPEKIND_DOUBLE, /* .typeKind */
21940 false, /* .pointerFree */
21941 false, /* .overlayable */
21942 0, /* .membersSize */
21943 Duration_members /* .members */
21944},
21945/* UtcTime */
21946{
21947 UA_TYPENAME("UtcTime") /* .typeName */
21948 {0, UA_NODEIDTYPE_NUMERIC, {294LU}}, /* .typeId */
21949 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21950 sizeof(UA_UtcTime), /* .memSize */
21951 UA_DATATYPEKIND_DATETIME, /* .typeKind */
21952 false, /* .pointerFree */
21953 false, /* .overlayable */
21954 0, /* .membersSize */
21955 UtcTime_members /* .members */
21956},
21957/* LocaleId */
21958{
21959 UA_TYPENAME("LocaleId") /* .typeName */
21960 {0, UA_NODEIDTYPE_NUMERIC, {295LU}}, /* .typeId */
21961 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21962 sizeof(UA_LocaleId), /* .memSize */
21963 UA_DATATYPEKIND_STRING, /* .typeKind */
21964 false, /* .pointerFree */
21965 false, /* .overlayable */
21966 0, /* .membersSize */
21967 LocaleId_members /* .members */
21968},
21969/* TimeZoneDataType */
21970{
21971 UA_TYPENAME("TimeZoneDataType") /* .typeName */
21972 {0, UA_NODEIDTYPE_NUMERIC, {8912LU}}, /* .typeId */
21973 {0, UA_NODEIDTYPE_NUMERIC, {8917LU}}, /* .binaryEncodingId */
21974 sizeof(UA_TimeZoneDataType), /* .memSize */
21975 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
21976 true, /* .pointerFree */
21977 false, /* .overlayable */
21978 2, /* .membersSize */
21979 TimeZoneDataType_members /* .members */
21980},
21981/* Index */
21982{
21983 UA_TYPENAME("Index") /* .typeName */
21984 {0, UA_NODEIDTYPE_NUMERIC, {17588LU}}, /* .typeId */
21985 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21986 sizeof(UA_Index), /* .memSize */
21987 UA_DATATYPEKIND_BYTESTRING, /* .typeKind */
21988 false, /* .pointerFree */
21989 false, /* .overlayable */
21990 0, /* .membersSize */
21991 Index_members /* .members */
21992},
21993/* IntegerId */
21994{
21995 UA_TYPENAME("IntegerId") /* .typeName */
21996 {0, UA_NODEIDTYPE_NUMERIC, {288LU}}, /* .typeId */
21997 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
21998 sizeof(UA_IntegerId), /* .memSize */
21999 UA_DATATYPEKIND_UINT32, /* .typeKind */
22000 false, /* .pointerFree */
22001 false, /* .overlayable */
22002 0, /* .membersSize */
22003 IntegerId_members /* .members */
22004},
22005/* ApplicationType */
22006{
22007 UA_TYPENAME("ApplicationType") /* .typeName */
22008 {0, UA_NODEIDTYPE_NUMERIC, {307LU}}, /* .typeId */
22009 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22010 sizeof(UA_ApplicationType), /* .memSize */
22011 UA_DATATYPEKIND_ENUM, /* .typeKind */
22012 true, /* .pointerFree */
22013 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
22014 0, /* .membersSize */
22015 ApplicationType_members /* .members */
22016},
22017/* ApplicationDescription */
22018{
22019 UA_TYPENAME("ApplicationDescription") /* .typeName */
22020 {0, UA_NODEIDTYPE_NUMERIC, {308LU}}, /* .typeId */
22021 {0, UA_NODEIDTYPE_NUMERIC, {310LU}}, /* .binaryEncodingId */
22022 sizeof(UA_ApplicationDescription), /* .memSize */
22023 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22024 false, /* .pointerFree */
22025 false, /* .overlayable */
22026 7, /* .membersSize */
22027 ApplicationDescription_members /* .members */
22028},
22029/* RequestHeader */
22030{
22031 UA_TYPENAME("RequestHeader") /* .typeName */
22032 {0, UA_NODEIDTYPE_NUMERIC, {389LU}}, /* .typeId */
22033 {0, UA_NODEIDTYPE_NUMERIC, {391LU}}, /* .binaryEncodingId */
22034 sizeof(UA_RequestHeader), /* .memSize */
22035 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22036 false, /* .pointerFree */
22037 false, /* .overlayable */
22038 7, /* .membersSize */
22039 RequestHeader_members /* .members */
22040},
22041/* ResponseHeader */
22042{
22043 UA_TYPENAME("ResponseHeader") /* .typeName */
22044 {0, UA_NODEIDTYPE_NUMERIC, {392LU}}, /* .typeId */
22045 {0, UA_NODEIDTYPE_NUMERIC, {394LU}}, /* .binaryEncodingId */
22046 sizeof(UA_ResponseHeader), /* .memSize */
22047 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22048 false, /* .pointerFree */
22049 false, /* .overlayable */
22050 6, /* .membersSize */
22051 ResponseHeader_members /* .members */
22052},
22053/* VersionTime */
22054{
22055 UA_TYPENAME("VersionTime") /* .typeName */
22056 {0, UA_NODEIDTYPE_NUMERIC, {20998LU}}, /* .typeId */
22057 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22058 sizeof(UA_VersionTime), /* .memSize */
22059 UA_DATATYPEKIND_BYTESTRING, /* .typeKind */
22060 false, /* .pointerFree */
22061 false, /* .overlayable */
22062 0, /* .membersSize */
22063 VersionTime_members /* .members */
22064},
22065/* ServiceFault */
22066{
22067 UA_TYPENAME("ServiceFault") /* .typeName */
22068 {0, UA_NODEIDTYPE_NUMERIC, {395LU}}, /* .typeId */
22069 {0, UA_NODEIDTYPE_NUMERIC, {397LU}}, /* .binaryEncodingId */
22070 sizeof(UA_ServiceFault), /* .memSize */
22071 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22072 false, /* .pointerFree */
22073 false, /* .overlayable */
22074 1, /* .membersSize */
22075 ServiceFault_members /* .members */
22076},
22077/* SessionlessInvokeRequestType */
22078{
22079 UA_TYPENAME("SessionlessInvokeRequestType") /* .typeName */
22080 {0, UA_NODEIDTYPE_NUMERIC, {15901LU}}, /* .typeId */
22081 {0, UA_NODEIDTYPE_NUMERIC, {15903LU}}, /* .binaryEncodingId */
22082 sizeof(UA_SessionlessInvokeRequestType), /* .memSize */
22083 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22084 false, /* .pointerFree */
22085 false, /* .overlayable */
22086 5, /* .membersSize */
22087 SessionlessInvokeRequestType_members /* .members */
22088},
22089/* SessionlessInvokeResponseType */
22090{
22091 UA_TYPENAME("SessionlessInvokeResponseType") /* .typeName */
22092 {0, UA_NODEIDTYPE_NUMERIC, {20999LU}}, /* .typeId */
22093 {0, UA_NODEIDTYPE_NUMERIC, {21001LU}}, /* .binaryEncodingId */
22094 sizeof(UA_SessionlessInvokeResponseType), /* .memSize */
22095 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22096 false, /* .pointerFree */
22097 false, /* .overlayable */
22098 3, /* .membersSize */
22099 SessionlessInvokeResponseType_members /* .members */
22100},
22101/* FindServersRequest */
22102{
22103 UA_TYPENAME("FindServersRequest") /* .typeName */
22104 {0, UA_NODEIDTYPE_NUMERIC, {420LU}}, /* .typeId */
22105 {0, UA_NODEIDTYPE_NUMERIC, {422LU}}, /* .binaryEncodingId */
22106 sizeof(UA_FindServersRequest), /* .memSize */
22107 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22108 false, /* .pointerFree */
22109 false, /* .overlayable */
22110 4, /* .membersSize */
22111 FindServersRequest_members /* .members */
22112},
22113/* FindServersResponse */
22114{
22115 UA_TYPENAME("FindServersResponse") /* .typeName */
22116 {0, UA_NODEIDTYPE_NUMERIC, {423LU}}, /* .typeId */
22117 {0, UA_NODEIDTYPE_NUMERIC, {425LU}}, /* .binaryEncodingId */
22118 sizeof(UA_FindServersResponse), /* .memSize */
22119 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22120 false, /* .pointerFree */
22121 false, /* .overlayable */
22122 2, /* .membersSize */
22123 FindServersResponse_members /* .members */
22124},
22125/* ServerOnNetwork */
22126{
22127 UA_TYPENAME("ServerOnNetwork") /* .typeName */
22128 {0, UA_NODEIDTYPE_NUMERIC, {12189LU}}, /* .typeId */
22129 {0, UA_NODEIDTYPE_NUMERIC, {12207LU}}, /* .binaryEncodingId */
22130 sizeof(UA_ServerOnNetwork), /* .memSize */
22131 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22132 false, /* .pointerFree */
22133 false, /* .overlayable */
22134 4, /* .membersSize */
22135 ServerOnNetwork_members /* .members */
22136},
22137/* FindServersOnNetworkRequest */
22138{
22139 UA_TYPENAME("FindServersOnNetworkRequest") /* .typeName */
22140 {0, UA_NODEIDTYPE_NUMERIC, {12190LU}}, /* .typeId */
22141 {0, UA_NODEIDTYPE_NUMERIC, {12208LU}}, /* .binaryEncodingId */
22142 sizeof(UA_FindServersOnNetworkRequest), /* .memSize */
22143 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22144 false, /* .pointerFree */
22145 false, /* .overlayable */
22146 4, /* .membersSize */
22147 FindServersOnNetworkRequest_members /* .members */
22148},
22149/* FindServersOnNetworkResponse */
22150{
22151 UA_TYPENAME("FindServersOnNetworkResponse") /* .typeName */
22152 {0, UA_NODEIDTYPE_NUMERIC, {12191LU}}, /* .typeId */
22153 {0, UA_NODEIDTYPE_NUMERIC, {12209LU}}, /* .binaryEncodingId */
22154 sizeof(UA_FindServersOnNetworkResponse), /* .memSize */
22155 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22156 false, /* .pointerFree */
22157 false, /* .overlayable */
22158 3, /* .membersSize */
22159 FindServersOnNetworkResponse_members /* .members */
22160},
22161/* ApplicationInstanceCertificate */
22162{
22163 UA_TYPENAME("ApplicationInstanceCertificate") /* .typeName */
22164 {0, UA_NODEIDTYPE_NUMERIC, {311LU}}, /* .typeId */
22165 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22166 sizeof(UA_ApplicationInstanceCertificate), /* .memSize */
22167 UA_DATATYPEKIND_BYTESTRING, /* .typeKind */
22168 false, /* .pointerFree */
22169 false, /* .overlayable */
22170 0, /* .membersSize */
22171 ApplicationInstanceCertificate_members /* .members */
22172},
22173/* MessageSecurityMode */
22174{
22175 UA_TYPENAME("MessageSecurityMode") /* .typeName */
22176 {0, UA_NODEIDTYPE_NUMERIC, {302LU}}, /* .typeId */
22177 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22178 sizeof(UA_MessageSecurityMode), /* .memSize */
22179 UA_DATATYPEKIND_ENUM, /* .typeKind */
22180 true, /* .pointerFree */
22181 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
22182 0, /* .membersSize */
22183 MessageSecurityMode_members /* .members */
22184},
22185/* UserTokenType */
22186{
22187 UA_TYPENAME("UserTokenType") /* .typeName */
22188 {0, UA_NODEIDTYPE_NUMERIC, {303LU}}, /* .typeId */
22189 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22190 sizeof(UA_UserTokenType), /* .memSize */
22191 UA_DATATYPEKIND_ENUM, /* .typeKind */
22192 true, /* .pointerFree */
22193 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
22194 0, /* .membersSize */
22195 UserTokenType_members /* .members */
22196},
22197/* UserTokenPolicy */
22198{
22199 UA_TYPENAME("UserTokenPolicy") /* .typeName */
22200 {0, UA_NODEIDTYPE_NUMERIC, {304LU}}, /* .typeId */
22201 {0, UA_NODEIDTYPE_NUMERIC, {306LU}}, /* .binaryEncodingId */
22202 sizeof(UA_UserTokenPolicy), /* .memSize */
22203 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22204 false, /* .pointerFree */
22205 false, /* .overlayable */
22206 5, /* .membersSize */
22207 UserTokenPolicy_members /* .members */
22208},
22209/* EndpointDescription */
22210{
22211 UA_TYPENAME("EndpointDescription") /* .typeName */
22212 {0, UA_NODEIDTYPE_NUMERIC, {312LU}}, /* .typeId */
22213 {0, UA_NODEIDTYPE_NUMERIC, {314LU}}, /* .binaryEncodingId */
22214 sizeof(UA_EndpointDescription), /* .memSize */
22215 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22216 false, /* .pointerFree */
22217 false, /* .overlayable */
22218 8, /* .membersSize */
22219 EndpointDescription_members /* .members */
22220},
22221/* GetEndpointsRequest */
22222{
22223 UA_TYPENAME("GetEndpointsRequest") /* .typeName */
22224 {0, UA_NODEIDTYPE_NUMERIC, {426LU}}, /* .typeId */
22225 {0, UA_NODEIDTYPE_NUMERIC, {428LU}}, /* .binaryEncodingId */
22226 sizeof(UA_GetEndpointsRequest), /* .memSize */
22227 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22228 false, /* .pointerFree */
22229 false, /* .overlayable */
22230 4, /* .membersSize */
22231 GetEndpointsRequest_members /* .members */
22232},
22233/* GetEndpointsResponse */
22234{
22235 UA_TYPENAME("GetEndpointsResponse") /* .typeName */
22236 {0, UA_NODEIDTYPE_NUMERIC, {429LU}}, /* .typeId */
22237 {0, UA_NODEIDTYPE_NUMERIC, {431LU}}, /* .binaryEncodingId */
22238 sizeof(UA_GetEndpointsResponse), /* .memSize */
22239 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22240 false, /* .pointerFree */
22241 false, /* .overlayable */
22242 2, /* .membersSize */
22243 GetEndpointsResponse_members /* .members */
22244},
22245/* RegisteredServer */
22246{
22247 UA_TYPENAME("RegisteredServer") /* .typeName */
22248 {0, UA_NODEIDTYPE_NUMERIC, {432LU}}, /* .typeId */
22249 {0, UA_NODEIDTYPE_NUMERIC, {434LU}}, /* .binaryEncodingId */
22250 sizeof(UA_RegisteredServer), /* .memSize */
22251 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22252 false, /* .pointerFree */
22253 false, /* .overlayable */
22254 8, /* .membersSize */
22255 RegisteredServer_members /* .members */
22256},
22257/* RegisterServerRequest */
22258{
22259 UA_TYPENAME("RegisterServerRequest") /* .typeName */
22260 {0, UA_NODEIDTYPE_NUMERIC, {435LU}}, /* .typeId */
22261 {0, UA_NODEIDTYPE_NUMERIC, {437LU}}, /* .binaryEncodingId */
22262 sizeof(UA_RegisterServerRequest), /* .memSize */
22263 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22264 false, /* .pointerFree */
22265 false, /* .overlayable */
22266 2, /* .membersSize */
22267 RegisterServerRequest_members /* .members */
22268},
22269/* RegisterServerResponse */
22270{
22271 UA_TYPENAME("RegisterServerResponse") /* .typeName */
22272 {0, UA_NODEIDTYPE_NUMERIC, {438LU}}, /* .typeId */
22273 {0, UA_NODEIDTYPE_NUMERIC, {440LU}}, /* .binaryEncodingId */
22274 sizeof(UA_RegisterServerResponse), /* .memSize */
22275 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22276 false, /* .pointerFree */
22277 false, /* .overlayable */
22278 1, /* .membersSize */
22279 RegisterServerResponse_members /* .members */
22280},
22281/* MdnsDiscoveryConfiguration */
22282{
22283 UA_TYPENAME("MdnsDiscoveryConfiguration") /* .typeName */
22284 {0, UA_NODEIDTYPE_NUMERIC, {12891LU}}, /* .typeId */
22285 {0, UA_NODEIDTYPE_NUMERIC, {12901LU}}, /* .binaryEncodingId */
22286 sizeof(UA_MdnsDiscoveryConfiguration), /* .memSize */
22287 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22288 false, /* .pointerFree */
22289 false, /* .overlayable */
22290 2, /* .membersSize */
22291 MdnsDiscoveryConfiguration_members /* .members */
22292},
22293/* RegisterServer2Request */
22294{
22295 UA_TYPENAME("RegisterServer2Request") /* .typeName */
22296 {0, UA_NODEIDTYPE_NUMERIC, {12193LU}}, /* .typeId */
22297 {0, UA_NODEIDTYPE_NUMERIC, {12211LU}}, /* .binaryEncodingId */
22298 sizeof(UA_RegisterServer2Request), /* .memSize */
22299 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22300 false, /* .pointerFree */
22301 false, /* .overlayable */
22302 3, /* .membersSize */
22303 RegisterServer2Request_members /* .members */
22304},
22305/* RegisterServer2Response */
22306{
22307 UA_TYPENAME("RegisterServer2Response") /* .typeName */
22308 {0, UA_NODEIDTYPE_NUMERIC, {12194LU}}, /* .typeId */
22309 {0, UA_NODEIDTYPE_NUMERIC, {12212LU}}, /* .binaryEncodingId */
22310 sizeof(UA_RegisterServer2Response), /* .memSize */
22311 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22312 false, /* .pointerFree */
22313 false, /* .overlayable */
22314 3, /* .membersSize */
22315 RegisterServer2Response_members /* .members */
22316},
22317/* SecurityTokenRequestType */
22318{
22319 UA_TYPENAME("SecurityTokenRequestType") /* .typeName */
22320 {0, UA_NODEIDTYPE_NUMERIC, {315LU}}, /* .typeId */
22321 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22322 sizeof(UA_SecurityTokenRequestType), /* .memSize */
22323 UA_DATATYPEKIND_ENUM, /* .typeKind */
22324 true, /* .pointerFree */
22325 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
22326 0, /* .membersSize */
22327 SecurityTokenRequestType_members /* .members */
22328},
22329/* ChannelSecurityToken */
22330{
22331 UA_TYPENAME("ChannelSecurityToken") /* .typeName */
22332 {0, UA_NODEIDTYPE_NUMERIC, {441LU}}, /* .typeId */
22333 {0, UA_NODEIDTYPE_NUMERIC, {443LU}}, /* .binaryEncodingId */
22334 sizeof(UA_ChannelSecurityToken), /* .memSize */
22335 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22336 true, /* .pointerFree */
22337 false, /* .overlayable */
22338 4, /* .membersSize */
22339 ChannelSecurityToken_members /* .members */
22340},
22341/* OpenSecureChannelRequest */
22342{
22343 UA_TYPENAME("OpenSecureChannelRequest") /* .typeName */
22344 {0, UA_NODEIDTYPE_NUMERIC, {444LU}}, /* .typeId */
22345 {0, UA_NODEIDTYPE_NUMERIC, {446LU}}, /* .binaryEncodingId */
22346 sizeof(UA_OpenSecureChannelRequest), /* .memSize */
22347 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22348 false, /* .pointerFree */
22349 false, /* .overlayable */
22350 6, /* .membersSize */
22351 OpenSecureChannelRequest_members /* .members */
22352},
22353/* OpenSecureChannelResponse */
22354{
22355 UA_TYPENAME("OpenSecureChannelResponse") /* .typeName */
22356 {0, UA_NODEIDTYPE_NUMERIC, {447LU}}, /* .typeId */
22357 {0, UA_NODEIDTYPE_NUMERIC, {449LU}}, /* .binaryEncodingId */
22358 sizeof(UA_OpenSecureChannelResponse), /* .memSize */
22359 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22360 false, /* .pointerFree */
22361 false, /* .overlayable */
22362 4, /* .membersSize */
22363 OpenSecureChannelResponse_members /* .members */
22364},
22365/* CloseSecureChannelRequest */
22366{
22367 UA_TYPENAME("CloseSecureChannelRequest") /* .typeName */
22368 {0, UA_NODEIDTYPE_NUMERIC, {450LU}}, /* .typeId */
22369 {0, UA_NODEIDTYPE_NUMERIC, {452LU}}, /* .binaryEncodingId */
22370 sizeof(UA_CloseSecureChannelRequest), /* .memSize */
22371 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22372 false, /* .pointerFree */
22373 false, /* .overlayable */
22374 1, /* .membersSize */
22375 CloseSecureChannelRequest_members /* .members */
22376},
22377/* CloseSecureChannelResponse */
22378{
22379 UA_TYPENAME("CloseSecureChannelResponse") /* .typeName */
22380 {0, UA_NODEIDTYPE_NUMERIC, {453LU}}, /* .typeId */
22381 {0, UA_NODEIDTYPE_NUMERIC, {455LU}}, /* .binaryEncodingId */
22382 sizeof(UA_CloseSecureChannelResponse), /* .memSize */
22383 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22384 false, /* .pointerFree */
22385 false, /* .overlayable */
22386 1, /* .membersSize */
22387 CloseSecureChannelResponse_members /* .members */
22388},
22389/* SignedSoftwareCertificate */
22390{
22391 UA_TYPENAME("SignedSoftwareCertificate") /* .typeName */
22392 {0, UA_NODEIDTYPE_NUMERIC, {344LU}}, /* .typeId */
22393 {0, UA_NODEIDTYPE_NUMERIC, {346LU}}, /* .binaryEncodingId */
22394 sizeof(UA_SignedSoftwareCertificate), /* .memSize */
22395 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22396 false, /* .pointerFree */
22397 false, /* .overlayable */
22398 2, /* .membersSize */
22399 SignedSoftwareCertificate_members /* .members */
22400},
22401/* SessionAuthenticationToken */
22402{
22403 UA_TYPENAME("SessionAuthenticationToken") /* .typeName */
22404 {0, UA_NODEIDTYPE_NUMERIC, {388LU}}, /* .typeId */
22405 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22406 sizeof(UA_SessionAuthenticationToken), /* .memSize */
22407 UA_DATATYPEKIND_NODEID, /* .typeKind */
22408 false, /* .pointerFree */
22409 false, /* .overlayable */
22410 0, /* .membersSize */
22411 SessionAuthenticationToken_members /* .members */
22412},
22413/* SignatureData */
22414{
22415 UA_TYPENAME("SignatureData") /* .typeName */
22416 {0, UA_NODEIDTYPE_NUMERIC, {456LU}}, /* .typeId */
22417 {0, UA_NODEIDTYPE_NUMERIC, {458LU}}, /* .binaryEncodingId */
22418 sizeof(UA_SignatureData), /* .memSize */
22419 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22420 false, /* .pointerFree */
22421 false, /* .overlayable */
22422 2, /* .membersSize */
22423 SignatureData_members /* .members */
22424},
22425/* CreateSessionRequest */
22426{
22427 UA_TYPENAME("CreateSessionRequest") /* .typeName */
22428 {0, UA_NODEIDTYPE_NUMERIC, {459LU}}, /* .typeId */
22429 {0, UA_NODEIDTYPE_NUMERIC, {461LU}}, /* .binaryEncodingId */
22430 sizeof(UA_CreateSessionRequest), /* .memSize */
22431 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22432 false, /* .pointerFree */
22433 false, /* .overlayable */
22434 9, /* .membersSize */
22435 CreateSessionRequest_members /* .members */
22436},
22437/* CreateSessionResponse */
22438{
22439 UA_TYPENAME("CreateSessionResponse") /* .typeName */
22440 {0, UA_NODEIDTYPE_NUMERIC, {462LU}}, /* .typeId */
22441 {0, UA_NODEIDTYPE_NUMERIC, {464LU}}, /* .binaryEncodingId */
22442 sizeof(UA_CreateSessionResponse), /* .memSize */
22443 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22444 false, /* .pointerFree */
22445 false, /* .overlayable */
22446 10, /* .membersSize */
22447 CreateSessionResponse_members /* .members */
22448},
22449/* UserIdentityToken */
22450{
22451 UA_TYPENAME("UserIdentityToken") /* .typeName */
22452 {0, UA_NODEIDTYPE_NUMERIC, {316LU}}, /* .typeId */
22453 {0, UA_NODEIDTYPE_NUMERIC, {318LU}}, /* .binaryEncodingId */
22454 sizeof(UA_UserIdentityToken), /* .memSize */
22455 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22456 false, /* .pointerFree */
22457 false, /* .overlayable */
22458 1, /* .membersSize */
22459 UserIdentityToken_members /* .members */
22460},
22461/* AnonymousIdentityToken */
22462{
22463 UA_TYPENAME("AnonymousIdentityToken") /* .typeName */
22464 {0, UA_NODEIDTYPE_NUMERIC, {319LU}}, /* .typeId */
22465 {0, UA_NODEIDTYPE_NUMERIC, {321LU}}, /* .binaryEncodingId */
22466 sizeof(UA_AnonymousIdentityToken), /* .memSize */
22467 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22468 false, /* .pointerFree */
22469 false, /* .overlayable */
22470 1, /* .membersSize */
22471 AnonymousIdentityToken_members /* .members */
22472},
22473/* UserNameIdentityToken */
22474{
22475 UA_TYPENAME("UserNameIdentityToken") /* .typeName */
22476 {0, UA_NODEIDTYPE_NUMERIC, {322LU}}, /* .typeId */
22477 {0, UA_NODEIDTYPE_NUMERIC, {324LU}}, /* .binaryEncodingId */
22478 sizeof(UA_UserNameIdentityToken), /* .memSize */
22479 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22480 false, /* .pointerFree */
22481 false, /* .overlayable */
22482 4, /* .membersSize */
22483 UserNameIdentityToken_members /* .members */
22484},
22485/* X509IdentityToken */
22486{
22487 UA_TYPENAME("X509IdentityToken") /* .typeName */
22488 {0, UA_NODEIDTYPE_NUMERIC, {325LU}}, /* .typeId */
22489 {0, UA_NODEIDTYPE_NUMERIC, {327LU}}, /* .binaryEncodingId */
22490 sizeof(UA_X509IdentityToken), /* .memSize */
22491 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22492 false, /* .pointerFree */
22493 false, /* .overlayable */
22494 2, /* .membersSize */
22495 X509IdentityToken_members /* .members */
22496},
22497/* IssuedIdentityToken */
22498{
22499 UA_TYPENAME("IssuedIdentityToken") /* .typeName */
22500 {0, UA_NODEIDTYPE_NUMERIC, {938LU}}, /* .typeId */
22501 {0, UA_NODEIDTYPE_NUMERIC, {940LU}}, /* .binaryEncodingId */
22502 sizeof(UA_IssuedIdentityToken), /* .memSize */
22503 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22504 false, /* .pointerFree */
22505 false, /* .overlayable */
22506 3, /* .membersSize */
22507 IssuedIdentityToken_members /* .members */
22508},
22509/* RsaEncryptedSecret */
22510{
22511 UA_TYPENAME("RsaEncryptedSecret") /* .typeName */
22512 {0, UA_NODEIDTYPE_NUMERIC, {17545LU}}, /* .typeId */
22513 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22514 sizeof(UA_RsaEncryptedSecret), /* .memSize */
22515 UA_DATATYPEKIND_BYTESTRING, /* .typeKind */
22516 false, /* .pointerFree */
22517 false, /* .overlayable */
22518 0, /* .membersSize */
22519 RsaEncryptedSecret_members /* .members */
22520},
22521/* EccEncryptedSecret */
22522{
22523 UA_TYPENAME("EccEncryptedSecret") /* .typeName */
22524 {0, UA_NODEIDTYPE_NUMERIC, {17546LU}}, /* .typeId */
22525 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22526 sizeof(UA_EccEncryptedSecret), /* .memSize */
22527 UA_DATATYPEKIND_BYTESTRING, /* .typeKind */
22528 false, /* .pointerFree */
22529 false, /* .overlayable */
22530 0, /* .membersSize */
22531 EccEncryptedSecret_members /* .members */
22532},
22533/* ActivateSessionRequest */
22534{
22535 UA_TYPENAME("ActivateSessionRequest") /* .typeName */
22536 {0, UA_NODEIDTYPE_NUMERIC, {465LU}}, /* .typeId */
22537 {0, UA_NODEIDTYPE_NUMERIC, {467LU}}, /* .binaryEncodingId */
22538 sizeof(UA_ActivateSessionRequest), /* .memSize */
22539 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22540 false, /* .pointerFree */
22541 false, /* .overlayable */
22542 6, /* .membersSize */
22543 ActivateSessionRequest_members /* .members */
22544},
22545/* ActivateSessionResponse */
22546{
22547 UA_TYPENAME("ActivateSessionResponse") /* .typeName */
22548 {0, UA_NODEIDTYPE_NUMERIC, {468LU}}, /* .typeId */
22549 {0, UA_NODEIDTYPE_NUMERIC, {470LU}}, /* .binaryEncodingId */
22550 sizeof(UA_ActivateSessionResponse), /* .memSize */
22551 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22552 false, /* .pointerFree */
22553 false, /* .overlayable */
22554 4, /* .membersSize */
22555 ActivateSessionResponse_members /* .members */
22556},
22557/* CloseSessionRequest */
22558{
22559 UA_TYPENAME("CloseSessionRequest") /* .typeName */
22560 {0, UA_NODEIDTYPE_NUMERIC, {471LU}}, /* .typeId */
22561 {0, UA_NODEIDTYPE_NUMERIC, {473LU}}, /* .binaryEncodingId */
22562 sizeof(UA_CloseSessionRequest), /* .memSize */
22563 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22564 false, /* .pointerFree */
22565 false, /* .overlayable */
22566 2, /* .membersSize */
22567 CloseSessionRequest_members /* .members */
22568},
22569/* CloseSessionResponse */
22570{
22571 UA_TYPENAME("CloseSessionResponse") /* .typeName */
22572 {0, UA_NODEIDTYPE_NUMERIC, {474LU}}, /* .typeId */
22573 {0, UA_NODEIDTYPE_NUMERIC, {476LU}}, /* .binaryEncodingId */
22574 sizeof(UA_CloseSessionResponse), /* .memSize */
22575 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22576 false, /* .pointerFree */
22577 false, /* .overlayable */
22578 1, /* .membersSize */
22579 CloseSessionResponse_members /* .members */
22580},
22581/* CancelRequest */
22582{
22583 UA_TYPENAME("CancelRequest") /* .typeName */
22584 {0, UA_NODEIDTYPE_NUMERIC, {477LU}}, /* .typeId */
22585 {0, UA_NODEIDTYPE_NUMERIC, {479LU}}, /* .binaryEncodingId */
22586 sizeof(UA_CancelRequest), /* .memSize */
22587 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22588 false, /* .pointerFree */
22589 false, /* .overlayable */
22590 2, /* .membersSize */
22591 CancelRequest_members /* .members */
22592},
22593/* CancelResponse */
22594{
22595 UA_TYPENAME("CancelResponse") /* .typeName */
22596 {0, UA_NODEIDTYPE_NUMERIC, {480LU}}, /* .typeId */
22597 {0, UA_NODEIDTYPE_NUMERIC, {482LU}}, /* .binaryEncodingId */
22598 sizeof(UA_CancelResponse), /* .memSize */
22599 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22600 false, /* .pointerFree */
22601 false, /* .overlayable */
22602 2, /* .membersSize */
22603 CancelResponse_members /* .members */
22604},
22605/* NodeAttributesMask */
22606{
22607 UA_TYPENAME("NodeAttributesMask") /* .typeName */
22608 {0, UA_NODEIDTYPE_NUMERIC, {348LU}}, /* .typeId */
22609 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22610 sizeof(UA_NodeAttributesMask), /* .memSize */
22611 UA_DATATYPEKIND_ENUM, /* .typeKind */
22612 true, /* .pointerFree */
22613 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
22614 0, /* .membersSize */
22615 NodeAttributesMask_members /* .members */
22616},
22617/* NodeAttributes */
22618{
22619 UA_TYPENAME("NodeAttributes") /* .typeName */
22620 {0, UA_NODEIDTYPE_NUMERIC, {349LU}}, /* .typeId */
22621 {0, UA_NODEIDTYPE_NUMERIC, {351LU}}, /* .binaryEncodingId */
22622 sizeof(UA_NodeAttributes), /* .memSize */
22623 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22624 false, /* .pointerFree */
22625 false, /* .overlayable */
22626 5, /* .membersSize */
22627 NodeAttributes_members /* .members */
22628},
22629/* ObjectAttributes */
22630{
22631 UA_TYPENAME("ObjectAttributes") /* .typeName */
22632 {0, UA_NODEIDTYPE_NUMERIC, {352LU}}, /* .typeId */
22633 {0, UA_NODEIDTYPE_NUMERIC, {354LU}}, /* .binaryEncodingId */
22634 sizeof(UA_ObjectAttributes), /* .memSize */
22635 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22636 false, /* .pointerFree */
22637 false, /* .overlayable */
22638 6, /* .membersSize */
22639 ObjectAttributes_members /* .members */
22640},
22641/* VariableAttributes */
22642{
22643 UA_TYPENAME("VariableAttributes") /* .typeName */
22644 {0, UA_NODEIDTYPE_NUMERIC, {355LU}}, /* .typeId */
22645 {0, UA_NODEIDTYPE_NUMERIC, {357LU}}, /* .binaryEncodingId */
22646 sizeof(UA_VariableAttributes), /* .memSize */
22647 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22648 false, /* .pointerFree */
22649 false, /* .overlayable */
22650 13, /* .membersSize */
22651 VariableAttributes_members /* .members */
22652},
22653/* MethodAttributes */
22654{
22655 UA_TYPENAME("MethodAttributes") /* .typeName */
22656 {0, UA_NODEIDTYPE_NUMERIC, {358LU}}, /* .typeId */
22657 {0, UA_NODEIDTYPE_NUMERIC, {360LU}}, /* .binaryEncodingId */
22658 sizeof(UA_MethodAttributes), /* .memSize */
22659 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22660 false, /* .pointerFree */
22661 false, /* .overlayable */
22662 7, /* .membersSize */
22663 MethodAttributes_members /* .members */
22664},
22665/* ObjectTypeAttributes */
22666{
22667 UA_TYPENAME("ObjectTypeAttributes") /* .typeName */
22668 {0, UA_NODEIDTYPE_NUMERIC, {361LU}}, /* .typeId */
22669 {0, UA_NODEIDTYPE_NUMERIC, {363LU}}, /* .binaryEncodingId */
22670 sizeof(UA_ObjectTypeAttributes), /* .memSize */
22671 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22672 false, /* .pointerFree */
22673 false, /* .overlayable */
22674 6, /* .membersSize */
22675 ObjectTypeAttributes_members /* .members */
22676},
22677/* VariableTypeAttributes */
22678{
22679 UA_TYPENAME("VariableTypeAttributes") /* .typeName */
22680 {0, UA_NODEIDTYPE_NUMERIC, {364LU}}, /* .typeId */
22681 {0, UA_NODEIDTYPE_NUMERIC, {366LU}}, /* .binaryEncodingId */
22682 sizeof(UA_VariableTypeAttributes), /* .memSize */
22683 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22684 false, /* .pointerFree */
22685 false, /* .overlayable */
22686 10, /* .membersSize */
22687 VariableTypeAttributes_members /* .members */
22688},
22689/* ReferenceTypeAttributes */
22690{
22691 UA_TYPENAME("ReferenceTypeAttributes") /* .typeName */
22692 {0, UA_NODEIDTYPE_NUMERIC, {367LU}}, /* .typeId */
22693 {0, UA_NODEIDTYPE_NUMERIC, {369LU}}, /* .binaryEncodingId */
22694 sizeof(UA_ReferenceTypeAttributes), /* .memSize */
22695 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22696 false, /* .pointerFree */
22697 false, /* .overlayable */
22698 8, /* .membersSize */
22699 ReferenceTypeAttributes_members /* .members */
22700},
22701/* DataTypeAttributes */
22702{
22703 UA_TYPENAME("DataTypeAttributes") /* .typeName */
22704 {0, UA_NODEIDTYPE_NUMERIC, {370LU}}, /* .typeId */
22705 {0, UA_NODEIDTYPE_NUMERIC, {372LU}}, /* .binaryEncodingId */
22706 sizeof(UA_DataTypeAttributes), /* .memSize */
22707 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22708 false, /* .pointerFree */
22709 false, /* .overlayable */
22710 6, /* .membersSize */
22711 DataTypeAttributes_members /* .members */
22712},
22713/* ViewAttributes */
22714{
22715 UA_TYPENAME("ViewAttributes") /* .typeName */
22716 {0, UA_NODEIDTYPE_NUMERIC, {373LU}}, /* .typeId */
22717 {0, UA_NODEIDTYPE_NUMERIC, {375LU}}, /* .binaryEncodingId */
22718 sizeof(UA_ViewAttributes), /* .memSize */
22719 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22720 false, /* .pointerFree */
22721 false, /* .overlayable */
22722 7, /* .membersSize */
22723 ViewAttributes_members /* .members */
22724},
22725/* GenericAttributeValue */
22726{
22727 UA_TYPENAME("GenericAttributeValue") /* .typeName */
22728 {0, UA_NODEIDTYPE_NUMERIC, {17606LU}}, /* .typeId */
22729 {0, UA_NODEIDTYPE_NUMERIC, {17610LU}}, /* .binaryEncodingId */
22730 sizeof(UA_GenericAttributeValue), /* .memSize */
22731 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22732 false, /* .pointerFree */
22733 false, /* .overlayable */
22734 2, /* .membersSize */
22735 GenericAttributeValue_members /* .members */
22736},
22737/* GenericAttributes */
22738{
22739 UA_TYPENAME("GenericAttributes") /* .typeName */
22740 {0, UA_NODEIDTYPE_NUMERIC, {17607LU}}, /* .typeId */
22741 {0, UA_NODEIDTYPE_NUMERIC, {17611LU}}, /* .binaryEncodingId */
22742 sizeof(UA_GenericAttributes), /* .memSize */
22743 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22744 false, /* .pointerFree */
22745 false, /* .overlayable */
22746 6, /* .membersSize */
22747 GenericAttributes_members /* .members */
22748},
22749/* AddNodesItem */
22750{
22751 UA_TYPENAME("AddNodesItem") /* .typeName */
22752 {0, UA_NODEIDTYPE_NUMERIC, {376LU}}, /* .typeId */
22753 {0, UA_NODEIDTYPE_NUMERIC, {378LU}}, /* .binaryEncodingId */
22754 sizeof(UA_AddNodesItem), /* .memSize */
22755 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22756 false, /* .pointerFree */
22757 false, /* .overlayable */
22758 7, /* .membersSize */
22759 AddNodesItem_members /* .members */
22760},
22761/* AddNodesResult */
22762{
22763 UA_TYPENAME("AddNodesResult") /* .typeName */
22764 {0, UA_NODEIDTYPE_NUMERIC, {483LU}}, /* .typeId */
22765 {0, UA_NODEIDTYPE_NUMERIC, {485LU}}, /* .binaryEncodingId */
22766 sizeof(UA_AddNodesResult), /* .memSize */
22767 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22768 false, /* .pointerFree */
22769 false, /* .overlayable */
22770 2, /* .membersSize */
22771 AddNodesResult_members /* .members */
22772},
22773/* AddNodesRequest */
22774{
22775 UA_TYPENAME("AddNodesRequest") /* .typeName */
22776 {0, UA_NODEIDTYPE_NUMERIC, {486LU}}, /* .typeId */
22777 {0, UA_NODEIDTYPE_NUMERIC, {488LU}}, /* .binaryEncodingId */
22778 sizeof(UA_AddNodesRequest), /* .memSize */
22779 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22780 false, /* .pointerFree */
22781 false, /* .overlayable */
22782 2, /* .membersSize */
22783 AddNodesRequest_members /* .members */
22784},
22785/* AddNodesResponse */
22786{
22787 UA_TYPENAME("AddNodesResponse") /* .typeName */
22788 {0, UA_NODEIDTYPE_NUMERIC, {489LU}}, /* .typeId */
22789 {0, UA_NODEIDTYPE_NUMERIC, {491LU}}, /* .binaryEncodingId */
22790 sizeof(UA_AddNodesResponse), /* .memSize */
22791 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22792 false, /* .pointerFree */
22793 false, /* .overlayable */
22794 3, /* .membersSize */
22795 AddNodesResponse_members /* .members */
22796},
22797/* AddReferencesItem */
22798{
22799 UA_TYPENAME("AddReferencesItem") /* .typeName */
22800 {0, UA_NODEIDTYPE_NUMERIC, {379LU}}, /* .typeId */
22801 {0, UA_NODEIDTYPE_NUMERIC, {381LU}}, /* .binaryEncodingId */
22802 sizeof(UA_AddReferencesItem), /* .memSize */
22803 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22804 false, /* .pointerFree */
22805 false, /* .overlayable */
22806 6, /* .membersSize */
22807 AddReferencesItem_members /* .members */
22808},
22809/* AddReferencesRequest */
22810{
22811 UA_TYPENAME("AddReferencesRequest") /* .typeName */
22812 {0, UA_NODEIDTYPE_NUMERIC, {492LU}}, /* .typeId */
22813 {0, UA_NODEIDTYPE_NUMERIC, {494LU}}, /* .binaryEncodingId */
22814 sizeof(UA_AddReferencesRequest), /* .memSize */
22815 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22816 false, /* .pointerFree */
22817 false, /* .overlayable */
22818 2, /* .membersSize */
22819 AddReferencesRequest_members /* .members */
22820},
22821/* AddReferencesResponse */
22822{
22823 UA_TYPENAME("AddReferencesResponse") /* .typeName */
22824 {0, UA_NODEIDTYPE_NUMERIC, {495LU}}, /* .typeId */
22825 {0, UA_NODEIDTYPE_NUMERIC, {497LU}}, /* .binaryEncodingId */
22826 sizeof(UA_AddReferencesResponse), /* .memSize */
22827 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22828 false, /* .pointerFree */
22829 false, /* .overlayable */
22830 3, /* .membersSize */
22831 AddReferencesResponse_members /* .members */
22832},
22833/* DeleteNodesItem */
22834{
22835 UA_TYPENAME("DeleteNodesItem") /* .typeName */
22836 {0, UA_NODEIDTYPE_NUMERIC, {382LU}}, /* .typeId */
22837 {0, UA_NODEIDTYPE_NUMERIC, {384LU}}, /* .binaryEncodingId */
22838 sizeof(UA_DeleteNodesItem), /* .memSize */
22839 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22840 false, /* .pointerFree */
22841 false, /* .overlayable */
22842 2, /* .membersSize */
22843 DeleteNodesItem_members /* .members */
22844},
22845/* DeleteNodesRequest */
22846{
22847 UA_TYPENAME("DeleteNodesRequest") /* .typeName */
22848 {0, UA_NODEIDTYPE_NUMERIC, {498LU}}, /* .typeId */
22849 {0, UA_NODEIDTYPE_NUMERIC, {500LU}}, /* .binaryEncodingId */
22850 sizeof(UA_DeleteNodesRequest), /* .memSize */
22851 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22852 false, /* .pointerFree */
22853 false, /* .overlayable */
22854 2, /* .membersSize */
22855 DeleteNodesRequest_members /* .members */
22856},
22857/* DeleteNodesResponse */
22858{
22859 UA_TYPENAME("DeleteNodesResponse") /* .typeName */
22860 {0, UA_NODEIDTYPE_NUMERIC, {501LU}}, /* .typeId */
22861 {0, UA_NODEIDTYPE_NUMERIC, {503LU}}, /* .binaryEncodingId */
22862 sizeof(UA_DeleteNodesResponse), /* .memSize */
22863 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22864 false, /* .pointerFree */
22865 false, /* .overlayable */
22866 3, /* .membersSize */
22867 DeleteNodesResponse_members /* .members */
22868},
22869/* DeleteReferencesItem */
22870{
22871 UA_TYPENAME("DeleteReferencesItem") /* .typeName */
22872 {0, UA_NODEIDTYPE_NUMERIC, {385LU}}, /* .typeId */
22873 {0, UA_NODEIDTYPE_NUMERIC, {387LU}}, /* .binaryEncodingId */
22874 sizeof(UA_DeleteReferencesItem), /* .memSize */
22875 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22876 false, /* .pointerFree */
22877 false, /* .overlayable */
22878 5, /* .membersSize */
22879 DeleteReferencesItem_members /* .members */
22880},
22881/* DeleteReferencesRequest */
22882{
22883 UA_TYPENAME("DeleteReferencesRequest") /* .typeName */
22884 {0, UA_NODEIDTYPE_NUMERIC, {504LU}}, /* .typeId */
22885 {0, UA_NODEIDTYPE_NUMERIC, {506LU}}, /* .binaryEncodingId */
22886 sizeof(UA_DeleteReferencesRequest), /* .memSize */
22887 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22888 false, /* .pointerFree */
22889 false, /* .overlayable */
22890 2, /* .membersSize */
22891 DeleteReferencesRequest_members /* .members */
22892},
22893/* DeleteReferencesResponse */
22894{
22895 UA_TYPENAME("DeleteReferencesResponse") /* .typeName */
22896 {0, UA_NODEIDTYPE_NUMERIC, {507LU}}, /* .typeId */
22897 {0, UA_NODEIDTYPE_NUMERIC, {509LU}}, /* .binaryEncodingId */
22898 sizeof(UA_DeleteReferencesResponse), /* .memSize */
22899 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22900 false, /* .pointerFree */
22901 false, /* .overlayable */
22902 3, /* .membersSize */
22903 DeleteReferencesResponse_members /* .members */
22904},
22905/* AttributeWriteMask */
22906{
22907 UA_TYPENAME("AttributeWriteMask") /* .typeName */
22908 {0, UA_NODEIDTYPE_NUMERIC, {347LU}}, /* .typeId */
22909 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22910 sizeof(UA_AttributeWriteMask), /* .memSize */
22911 UA_DATATYPEKIND_UINT32, /* .typeKind */
22912 true, /* .pointerFree */
22913 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
22914 0, /* .membersSize */
22915 AttributeWriteMask_members /* .members */
22916},
22917/* BrowseDirection */
22918{
22919 UA_TYPENAME("BrowseDirection") /* .typeName */
22920 {0, UA_NODEIDTYPE_NUMERIC, {510LU}}, /* .typeId */
22921 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22922 sizeof(UA_BrowseDirection), /* .memSize */
22923 UA_DATATYPEKIND_ENUM, /* .typeKind */
22924 true, /* .pointerFree */
22925 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
22926 0, /* .membersSize */
22927 BrowseDirection_members /* .members */
22928},
22929/* ViewDescription */
22930{
22931 UA_TYPENAME("ViewDescription") /* .typeName */
22932 {0, UA_NODEIDTYPE_NUMERIC, {511LU}}, /* .typeId */
22933 {0, UA_NODEIDTYPE_NUMERIC, {513LU}}, /* .binaryEncodingId */
22934 sizeof(UA_ViewDescription), /* .memSize */
22935 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22936 false, /* .pointerFree */
22937 false, /* .overlayable */
22938 3, /* .membersSize */
22939 ViewDescription_members /* .members */
22940},
22941/* BrowseDescription */
22942{
22943 UA_TYPENAME("BrowseDescription") /* .typeName */
22944 {0, UA_NODEIDTYPE_NUMERIC, {514LU}}, /* .typeId */
22945 {0, UA_NODEIDTYPE_NUMERIC, {516LU}}, /* .binaryEncodingId */
22946 sizeof(UA_BrowseDescription), /* .memSize */
22947 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22948 false, /* .pointerFree */
22949 false, /* .overlayable */
22950 6, /* .membersSize */
22951 BrowseDescription_members /* .members */
22952},
22953/* BrowseResultMask */
22954{
22955 UA_TYPENAME("BrowseResultMask") /* .typeName */
22956 {0, UA_NODEIDTYPE_NUMERIC, {517LU}}, /* .typeId */
22957 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22958 sizeof(UA_BrowseResultMask), /* .memSize */
22959 UA_DATATYPEKIND_ENUM, /* .typeKind */
22960 true, /* .pointerFree */
22961 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
22962 0, /* .membersSize */
22963 BrowseResultMask_members /* .members */
22964},
22965/* ReferenceDescription */
22966{
22967 UA_TYPENAME("ReferenceDescription") /* .typeName */
22968 {0, UA_NODEIDTYPE_NUMERIC, {518LU}}, /* .typeId */
22969 {0, UA_NODEIDTYPE_NUMERIC, {520LU}}, /* .binaryEncodingId */
22970 sizeof(UA_ReferenceDescription), /* .memSize */
22971 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22972 false, /* .pointerFree */
22973 false, /* .overlayable */
22974 7, /* .membersSize */
22975 ReferenceDescription_members /* .members */
22976},
22977/* ContinuationPoint */
22978{
22979 UA_TYPENAME("ContinuationPoint") /* .typeName */
22980 {0, UA_NODEIDTYPE_NUMERIC, {521LU}}, /* .typeId */
22981 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
22982 sizeof(UA_ContinuationPoint), /* .memSize */
22983 UA_DATATYPEKIND_BYTESTRING, /* .typeKind */
22984 false, /* .pointerFree */
22985 false, /* .overlayable */
22986 0, /* .membersSize */
22987 ContinuationPoint_members /* .members */
22988},
22989/* BrowseResult */
22990{
22991 UA_TYPENAME("BrowseResult") /* .typeName */
22992 {0, UA_NODEIDTYPE_NUMERIC, {522LU}}, /* .typeId */
22993 {0, UA_NODEIDTYPE_NUMERIC, {524LU}}, /* .binaryEncodingId */
22994 sizeof(UA_BrowseResult), /* .memSize */
22995 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
22996 false, /* .pointerFree */
22997 false, /* .overlayable */
22998 3, /* .membersSize */
22999 BrowseResult_members /* .members */
23000},
23001/* BrowseRequest */
23002{
23003 UA_TYPENAME("BrowseRequest") /* .typeName */
23004 {0, UA_NODEIDTYPE_NUMERIC, {525LU}}, /* .typeId */
23005 {0, UA_NODEIDTYPE_NUMERIC, {527LU}}, /* .binaryEncodingId */
23006 sizeof(UA_BrowseRequest), /* .memSize */
23007 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23008 false, /* .pointerFree */
23009 false, /* .overlayable */
23010 4, /* .membersSize */
23011 BrowseRequest_members /* .members */
23012},
23013/* BrowseResponse */
23014{
23015 UA_TYPENAME("BrowseResponse") /* .typeName */
23016 {0, UA_NODEIDTYPE_NUMERIC, {528LU}}, /* .typeId */
23017 {0, UA_NODEIDTYPE_NUMERIC, {530LU}}, /* .binaryEncodingId */
23018 sizeof(UA_BrowseResponse), /* .memSize */
23019 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23020 false, /* .pointerFree */
23021 false, /* .overlayable */
23022 3, /* .membersSize */
23023 BrowseResponse_members /* .members */
23024},
23025/* BrowseNextRequest */
23026{
23027 UA_TYPENAME("BrowseNextRequest") /* .typeName */
23028 {0, UA_NODEIDTYPE_NUMERIC, {531LU}}, /* .typeId */
23029 {0, UA_NODEIDTYPE_NUMERIC, {533LU}}, /* .binaryEncodingId */
23030 sizeof(UA_BrowseNextRequest), /* .memSize */
23031 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23032 false, /* .pointerFree */
23033 false, /* .overlayable */
23034 3, /* .membersSize */
23035 BrowseNextRequest_members /* .members */
23036},
23037/* BrowseNextResponse */
23038{
23039 UA_TYPENAME("BrowseNextResponse") /* .typeName */
23040 {0, UA_NODEIDTYPE_NUMERIC, {534LU}}, /* .typeId */
23041 {0, UA_NODEIDTYPE_NUMERIC, {536LU}}, /* .binaryEncodingId */
23042 sizeof(UA_BrowseNextResponse), /* .memSize */
23043 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23044 false, /* .pointerFree */
23045 false, /* .overlayable */
23046 3, /* .membersSize */
23047 BrowseNextResponse_members /* .members */
23048},
23049/* RelativePathElement */
23050{
23051 UA_TYPENAME("RelativePathElement") /* .typeName */
23052 {0, UA_NODEIDTYPE_NUMERIC, {537LU}}, /* .typeId */
23053 {0, UA_NODEIDTYPE_NUMERIC, {539LU}}, /* .binaryEncodingId */
23054 sizeof(UA_RelativePathElement), /* .memSize */
23055 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23056 false, /* .pointerFree */
23057 false, /* .overlayable */
23058 4, /* .membersSize */
23059 RelativePathElement_members /* .members */
23060},
23061/* RelativePath */
23062{
23063 UA_TYPENAME("RelativePath") /* .typeName */
23064 {0, UA_NODEIDTYPE_NUMERIC, {540LU}}, /* .typeId */
23065 {0, UA_NODEIDTYPE_NUMERIC, {542LU}}, /* .binaryEncodingId */
23066 sizeof(UA_RelativePath), /* .memSize */
23067 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23068 false, /* .pointerFree */
23069 false, /* .overlayable */
23070 1, /* .membersSize */
23071 RelativePath_members /* .members */
23072},
23073/* BrowsePath */
23074{
23075 UA_TYPENAME("BrowsePath") /* .typeName */
23076 {0, UA_NODEIDTYPE_NUMERIC, {543LU}}, /* .typeId */
23077 {0, UA_NODEIDTYPE_NUMERIC, {545LU}}, /* .binaryEncodingId */
23078 sizeof(UA_BrowsePath), /* .memSize */
23079 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23080 false, /* .pointerFree */
23081 false, /* .overlayable */
23082 2, /* .membersSize */
23083 BrowsePath_members /* .members */
23084},
23085/* BrowsePathTarget */
23086{
23087 UA_TYPENAME("BrowsePathTarget") /* .typeName */
23088 {0, UA_NODEIDTYPE_NUMERIC, {546LU}}, /* .typeId */
23089 {0, UA_NODEIDTYPE_NUMERIC, {548LU}}, /* .binaryEncodingId */
23090 sizeof(UA_BrowsePathTarget), /* .memSize */
23091 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23092 false, /* .pointerFree */
23093 false, /* .overlayable */
23094 2, /* .membersSize */
23095 BrowsePathTarget_members /* .members */
23096},
23097/* BrowsePathResult */
23098{
23099 UA_TYPENAME("BrowsePathResult") /* .typeName */
23100 {0, UA_NODEIDTYPE_NUMERIC, {549LU}}, /* .typeId */
23101 {0, UA_NODEIDTYPE_NUMERIC, {551LU}}, /* .binaryEncodingId */
23102 sizeof(UA_BrowsePathResult), /* .memSize */
23103 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23104 false, /* .pointerFree */
23105 false, /* .overlayable */
23106 2, /* .membersSize */
23107 BrowsePathResult_members /* .members */
23108},
23109/* TranslateBrowsePathsToNodeIdsRequest */
23110{
23111 UA_TYPENAME("TranslateBrowsePathsToNodeIdsRequest") /* .typeName */
23112 {0, UA_NODEIDTYPE_NUMERIC, {552LU}}, /* .typeId */
23113 {0, UA_NODEIDTYPE_NUMERIC, {554LU}}, /* .binaryEncodingId */
23114 sizeof(UA_TranslateBrowsePathsToNodeIdsRequest), /* .memSize */
23115 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23116 false, /* .pointerFree */
23117 false, /* .overlayable */
23118 2, /* .membersSize */
23119 TranslateBrowsePathsToNodeIdsRequest_members /* .members */
23120},
23121/* TranslateBrowsePathsToNodeIdsResponse */
23122{
23123 UA_TYPENAME("TranslateBrowsePathsToNodeIdsResponse") /* .typeName */
23124 {0, UA_NODEIDTYPE_NUMERIC, {555LU}}, /* .typeId */
23125 {0, UA_NODEIDTYPE_NUMERIC, {557LU}}, /* .binaryEncodingId */
23126 sizeof(UA_TranslateBrowsePathsToNodeIdsResponse), /* .memSize */
23127 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23128 false, /* .pointerFree */
23129 false, /* .overlayable */
23130 3, /* .membersSize */
23131 TranslateBrowsePathsToNodeIdsResponse_members /* .members */
23132},
23133/* RegisterNodesRequest */
23134{
23135 UA_TYPENAME("RegisterNodesRequest") /* .typeName */
23136 {0, UA_NODEIDTYPE_NUMERIC, {558LU}}, /* .typeId */
23137 {0, UA_NODEIDTYPE_NUMERIC, {560LU}}, /* .binaryEncodingId */
23138 sizeof(UA_RegisterNodesRequest), /* .memSize */
23139 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23140 false, /* .pointerFree */
23141 false, /* .overlayable */
23142 2, /* .membersSize */
23143 RegisterNodesRequest_members /* .members */
23144},
23145/* RegisterNodesResponse */
23146{
23147 UA_TYPENAME("RegisterNodesResponse") /* .typeName */
23148 {0, UA_NODEIDTYPE_NUMERIC, {561LU}}, /* .typeId */
23149 {0, UA_NODEIDTYPE_NUMERIC, {563LU}}, /* .binaryEncodingId */
23150 sizeof(UA_RegisterNodesResponse), /* .memSize */
23151 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23152 false, /* .pointerFree */
23153 false, /* .overlayable */
23154 2, /* .membersSize */
23155 RegisterNodesResponse_members /* .members */
23156},
23157/* UnregisterNodesRequest */
23158{
23159 UA_TYPENAME("UnregisterNodesRequest") /* .typeName */
23160 {0, UA_NODEIDTYPE_NUMERIC, {564LU}}, /* .typeId */
23161 {0, UA_NODEIDTYPE_NUMERIC, {566LU}}, /* .binaryEncodingId */
23162 sizeof(UA_UnregisterNodesRequest), /* .memSize */
23163 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23164 false, /* .pointerFree */
23165 false, /* .overlayable */
23166 2, /* .membersSize */
23167 UnregisterNodesRequest_members /* .members */
23168},
23169/* UnregisterNodesResponse */
23170{
23171 UA_TYPENAME("UnregisterNodesResponse") /* .typeName */
23172 {0, UA_NODEIDTYPE_NUMERIC, {567LU}}, /* .typeId */
23173 {0, UA_NODEIDTYPE_NUMERIC, {569LU}}, /* .binaryEncodingId */
23174 sizeof(UA_UnregisterNodesResponse), /* .memSize */
23175 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23176 false, /* .pointerFree */
23177 false, /* .overlayable */
23178 1, /* .membersSize */
23179 UnregisterNodesResponse_members /* .members */
23180},
23181/* Counter */
23182{
23183 UA_TYPENAME("Counter") /* .typeName */
23184 {0, UA_NODEIDTYPE_NUMERIC, {289LU}}, /* .typeId */
23185 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
23186 sizeof(UA_Counter), /* .memSize */
23187 UA_DATATYPEKIND_UINT32, /* .typeKind */
23188 false, /* .pointerFree */
23189 false, /* .overlayable */
23190 0, /* .membersSize */
23191 Counter_members /* .members */
23192},
23193/* OpaqueNumericRange */
23194{
23195 UA_TYPENAME("OpaqueNumericRange") /* .typeName */
23196 {0, UA_NODEIDTYPE_NUMERIC, {291LU}}, /* .typeId */
23197 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
23198 sizeof(UA_OpaqueNumericRange), /* .memSize */
23199 UA_DATATYPEKIND_STRING, /* .typeKind */
23200 false, /* .pointerFree */
23201 false, /* .overlayable */
23202 0, /* .membersSize */
23203 OpaqueNumericRange_members /* .members */
23204},
23205/* EndpointConfiguration */
23206{
23207 UA_TYPENAME("EndpointConfiguration") /* .typeName */
23208 {0, UA_NODEIDTYPE_NUMERIC, {331LU}}, /* .typeId */
23209 {0, UA_NODEIDTYPE_NUMERIC, {333LU}}, /* .binaryEncodingId */
23210 sizeof(UA_EndpointConfiguration), /* .memSize */
23211 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23212 true, /* .pointerFree */
23213 false, /* .overlayable */
23214 9, /* .membersSize */
23215 EndpointConfiguration_members /* .members */
23216},
23217/* QueryDataDescription */
23218{
23219 UA_TYPENAME("QueryDataDescription") /* .typeName */
23220 {0, UA_NODEIDTYPE_NUMERIC, {570LU}}, /* .typeId */
23221 {0, UA_NODEIDTYPE_NUMERIC, {572LU}}, /* .binaryEncodingId */
23222 sizeof(UA_QueryDataDescription), /* .memSize */
23223 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23224 false, /* .pointerFree */
23225 false, /* .overlayable */
23226 3, /* .membersSize */
23227 QueryDataDescription_members /* .members */
23228},
23229/* NodeTypeDescription */
23230{
23231 UA_TYPENAME("NodeTypeDescription") /* .typeName */
23232 {0, UA_NODEIDTYPE_NUMERIC, {573LU}}, /* .typeId */
23233 {0, UA_NODEIDTYPE_NUMERIC, {575LU}}, /* .binaryEncodingId */
23234 sizeof(UA_NodeTypeDescription), /* .memSize */
23235 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23236 false, /* .pointerFree */
23237 false, /* .overlayable */
23238 3, /* .membersSize */
23239 NodeTypeDescription_members /* .members */
23240},
23241/* FilterOperator */
23242{
23243 UA_TYPENAME("FilterOperator") /* .typeName */
23244 {0, UA_NODEIDTYPE_NUMERIC, {576LU}}, /* .typeId */
23245 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
23246 sizeof(UA_FilterOperator), /* .memSize */
23247 UA_DATATYPEKIND_ENUM, /* .typeKind */
23248 true, /* .pointerFree */
23249 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
23250 0, /* .membersSize */
23251 FilterOperator_members /* .members */
23252},
23253/* QueryDataSet */
23254{
23255 UA_TYPENAME("QueryDataSet") /* .typeName */
23256 {0, UA_NODEIDTYPE_NUMERIC, {577LU}}, /* .typeId */
23257 {0, UA_NODEIDTYPE_NUMERIC, {579LU}}, /* .binaryEncodingId */
23258 sizeof(UA_QueryDataSet), /* .memSize */
23259 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23260 false, /* .pointerFree */
23261 false, /* .overlayable */
23262 3, /* .membersSize */
23263 QueryDataSet_members /* .members */
23264},
23265/* NodeReference */
23266{
23267 UA_TYPENAME("NodeReference") /* .typeName */
23268 {0, UA_NODEIDTYPE_NUMERIC, {580LU}}, /* .typeId */
23269 {0, UA_NODEIDTYPE_NUMERIC, {582LU}}, /* .binaryEncodingId */
23270 sizeof(UA_NodeReference), /* .memSize */
23271 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23272 false, /* .pointerFree */
23273 false, /* .overlayable */
23274 4, /* .membersSize */
23275 NodeReference_members /* .members */
23276},
23277/* ContentFilterElement */
23278{
23279 UA_TYPENAME("ContentFilterElement") /* .typeName */
23280 {0, UA_NODEIDTYPE_NUMERIC, {583LU}}, /* .typeId */
23281 {0, UA_NODEIDTYPE_NUMERIC, {585LU}}, /* .binaryEncodingId */
23282 sizeof(UA_ContentFilterElement), /* .memSize */
23283 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23284 false, /* .pointerFree */
23285 false, /* .overlayable */
23286 2, /* .membersSize */
23287 ContentFilterElement_members /* .members */
23288},
23289/* ContentFilter */
23290{
23291 UA_TYPENAME("ContentFilter") /* .typeName */
23292 {0, UA_NODEIDTYPE_NUMERIC, {586LU}}, /* .typeId */
23293 {0, UA_NODEIDTYPE_NUMERIC, {588LU}}, /* .binaryEncodingId */
23294 sizeof(UA_ContentFilter), /* .memSize */
23295 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23296 false, /* .pointerFree */
23297 false, /* .overlayable */
23298 1, /* .membersSize */
23299 ContentFilter_members /* .members */
23300},
23301/* ElementOperand */
23302{
23303 UA_TYPENAME("ElementOperand") /* .typeName */
23304 {0, UA_NODEIDTYPE_NUMERIC, {592LU}}, /* .typeId */
23305 {0, UA_NODEIDTYPE_NUMERIC, {594LU}}, /* .binaryEncodingId */
23306 sizeof(UA_ElementOperand), /* .memSize */
23307 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23308 true, /* .pointerFree */
23309 false, /* .overlayable */
23310 1, /* .membersSize */
23311 ElementOperand_members /* .members */
23312},
23313/* LiteralOperand */
23314{
23315 UA_TYPENAME("LiteralOperand") /* .typeName */
23316 {0, UA_NODEIDTYPE_NUMERIC, {595LU}}, /* .typeId */
23317 {0, UA_NODEIDTYPE_NUMERIC, {597LU}}, /* .binaryEncodingId */
23318 sizeof(UA_LiteralOperand), /* .memSize */
23319 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23320 false, /* .pointerFree */
23321 false, /* .overlayable */
23322 1, /* .membersSize */
23323 LiteralOperand_members /* .members */
23324},
23325/* AttributeOperand */
23326{
23327 UA_TYPENAME("AttributeOperand") /* .typeName */
23328 {0, UA_NODEIDTYPE_NUMERIC, {598LU}}, /* .typeId */
23329 {0, UA_NODEIDTYPE_NUMERIC, {600LU}}, /* .binaryEncodingId */
23330 sizeof(UA_AttributeOperand), /* .memSize */
23331 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23332 false, /* .pointerFree */
23333 false, /* .overlayable */
23334 5, /* .membersSize */
23335 AttributeOperand_members /* .members */
23336},
23337/* SimpleAttributeOperand */
23338{
23339 UA_TYPENAME("SimpleAttributeOperand") /* .typeName */
23340 {0, UA_NODEIDTYPE_NUMERIC, {601LU}}, /* .typeId */
23341 {0, UA_NODEIDTYPE_NUMERIC, {603LU}}, /* .binaryEncodingId */
23342 sizeof(UA_SimpleAttributeOperand), /* .memSize */
23343 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23344 false, /* .pointerFree */
23345 false, /* .overlayable */
23346 4, /* .membersSize */
23347 SimpleAttributeOperand_members /* .members */
23348},
23349/* ContentFilterElementResult */
23350{
23351 UA_TYPENAME("ContentFilterElementResult") /* .typeName */
23352 {0, UA_NODEIDTYPE_NUMERIC, {604LU}}, /* .typeId */
23353 {0, UA_NODEIDTYPE_NUMERIC, {606LU}}, /* .binaryEncodingId */
23354 sizeof(UA_ContentFilterElementResult), /* .memSize */
23355 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23356 false, /* .pointerFree */
23357 false, /* .overlayable */
23358 3, /* .membersSize */
23359 ContentFilterElementResult_members /* .members */
23360},
23361/* ContentFilterResult */
23362{
23363 UA_TYPENAME("ContentFilterResult") /* .typeName */
23364 {0, UA_NODEIDTYPE_NUMERIC, {607LU}}, /* .typeId */
23365 {0, UA_NODEIDTYPE_NUMERIC, {609LU}}, /* .binaryEncodingId */
23366 sizeof(UA_ContentFilterResult), /* .memSize */
23367 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23368 false, /* .pointerFree */
23369 false, /* .overlayable */
23370 2, /* .membersSize */
23371 ContentFilterResult_members /* .members */
23372},
23373/* ParsingResult */
23374{
23375 UA_TYPENAME("ParsingResult") /* .typeName */
23376 {0, UA_NODEIDTYPE_NUMERIC, {610LU}}, /* .typeId */
23377 {0, UA_NODEIDTYPE_NUMERIC, {612LU}}, /* .binaryEncodingId */
23378 sizeof(UA_ParsingResult), /* .memSize */
23379 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23380 false, /* .pointerFree */
23381 false, /* .overlayable */
23382 3, /* .membersSize */
23383 ParsingResult_members /* .members */
23384},
23385/* QueryFirstRequest */
23386{
23387 UA_TYPENAME("QueryFirstRequest") /* .typeName */
23388 {0, UA_NODEIDTYPE_NUMERIC, {613LU}}, /* .typeId */
23389 {0, UA_NODEIDTYPE_NUMERIC, {615LU}}, /* .binaryEncodingId */
23390 sizeof(UA_QueryFirstRequest), /* .memSize */
23391 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23392 false, /* .pointerFree */
23393 false, /* .overlayable */
23394 6, /* .membersSize */
23395 QueryFirstRequest_members /* .members */
23396},
23397/* QueryFirstResponse */
23398{
23399 UA_TYPENAME("QueryFirstResponse") /* .typeName */
23400 {0, UA_NODEIDTYPE_NUMERIC, {616LU}}, /* .typeId */
23401 {0, UA_NODEIDTYPE_NUMERIC, {618LU}}, /* .binaryEncodingId */
23402 sizeof(UA_QueryFirstResponse), /* .memSize */
23403 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23404 false, /* .pointerFree */
23405 false, /* .overlayable */
23406 6, /* .membersSize */
23407 QueryFirstResponse_members /* .members */
23408},
23409/* QueryNextRequest */
23410{
23411 UA_TYPENAME("QueryNextRequest") /* .typeName */
23412 {0, UA_NODEIDTYPE_NUMERIC, {619LU}}, /* .typeId */
23413 {0, UA_NODEIDTYPE_NUMERIC, {621LU}}, /* .binaryEncodingId */
23414 sizeof(UA_QueryNextRequest), /* .memSize */
23415 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23416 false, /* .pointerFree */
23417 false, /* .overlayable */
23418 3, /* .membersSize */
23419 QueryNextRequest_members /* .members */
23420},
23421/* QueryNextResponse */
23422{
23423 UA_TYPENAME("QueryNextResponse") /* .typeName */
23424 {0, UA_NODEIDTYPE_NUMERIC, {622LU}}, /* .typeId */
23425 {0, UA_NODEIDTYPE_NUMERIC, {624LU}}, /* .binaryEncodingId */
23426 sizeof(UA_QueryNextResponse), /* .memSize */
23427 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23428 false, /* .pointerFree */
23429 false, /* .overlayable */
23430 3, /* .membersSize */
23431 QueryNextResponse_members /* .members */
23432},
23433/* TimestampsToReturn */
23434{
23435 UA_TYPENAME("TimestampsToReturn") /* .typeName */
23436 {0, UA_NODEIDTYPE_NUMERIC, {625LU}}, /* .typeId */
23437 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
23438 sizeof(UA_TimestampsToReturn), /* .memSize */
23439 UA_DATATYPEKIND_ENUM, /* .typeKind */
23440 true, /* .pointerFree */
23441 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
23442 0, /* .membersSize */
23443 TimestampsToReturn_members /* .members */
23444},
23445/* ReadValueId */
23446{
23447 UA_TYPENAME("ReadValueId") /* .typeName */
23448 {0, UA_NODEIDTYPE_NUMERIC, {626LU}}, /* .typeId */
23449 {0, UA_NODEIDTYPE_NUMERIC, {628LU}}, /* .binaryEncodingId */
23450 sizeof(UA_ReadValueId), /* .memSize */
23451 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23452 false, /* .pointerFree */
23453 false, /* .overlayable */
23454 4, /* .membersSize */
23455 ReadValueId_members /* .members */
23456},
23457/* ReadRequest */
23458{
23459 UA_TYPENAME("ReadRequest") /* .typeName */
23460 {0, UA_NODEIDTYPE_NUMERIC, {629LU}}, /* .typeId */
23461 {0, UA_NODEIDTYPE_NUMERIC, {631LU}}, /* .binaryEncodingId */
23462 sizeof(UA_ReadRequest), /* .memSize */
23463 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23464 false, /* .pointerFree */
23465 false, /* .overlayable */
23466 4, /* .membersSize */
23467 ReadRequest_members /* .members */
23468},
23469/* ReadResponse */
23470{
23471 UA_TYPENAME("ReadResponse") /* .typeName */
23472 {0, UA_NODEIDTYPE_NUMERIC, {632LU}}, /* .typeId */
23473 {0, UA_NODEIDTYPE_NUMERIC, {634LU}}, /* .binaryEncodingId */
23474 sizeof(UA_ReadResponse), /* .memSize */
23475 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23476 false, /* .pointerFree */
23477 false, /* .overlayable */
23478 3, /* .membersSize */
23479 ReadResponse_members /* .members */
23480},
23481/* HistoryReadValueId */
23482{
23483 UA_TYPENAME("HistoryReadValueId") /* .typeName */
23484 {0, UA_NODEIDTYPE_NUMERIC, {635LU}}, /* .typeId */
23485 {0, UA_NODEIDTYPE_NUMERIC, {637LU}}, /* .binaryEncodingId */
23486 sizeof(UA_HistoryReadValueId), /* .memSize */
23487 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23488 false, /* .pointerFree */
23489 false, /* .overlayable */
23490 4, /* .membersSize */
23491 HistoryReadValueId_members /* .members */
23492},
23493/* HistoryReadResult */
23494{
23495 UA_TYPENAME("HistoryReadResult") /* .typeName */
23496 {0, UA_NODEIDTYPE_NUMERIC, {638LU}}, /* .typeId */
23497 {0, UA_NODEIDTYPE_NUMERIC, {640LU}}, /* .binaryEncodingId */
23498 sizeof(UA_HistoryReadResult), /* .memSize */
23499 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23500 false, /* .pointerFree */
23501 false, /* .overlayable */
23502 3, /* .membersSize */
23503 HistoryReadResult_members /* .members */
23504},
23505/* ReadRawModifiedDetails */
23506{
23507 UA_TYPENAME("ReadRawModifiedDetails") /* .typeName */
23508 {0, UA_NODEIDTYPE_NUMERIC, {647LU}}, /* .typeId */
23509 {0, UA_NODEIDTYPE_NUMERIC, {649LU}}, /* .binaryEncodingId */
23510 sizeof(UA_ReadRawModifiedDetails), /* .memSize */
23511 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23512 true, /* .pointerFree */
23513 false, /* .overlayable */
23514 5, /* .membersSize */
23515 ReadRawModifiedDetails_members /* .members */
23516},
23517/* ReadAtTimeDetails */
23518{
23519 UA_TYPENAME("ReadAtTimeDetails") /* .typeName */
23520 {0, UA_NODEIDTYPE_NUMERIC, {653LU}}, /* .typeId */
23521 {0, UA_NODEIDTYPE_NUMERIC, {655LU}}, /* .binaryEncodingId */
23522 sizeof(UA_ReadAtTimeDetails), /* .memSize */
23523 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23524 false, /* .pointerFree */
23525 false, /* .overlayable */
23526 2, /* .membersSize */
23527 ReadAtTimeDetails_members /* .members */
23528},
23529/* ReadAnnotationDataDetails */
23530{
23531 UA_TYPENAME("ReadAnnotationDataDetails") /* .typeName */
23532 {0, UA_NODEIDTYPE_NUMERIC, {23497LU}}, /* .typeId */
23533 {0, UA_NODEIDTYPE_NUMERIC, {23500LU}}, /* .binaryEncodingId */
23534 sizeof(UA_ReadAnnotationDataDetails), /* .memSize */
23535 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23536 false, /* .pointerFree */
23537 false, /* .overlayable */
23538 1, /* .membersSize */
23539 ReadAnnotationDataDetails_members /* .members */
23540},
23541/* HistoryData */
23542{
23543 UA_TYPENAME("HistoryData") /* .typeName */
23544 {0, UA_NODEIDTYPE_NUMERIC, {656LU}}, /* .typeId */
23545 {0, UA_NODEIDTYPE_NUMERIC, {658LU}}, /* .binaryEncodingId */
23546 sizeof(UA_HistoryData), /* .memSize */
23547 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23548 false, /* .pointerFree */
23549 false, /* .overlayable */
23550 1, /* .membersSize */
23551 HistoryData_members /* .members */
23552},
23553/* HistoryReadRequest */
23554{
23555 UA_TYPENAME("HistoryReadRequest") /* .typeName */
23556 {0, UA_NODEIDTYPE_NUMERIC, {662LU}}, /* .typeId */
23557 {0, UA_NODEIDTYPE_NUMERIC, {664LU}}, /* .binaryEncodingId */
23558 sizeof(UA_HistoryReadRequest), /* .memSize */
23559 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23560 false, /* .pointerFree */
23561 false, /* .overlayable */
23562 5, /* .membersSize */
23563 HistoryReadRequest_members /* .members */
23564},
23565/* HistoryReadResponse */
23566{
23567 UA_TYPENAME("HistoryReadResponse") /* .typeName */
23568 {0, UA_NODEIDTYPE_NUMERIC, {665LU}}, /* .typeId */
23569 {0, UA_NODEIDTYPE_NUMERIC, {667LU}}, /* .binaryEncodingId */
23570 sizeof(UA_HistoryReadResponse), /* .memSize */
23571 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23572 false, /* .pointerFree */
23573 false, /* .overlayable */
23574 3, /* .membersSize */
23575 HistoryReadResponse_members /* .members */
23576},
23577/* WriteValue */
23578{
23579 UA_TYPENAME("WriteValue") /* .typeName */
23580 {0, UA_NODEIDTYPE_NUMERIC, {668LU}}, /* .typeId */
23581 {0, UA_NODEIDTYPE_NUMERIC, {670LU}}, /* .binaryEncodingId */
23582 sizeof(UA_WriteValue), /* .memSize */
23583 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23584 false, /* .pointerFree */
23585 false, /* .overlayable */
23586 4, /* .membersSize */
23587 WriteValue_members /* .members */
23588},
23589/* WriteRequest */
23590{
23591 UA_TYPENAME("WriteRequest") /* .typeName */
23592 {0, UA_NODEIDTYPE_NUMERIC, {671LU}}, /* .typeId */
23593 {0, UA_NODEIDTYPE_NUMERIC, {673LU}}, /* .binaryEncodingId */
23594 sizeof(UA_WriteRequest), /* .memSize */
23595 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23596 false, /* .pointerFree */
23597 false, /* .overlayable */
23598 2, /* .membersSize */
23599 WriteRequest_members /* .members */
23600},
23601/* WriteResponse */
23602{
23603 UA_TYPENAME("WriteResponse") /* .typeName */
23604 {0, UA_NODEIDTYPE_NUMERIC, {674LU}}, /* .typeId */
23605 {0, UA_NODEIDTYPE_NUMERIC, {676LU}}, /* .binaryEncodingId */
23606 sizeof(UA_WriteResponse), /* .memSize */
23607 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23608 false, /* .pointerFree */
23609 false, /* .overlayable */
23610 3, /* .membersSize */
23611 WriteResponse_members /* .members */
23612},
23613/* HistoryUpdateDetails */
23614{
23615 UA_TYPENAME("HistoryUpdateDetails") /* .typeName */
23616 {0, UA_NODEIDTYPE_NUMERIC, {677LU}}, /* .typeId */
23617 {0, UA_NODEIDTYPE_NUMERIC, {679LU}}, /* .binaryEncodingId */
23618 sizeof(UA_HistoryUpdateDetails), /* .memSize */
23619 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23620 false, /* .pointerFree */
23621 false, /* .overlayable */
23622 1, /* .membersSize */
23623 HistoryUpdateDetails_members /* .members */
23624},
23625/* HistoryUpdateType */
23626{
23627 UA_TYPENAME("HistoryUpdateType") /* .typeName */
23628 {0, UA_NODEIDTYPE_NUMERIC, {11234LU}}, /* .typeId */
23629 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
23630 sizeof(UA_HistoryUpdateType), /* .memSize */
23631 UA_DATATYPEKIND_ENUM, /* .typeKind */
23632 true, /* .pointerFree */
23633 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
23634 0, /* .membersSize */
23635 HistoryUpdateType_members /* .members */
23636},
23637/* PerformUpdateType */
23638{
23639 UA_TYPENAME("PerformUpdateType") /* .typeName */
23640 {0, UA_NODEIDTYPE_NUMERIC, {11293LU}}, /* .typeId */
23641 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
23642 sizeof(UA_PerformUpdateType), /* .memSize */
23643 UA_DATATYPEKIND_ENUM, /* .typeKind */
23644 true, /* .pointerFree */
23645 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
23646 0, /* .membersSize */
23647 PerformUpdateType_members /* .members */
23648},
23649/* UpdateDataDetails */
23650{
23651 UA_TYPENAME("UpdateDataDetails") /* .typeName */
23652 {0, UA_NODEIDTYPE_NUMERIC, {680LU}}, /* .typeId */
23653 {0, UA_NODEIDTYPE_NUMERIC, {682LU}}, /* .binaryEncodingId */
23654 sizeof(UA_UpdateDataDetails), /* .memSize */
23655 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23656 false, /* .pointerFree */
23657 false, /* .overlayable */
23658 3, /* .membersSize */
23659 UpdateDataDetails_members /* .members */
23660},
23661/* UpdateStructureDataDetails */
23662{
23663 UA_TYPENAME("UpdateStructureDataDetails") /* .typeName */
23664 {0, UA_NODEIDTYPE_NUMERIC, {11295LU}}, /* .typeId */
23665 {0, UA_NODEIDTYPE_NUMERIC, {11300LU}}, /* .binaryEncodingId */
23666 sizeof(UA_UpdateStructureDataDetails), /* .memSize */
23667 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23668 false, /* .pointerFree */
23669 false, /* .overlayable */
23670 3, /* .membersSize */
23671 UpdateStructureDataDetails_members /* .members */
23672},
23673/* DeleteRawModifiedDetails */
23674{
23675 UA_TYPENAME("DeleteRawModifiedDetails") /* .typeName */
23676 {0, UA_NODEIDTYPE_NUMERIC, {686LU}}, /* .typeId */
23677 {0, UA_NODEIDTYPE_NUMERIC, {688LU}}, /* .binaryEncodingId */
23678 sizeof(UA_DeleteRawModifiedDetails), /* .memSize */
23679 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23680 false, /* .pointerFree */
23681 false, /* .overlayable */
23682 4, /* .membersSize */
23683 DeleteRawModifiedDetails_members /* .members */
23684},
23685/* DeleteAtTimeDetails */
23686{
23687 UA_TYPENAME("DeleteAtTimeDetails") /* .typeName */
23688 {0, UA_NODEIDTYPE_NUMERIC, {689LU}}, /* .typeId */
23689 {0, UA_NODEIDTYPE_NUMERIC, {691LU}}, /* .binaryEncodingId */
23690 sizeof(UA_DeleteAtTimeDetails), /* .memSize */
23691 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23692 false, /* .pointerFree */
23693 false, /* .overlayable */
23694 2, /* .membersSize */
23695 DeleteAtTimeDetails_members /* .members */
23696},
23697/* DeleteEventDetails */
23698{
23699 UA_TYPENAME("DeleteEventDetails") /* .typeName */
23700 {0, UA_NODEIDTYPE_NUMERIC, {692LU}}, /* .typeId */
23701 {0, UA_NODEIDTYPE_NUMERIC, {694LU}}, /* .binaryEncodingId */
23702 sizeof(UA_DeleteEventDetails), /* .memSize */
23703 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23704 false, /* .pointerFree */
23705 false, /* .overlayable */
23706 2, /* .membersSize */
23707 DeleteEventDetails_members /* .members */
23708},
23709/* HistoryUpdateResult */
23710{
23711 UA_TYPENAME("HistoryUpdateResult") /* .typeName */
23712 {0, UA_NODEIDTYPE_NUMERIC, {695LU}}, /* .typeId */
23713 {0, UA_NODEIDTYPE_NUMERIC, {697LU}}, /* .binaryEncodingId */
23714 sizeof(UA_HistoryUpdateResult), /* .memSize */
23715 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23716 false, /* .pointerFree */
23717 false, /* .overlayable */
23718 3, /* .membersSize */
23719 HistoryUpdateResult_members /* .members */
23720},
23721/* HistoryUpdateRequest */
23722{
23723 UA_TYPENAME("HistoryUpdateRequest") /* .typeName */
23724 {0, UA_NODEIDTYPE_NUMERIC, {698LU}}, /* .typeId */
23725 {0, UA_NODEIDTYPE_NUMERIC, {700LU}}, /* .binaryEncodingId */
23726 sizeof(UA_HistoryUpdateRequest), /* .memSize */
23727 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23728 false, /* .pointerFree */
23729 false, /* .overlayable */
23730 2, /* .membersSize */
23731 HistoryUpdateRequest_members /* .members */
23732},
23733/* HistoryUpdateResponse */
23734{
23735 UA_TYPENAME("HistoryUpdateResponse") /* .typeName */
23736 {0, UA_NODEIDTYPE_NUMERIC, {701LU}}, /* .typeId */
23737 {0, UA_NODEIDTYPE_NUMERIC, {703LU}}, /* .binaryEncodingId */
23738 sizeof(UA_HistoryUpdateResponse), /* .memSize */
23739 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23740 false, /* .pointerFree */
23741 false, /* .overlayable */
23742 3, /* .membersSize */
23743 HistoryUpdateResponse_members /* .members */
23744},
23745/* CallMethodRequest */
23746{
23747 UA_TYPENAME("CallMethodRequest") /* .typeName */
23748 {0, UA_NODEIDTYPE_NUMERIC, {704LU}}, /* .typeId */
23749 {0, UA_NODEIDTYPE_NUMERIC, {706LU}}, /* .binaryEncodingId */
23750 sizeof(UA_CallMethodRequest), /* .memSize */
23751 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23752 false, /* .pointerFree */
23753 false, /* .overlayable */
23754 3, /* .membersSize */
23755 CallMethodRequest_members /* .members */
23756},
23757/* CallMethodResult */
23758{
23759 UA_TYPENAME("CallMethodResult") /* .typeName */
23760 {0, UA_NODEIDTYPE_NUMERIC, {707LU}}, /* .typeId */
23761 {0, UA_NODEIDTYPE_NUMERIC, {709LU}}, /* .binaryEncodingId */
23762 sizeof(UA_CallMethodResult), /* .memSize */
23763 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23764 false, /* .pointerFree */
23765 false, /* .overlayable */
23766 4, /* .membersSize */
23767 CallMethodResult_members /* .members */
23768},
23769/* CallRequest */
23770{
23771 UA_TYPENAME("CallRequest") /* .typeName */
23772 {0, UA_NODEIDTYPE_NUMERIC, {710LU}}, /* .typeId */
23773 {0, UA_NODEIDTYPE_NUMERIC, {712LU}}, /* .binaryEncodingId */
23774 sizeof(UA_CallRequest), /* .memSize */
23775 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23776 false, /* .pointerFree */
23777 false, /* .overlayable */
23778 2, /* .membersSize */
23779 CallRequest_members /* .members */
23780},
23781/* CallResponse */
23782{
23783 UA_TYPENAME("CallResponse") /* .typeName */
23784 {0, UA_NODEIDTYPE_NUMERIC, {713LU}}, /* .typeId */
23785 {0, UA_NODEIDTYPE_NUMERIC, {715LU}}, /* .binaryEncodingId */
23786 sizeof(UA_CallResponse), /* .memSize */
23787 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23788 false, /* .pointerFree */
23789 false, /* .overlayable */
23790 3, /* .membersSize */
23791 CallResponse_members /* .members */
23792},
23793/* MonitoringMode */
23794{
23795 UA_TYPENAME("MonitoringMode") /* .typeName */
23796 {0, UA_NODEIDTYPE_NUMERIC, {716LU}}, /* .typeId */
23797 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
23798 sizeof(UA_MonitoringMode), /* .memSize */
23799 UA_DATATYPEKIND_ENUM, /* .typeKind */
23800 true, /* .pointerFree */
23801 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
23802 0, /* .membersSize */
23803 MonitoringMode_members /* .members */
23804},
23805/* DataChangeTrigger */
23806{
23807 UA_TYPENAME("DataChangeTrigger") /* .typeName */
23808 {0, UA_NODEIDTYPE_NUMERIC, {717LU}}, /* .typeId */
23809 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
23810 sizeof(UA_DataChangeTrigger), /* .memSize */
23811 UA_DATATYPEKIND_ENUM, /* .typeKind */
23812 true, /* .pointerFree */
23813 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
23814 0, /* .membersSize */
23815 DataChangeTrigger_members /* .members */
23816},
23817/* DeadbandType */
23818{
23819 UA_TYPENAME("DeadbandType") /* .typeName */
23820 {0, UA_NODEIDTYPE_NUMERIC, {718LU}}, /* .typeId */
23821 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
23822 sizeof(UA_DeadbandType), /* .memSize */
23823 UA_DATATYPEKIND_ENUM, /* .typeKind */
23824 true, /* .pointerFree */
23825 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
23826 0, /* .membersSize */
23827 DeadbandType_members /* .members */
23828},
23829/* DataChangeFilter */
23830{
23831 UA_TYPENAME("DataChangeFilter") /* .typeName */
23832 {0, UA_NODEIDTYPE_NUMERIC, {722LU}}, /* .typeId */
23833 {0, UA_NODEIDTYPE_NUMERIC, {724LU}}, /* .binaryEncodingId */
23834 sizeof(UA_DataChangeFilter), /* .memSize */
23835 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23836 true, /* .pointerFree */
23837 false, /* .overlayable */
23838 3, /* .membersSize */
23839 DataChangeFilter_members /* .members */
23840},
23841/* EventFilter */
23842{
23843 UA_TYPENAME("EventFilter") /* .typeName */
23844 {0, UA_NODEIDTYPE_NUMERIC, {725LU}}, /* .typeId */
23845 {0, UA_NODEIDTYPE_NUMERIC, {727LU}}, /* .binaryEncodingId */
23846 sizeof(UA_EventFilter), /* .memSize */
23847 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23848 false, /* .pointerFree */
23849 false, /* .overlayable */
23850 2, /* .membersSize */
23851 EventFilter_members /* .members */
23852},
23853/* AggregateConfiguration */
23854{
23855 UA_TYPENAME("AggregateConfiguration") /* .typeName */
23856 {0, UA_NODEIDTYPE_NUMERIC, {948LU}}, /* .typeId */
23857 {0, UA_NODEIDTYPE_NUMERIC, {950LU}}, /* .binaryEncodingId */
23858 sizeof(UA_AggregateConfiguration), /* .memSize */
23859 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23860 true, /* .pointerFree */
23861 false, /* .overlayable */
23862 5, /* .membersSize */
23863 AggregateConfiguration_members /* .members */
23864},
23865/* AggregateFilter */
23866{
23867 UA_TYPENAME("AggregateFilter") /* .typeName */
23868 {0, UA_NODEIDTYPE_NUMERIC, {728LU}}, /* .typeId */
23869 {0, UA_NODEIDTYPE_NUMERIC, {730LU}}, /* .binaryEncodingId */
23870 sizeof(UA_AggregateFilter), /* .memSize */
23871 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23872 false, /* .pointerFree */
23873 false, /* .overlayable */
23874 4, /* .membersSize */
23875 AggregateFilter_members /* .members */
23876},
23877/* EventFilterResult */
23878{
23879 UA_TYPENAME("EventFilterResult") /* .typeName */
23880 {0, UA_NODEIDTYPE_NUMERIC, {734LU}}, /* .typeId */
23881 {0, UA_NODEIDTYPE_NUMERIC, {736LU}}, /* .binaryEncodingId */
23882 sizeof(UA_EventFilterResult), /* .memSize */
23883 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23884 false, /* .pointerFree */
23885 false, /* .overlayable */
23886 3, /* .membersSize */
23887 EventFilterResult_members /* .members */
23888},
23889/* AggregateFilterResult */
23890{
23891 UA_TYPENAME("AggregateFilterResult") /* .typeName */
23892 {0, UA_NODEIDTYPE_NUMERIC, {737LU}}, /* .typeId */
23893 {0, UA_NODEIDTYPE_NUMERIC, {739LU}}, /* .binaryEncodingId */
23894 sizeof(UA_AggregateFilterResult), /* .memSize */
23895 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23896 true, /* .pointerFree */
23897 false, /* .overlayable */
23898 3, /* .membersSize */
23899 AggregateFilterResult_members /* .members */
23900},
23901/* MonitoringParameters */
23902{
23903 UA_TYPENAME("MonitoringParameters") /* .typeName */
23904 {0, UA_NODEIDTYPE_NUMERIC, {740LU}}, /* .typeId */
23905 {0, UA_NODEIDTYPE_NUMERIC, {742LU}}, /* .binaryEncodingId */
23906 sizeof(UA_MonitoringParameters), /* .memSize */
23907 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23908 false, /* .pointerFree */
23909 false, /* .overlayable */
23910 5, /* .membersSize */
23911 MonitoringParameters_members /* .members */
23912},
23913/* MonitoredItemCreateRequest */
23914{
23915 UA_TYPENAME("MonitoredItemCreateRequest") /* .typeName */
23916 {0, UA_NODEIDTYPE_NUMERIC, {743LU}}, /* .typeId */
23917 {0, UA_NODEIDTYPE_NUMERIC, {745LU}}, /* .binaryEncodingId */
23918 sizeof(UA_MonitoredItemCreateRequest), /* .memSize */
23919 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23920 false, /* .pointerFree */
23921 false, /* .overlayable */
23922 3, /* .membersSize */
23923 MonitoredItemCreateRequest_members /* .members */
23924},
23925/* MonitoredItemCreateResult */
23926{
23927 UA_TYPENAME("MonitoredItemCreateResult") /* .typeName */
23928 {0, UA_NODEIDTYPE_NUMERIC, {746LU}}, /* .typeId */
23929 {0, UA_NODEIDTYPE_NUMERIC, {748LU}}, /* .binaryEncodingId */
23930 sizeof(UA_MonitoredItemCreateResult), /* .memSize */
23931 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23932 false, /* .pointerFree */
23933 false, /* .overlayable */
23934 5, /* .membersSize */
23935 MonitoredItemCreateResult_members /* .members */
23936},
23937/* CreateMonitoredItemsRequest */
23938{
23939 UA_TYPENAME("CreateMonitoredItemsRequest") /* .typeName */
23940 {0, UA_NODEIDTYPE_NUMERIC, {749LU}}, /* .typeId */
23941 {0, UA_NODEIDTYPE_NUMERIC, {751LU}}, /* .binaryEncodingId */
23942 sizeof(UA_CreateMonitoredItemsRequest), /* .memSize */
23943 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23944 false, /* .pointerFree */
23945 false, /* .overlayable */
23946 4, /* .membersSize */
23947 CreateMonitoredItemsRequest_members /* .members */
23948},
23949/* CreateMonitoredItemsResponse */
23950{
23951 UA_TYPENAME("CreateMonitoredItemsResponse") /* .typeName */
23952 {0, UA_NODEIDTYPE_NUMERIC, {752LU}}, /* .typeId */
23953 {0, UA_NODEIDTYPE_NUMERIC, {754LU}}, /* .binaryEncodingId */
23954 sizeof(UA_CreateMonitoredItemsResponse), /* .memSize */
23955 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23956 false, /* .pointerFree */
23957 false, /* .overlayable */
23958 3, /* .membersSize */
23959 CreateMonitoredItemsResponse_members /* .members */
23960},
23961/* MonitoredItemModifyRequest */
23962{
23963 UA_TYPENAME("MonitoredItemModifyRequest") /* .typeName */
23964 {0, UA_NODEIDTYPE_NUMERIC, {755LU}}, /* .typeId */
23965 {0, UA_NODEIDTYPE_NUMERIC, {757LU}}, /* .binaryEncodingId */
23966 sizeof(UA_MonitoredItemModifyRequest), /* .memSize */
23967 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23968 false, /* .pointerFree */
23969 false, /* .overlayable */
23970 2, /* .membersSize */
23971 MonitoredItemModifyRequest_members /* .members */
23972},
23973/* MonitoredItemModifyResult */
23974{
23975 UA_TYPENAME("MonitoredItemModifyResult") /* .typeName */
23976 {0, UA_NODEIDTYPE_NUMERIC, {758LU}}, /* .typeId */
23977 {0, UA_NODEIDTYPE_NUMERIC, {760LU}}, /* .binaryEncodingId */
23978 sizeof(UA_MonitoredItemModifyResult), /* .memSize */
23979 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23980 false, /* .pointerFree */
23981 false, /* .overlayable */
23982 4, /* .membersSize */
23983 MonitoredItemModifyResult_members /* .members */
23984},
23985/* ModifyMonitoredItemsRequest */
23986{
23987 UA_TYPENAME("ModifyMonitoredItemsRequest") /* .typeName */
23988 {0, UA_NODEIDTYPE_NUMERIC, {761LU}}, /* .typeId */
23989 {0, UA_NODEIDTYPE_NUMERIC, {763LU}}, /* .binaryEncodingId */
23990 sizeof(UA_ModifyMonitoredItemsRequest), /* .memSize */
23991 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
23992 false, /* .pointerFree */
23993 false, /* .overlayable */
23994 4, /* .membersSize */
23995 ModifyMonitoredItemsRequest_members /* .members */
23996},
23997/* ModifyMonitoredItemsResponse */
23998{
23999 UA_TYPENAME("ModifyMonitoredItemsResponse") /* .typeName */
24000 {0, UA_NODEIDTYPE_NUMERIC, {764LU}}, /* .typeId */
24001 {0, UA_NODEIDTYPE_NUMERIC, {766LU}}, /* .binaryEncodingId */
24002 sizeof(UA_ModifyMonitoredItemsResponse), /* .memSize */
24003 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24004 false, /* .pointerFree */
24005 false, /* .overlayable */
24006 3, /* .membersSize */
24007 ModifyMonitoredItemsResponse_members /* .members */
24008},
24009/* SetMonitoringModeRequest */
24010{
24011 UA_TYPENAME("SetMonitoringModeRequest") /* .typeName */
24012 {0, UA_NODEIDTYPE_NUMERIC, {767LU}}, /* .typeId */
24013 {0, UA_NODEIDTYPE_NUMERIC, {769LU}}, /* .binaryEncodingId */
24014 sizeof(UA_SetMonitoringModeRequest), /* .memSize */
24015 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24016 false, /* .pointerFree */
24017 false, /* .overlayable */
24018 4, /* .membersSize */
24019 SetMonitoringModeRequest_members /* .members */
24020},
24021/* SetMonitoringModeResponse */
24022{
24023 UA_TYPENAME("SetMonitoringModeResponse") /* .typeName */
24024 {0, UA_NODEIDTYPE_NUMERIC, {770LU}}, /* .typeId */
24025 {0, UA_NODEIDTYPE_NUMERIC, {772LU}}, /* .binaryEncodingId */
24026 sizeof(UA_SetMonitoringModeResponse), /* .memSize */
24027 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24028 false, /* .pointerFree */
24029 false, /* .overlayable */
24030 3, /* .membersSize */
24031 SetMonitoringModeResponse_members /* .members */
24032},
24033/* SetTriggeringRequest */
24034{
24035 UA_TYPENAME("SetTriggeringRequest") /* .typeName */
24036 {0, UA_NODEIDTYPE_NUMERIC, {773LU}}, /* .typeId */
24037 {0, UA_NODEIDTYPE_NUMERIC, {775LU}}, /* .binaryEncodingId */
24038 sizeof(UA_SetTriggeringRequest), /* .memSize */
24039 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24040 false, /* .pointerFree */
24041 false, /* .overlayable */
24042 5, /* .membersSize */
24043 SetTriggeringRequest_members /* .members */
24044},
24045/* SetTriggeringResponse */
24046{
24047 UA_TYPENAME("SetTriggeringResponse") /* .typeName */
24048 {0, UA_NODEIDTYPE_NUMERIC, {776LU}}, /* .typeId */
24049 {0, UA_NODEIDTYPE_NUMERIC, {778LU}}, /* .binaryEncodingId */
24050 sizeof(UA_SetTriggeringResponse), /* .memSize */
24051 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24052 false, /* .pointerFree */
24053 false, /* .overlayable */
24054 5, /* .membersSize */
24055 SetTriggeringResponse_members /* .members */
24056},
24057/* DeleteMonitoredItemsRequest */
24058{
24059 UA_TYPENAME("DeleteMonitoredItemsRequest") /* .typeName */
24060 {0, UA_NODEIDTYPE_NUMERIC, {779LU}}, /* .typeId */
24061 {0, UA_NODEIDTYPE_NUMERIC, {781LU}}, /* .binaryEncodingId */
24062 sizeof(UA_DeleteMonitoredItemsRequest), /* .memSize */
24063 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24064 false, /* .pointerFree */
24065 false, /* .overlayable */
24066 3, /* .membersSize */
24067 DeleteMonitoredItemsRequest_members /* .members */
24068},
24069/* DeleteMonitoredItemsResponse */
24070{
24071 UA_TYPENAME("DeleteMonitoredItemsResponse") /* .typeName */
24072 {0, UA_NODEIDTYPE_NUMERIC, {782LU}}, /* .typeId */
24073 {0, UA_NODEIDTYPE_NUMERIC, {784LU}}, /* .binaryEncodingId */
24074 sizeof(UA_DeleteMonitoredItemsResponse), /* .memSize */
24075 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24076 false, /* .pointerFree */
24077 false, /* .overlayable */
24078 3, /* .membersSize */
24079 DeleteMonitoredItemsResponse_members /* .members */
24080},
24081/* CreateSubscriptionRequest */
24082{
24083 UA_TYPENAME("CreateSubscriptionRequest") /* .typeName */
24084 {0, UA_NODEIDTYPE_NUMERIC, {785LU}}, /* .typeId */
24085 {0, UA_NODEIDTYPE_NUMERIC, {787LU}}, /* .binaryEncodingId */
24086 sizeof(UA_CreateSubscriptionRequest), /* .memSize */
24087 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24088 false, /* .pointerFree */
24089 false, /* .overlayable */
24090 7, /* .membersSize */
24091 CreateSubscriptionRequest_members /* .members */
24092},
24093/* CreateSubscriptionResponse */
24094{
24095 UA_TYPENAME("CreateSubscriptionResponse") /* .typeName */
24096 {0, UA_NODEIDTYPE_NUMERIC, {788LU}}, /* .typeId */
24097 {0, UA_NODEIDTYPE_NUMERIC, {790LU}}, /* .binaryEncodingId */
24098 sizeof(UA_CreateSubscriptionResponse), /* .memSize */
24099 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24100 false, /* .pointerFree */
24101 false, /* .overlayable */
24102 5, /* .membersSize */
24103 CreateSubscriptionResponse_members /* .members */
24104},
24105/* ModifySubscriptionRequest */
24106{
24107 UA_TYPENAME("ModifySubscriptionRequest") /* .typeName */
24108 {0, UA_NODEIDTYPE_NUMERIC, {791LU}}, /* .typeId */
24109 {0, UA_NODEIDTYPE_NUMERIC, {793LU}}, /* .binaryEncodingId */
24110 sizeof(UA_ModifySubscriptionRequest), /* .memSize */
24111 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24112 false, /* .pointerFree */
24113 false, /* .overlayable */
24114 7, /* .membersSize */
24115 ModifySubscriptionRequest_members /* .members */
24116},
24117/* ModifySubscriptionResponse */
24118{
24119 UA_TYPENAME("ModifySubscriptionResponse") /* .typeName */
24120 {0, UA_NODEIDTYPE_NUMERIC, {794LU}}, /* .typeId */
24121 {0, UA_NODEIDTYPE_NUMERIC, {796LU}}, /* .binaryEncodingId */
24122 sizeof(UA_ModifySubscriptionResponse), /* .memSize */
24123 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24124 false, /* .pointerFree */
24125 false, /* .overlayable */
24126 4, /* .membersSize */
24127 ModifySubscriptionResponse_members /* .members */
24128},
24129/* SetPublishingModeRequest */
24130{
24131 UA_TYPENAME("SetPublishingModeRequest") /* .typeName */
24132 {0, UA_NODEIDTYPE_NUMERIC, {797LU}}, /* .typeId */
24133 {0, UA_NODEIDTYPE_NUMERIC, {799LU}}, /* .binaryEncodingId */
24134 sizeof(UA_SetPublishingModeRequest), /* .memSize */
24135 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24136 false, /* .pointerFree */
24137 false, /* .overlayable */
24138 3, /* .membersSize */
24139 SetPublishingModeRequest_members /* .members */
24140},
24141/* SetPublishingModeResponse */
24142{
24143 UA_TYPENAME("SetPublishingModeResponse") /* .typeName */
24144 {0, UA_NODEIDTYPE_NUMERIC, {800LU}}, /* .typeId */
24145 {0, UA_NODEIDTYPE_NUMERIC, {802LU}}, /* .binaryEncodingId */
24146 sizeof(UA_SetPublishingModeResponse), /* .memSize */
24147 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24148 false, /* .pointerFree */
24149 false, /* .overlayable */
24150 3, /* .membersSize */
24151 SetPublishingModeResponse_members /* .members */
24152},
24153/* NotificationMessage */
24154{
24155 UA_TYPENAME("NotificationMessage") /* .typeName */
24156 {0, UA_NODEIDTYPE_NUMERIC, {803LU}}, /* .typeId */
24157 {0, UA_NODEIDTYPE_NUMERIC, {805LU}}, /* .binaryEncodingId */
24158 sizeof(UA_NotificationMessage), /* .memSize */
24159 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24160 false, /* .pointerFree */
24161 false, /* .overlayable */
24162 3, /* .membersSize */
24163 NotificationMessage_members /* .members */
24164},
24165/* MonitoredItemNotification */
24166{
24167 UA_TYPENAME("MonitoredItemNotification") /* .typeName */
24168 {0, UA_NODEIDTYPE_NUMERIC, {806LU}}, /* .typeId */
24169 {0, UA_NODEIDTYPE_NUMERIC, {808LU}}, /* .binaryEncodingId */
24170 sizeof(UA_MonitoredItemNotification), /* .memSize */
24171 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24172 false, /* .pointerFree */
24173 false, /* .overlayable */
24174 2, /* .membersSize */
24175 MonitoredItemNotification_members /* .members */
24176},
24177/* EventFieldList */
24178{
24179 UA_TYPENAME("EventFieldList") /* .typeName */
24180 {0, UA_NODEIDTYPE_NUMERIC, {917LU}}, /* .typeId */
24181 {0, UA_NODEIDTYPE_NUMERIC, {919LU}}, /* .binaryEncodingId */
24182 sizeof(UA_EventFieldList), /* .memSize */
24183 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24184 false, /* .pointerFree */
24185 false, /* .overlayable */
24186 2, /* .membersSize */
24187 EventFieldList_members /* .members */
24188},
24189/* HistoryEventFieldList */
24190{
24191 UA_TYPENAME("HistoryEventFieldList") /* .typeName */
24192 {0, UA_NODEIDTYPE_NUMERIC, {920LU}}, /* .typeId */
24193 {0, UA_NODEIDTYPE_NUMERIC, {922LU}}, /* .binaryEncodingId */
24194 sizeof(UA_HistoryEventFieldList), /* .memSize */
24195 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24196 false, /* .pointerFree */
24197 false, /* .overlayable */
24198 1, /* .membersSize */
24199 HistoryEventFieldList_members /* .members */
24200},
24201/* StatusChangeNotification */
24202{
24203 UA_TYPENAME("StatusChangeNotification") /* .typeName */
24204 {0, UA_NODEIDTYPE_NUMERIC, {818LU}}, /* .typeId */
24205 {0, UA_NODEIDTYPE_NUMERIC, {820LU}}, /* .binaryEncodingId */
24206 sizeof(UA_StatusChangeNotification), /* .memSize */
24207 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24208 false, /* .pointerFree */
24209 false, /* .overlayable */
24210 2, /* .membersSize */
24211 StatusChangeNotification_members /* .members */
24212},
24213/* SubscriptionAcknowledgement */
24214{
24215 UA_TYPENAME("SubscriptionAcknowledgement") /* .typeName */
24216 {0, UA_NODEIDTYPE_NUMERIC, {821LU}}, /* .typeId */
24217 {0, UA_NODEIDTYPE_NUMERIC, {823LU}}, /* .binaryEncodingId */
24218 sizeof(UA_SubscriptionAcknowledgement), /* .memSize */
24219 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24220 true, /* .pointerFree */
24221 false, /* .overlayable */
24222 2, /* .membersSize */
24223 SubscriptionAcknowledgement_members /* .members */
24224},
24225/* PublishRequest */
24226{
24227 UA_TYPENAME("PublishRequest") /* .typeName */
24228 {0, UA_NODEIDTYPE_NUMERIC, {824LU}}, /* .typeId */
24229 {0, UA_NODEIDTYPE_NUMERIC, {826LU}}, /* .binaryEncodingId */
24230 sizeof(UA_PublishRequest), /* .memSize */
24231 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24232 false, /* .pointerFree */
24233 false, /* .overlayable */
24234 2, /* .membersSize */
24235 PublishRequest_members /* .members */
24236},
24237/* PublishResponse */
24238{
24239 UA_TYPENAME("PublishResponse") /* .typeName */
24240 {0, UA_NODEIDTYPE_NUMERIC, {827LU}}, /* .typeId */
24241 {0, UA_NODEIDTYPE_NUMERIC, {829LU}}, /* .binaryEncodingId */
24242 sizeof(UA_PublishResponse), /* .memSize */
24243 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24244 false, /* .pointerFree */
24245 false, /* .overlayable */
24246 7, /* .membersSize */
24247 PublishResponse_members /* .members */
24248},
24249/* RepublishRequest */
24250{
24251 UA_TYPENAME("RepublishRequest") /* .typeName */
24252 {0, UA_NODEIDTYPE_NUMERIC, {830LU}}, /* .typeId */
24253 {0, UA_NODEIDTYPE_NUMERIC, {832LU}}, /* .binaryEncodingId */
24254 sizeof(UA_RepublishRequest), /* .memSize */
24255 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24256 false, /* .pointerFree */
24257 false, /* .overlayable */
24258 3, /* .membersSize */
24259 RepublishRequest_members /* .members */
24260},
24261/* RepublishResponse */
24262{
24263 UA_TYPENAME("RepublishResponse") /* .typeName */
24264 {0, UA_NODEIDTYPE_NUMERIC, {833LU}}, /* .typeId */
24265 {0, UA_NODEIDTYPE_NUMERIC, {835LU}}, /* .binaryEncodingId */
24266 sizeof(UA_RepublishResponse), /* .memSize */
24267 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24268 false, /* .pointerFree */
24269 false, /* .overlayable */
24270 2, /* .membersSize */
24271 RepublishResponse_members /* .members */
24272},
24273/* TransferResult */
24274{
24275 UA_TYPENAME("TransferResult") /* .typeName */
24276 {0, UA_NODEIDTYPE_NUMERIC, {836LU}}, /* .typeId */
24277 {0, UA_NODEIDTYPE_NUMERIC, {838LU}}, /* .binaryEncodingId */
24278 sizeof(UA_TransferResult), /* .memSize */
24279 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24280 false, /* .pointerFree */
24281 false, /* .overlayable */
24282 2, /* .membersSize */
24283 TransferResult_members /* .members */
24284},
24285/* TransferSubscriptionsRequest */
24286{
24287 UA_TYPENAME("TransferSubscriptionsRequest") /* .typeName */
24288 {0, UA_NODEIDTYPE_NUMERIC, {839LU}}, /* .typeId */
24289 {0, UA_NODEIDTYPE_NUMERIC, {841LU}}, /* .binaryEncodingId */
24290 sizeof(UA_TransferSubscriptionsRequest), /* .memSize */
24291 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24292 false, /* .pointerFree */
24293 false, /* .overlayable */
24294 3, /* .membersSize */
24295 TransferSubscriptionsRequest_members /* .members */
24296},
24297/* TransferSubscriptionsResponse */
24298{
24299 UA_TYPENAME("TransferSubscriptionsResponse") /* .typeName */
24300 {0, UA_NODEIDTYPE_NUMERIC, {842LU}}, /* .typeId */
24301 {0, UA_NODEIDTYPE_NUMERIC, {844LU}}, /* .binaryEncodingId */
24302 sizeof(UA_TransferSubscriptionsResponse), /* .memSize */
24303 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24304 false, /* .pointerFree */
24305 false, /* .overlayable */
24306 3, /* .membersSize */
24307 TransferSubscriptionsResponse_members /* .members */
24308},
24309/* DeleteSubscriptionsRequest */
24310{
24311 UA_TYPENAME("DeleteSubscriptionsRequest") /* .typeName */
24312 {0, UA_NODEIDTYPE_NUMERIC, {845LU}}, /* .typeId */
24313 {0, UA_NODEIDTYPE_NUMERIC, {847LU}}, /* .binaryEncodingId */
24314 sizeof(UA_DeleteSubscriptionsRequest), /* .memSize */
24315 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24316 false, /* .pointerFree */
24317 false, /* .overlayable */
24318 2, /* .membersSize */
24319 DeleteSubscriptionsRequest_members /* .members */
24320},
24321/* DeleteSubscriptionsResponse */
24322{
24323 UA_TYPENAME("DeleteSubscriptionsResponse") /* .typeName */
24324 {0, UA_NODEIDTYPE_NUMERIC, {848LU}}, /* .typeId */
24325 {0, UA_NODEIDTYPE_NUMERIC, {850LU}}, /* .binaryEncodingId */
24326 sizeof(UA_DeleteSubscriptionsResponse), /* .memSize */
24327 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24328 false, /* .pointerFree */
24329 false, /* .overlayable */
24330 3, /* .membersSize */
24331 DeleteSubscriptionsResponse_members /* .members */
24332},
24333/* BuildInfo */
24334{
24335 UA_TYPENAME("BuildInfo") /* .typeName */
24336 {0, UA_NODEIDTYPE_NUMERIC, {338LU}}, /* .typeId */
24337 {0, UA_NODEIDTYPE_NUMERIC, {340LU}}, /* .binaryEncodingId */
24338 sizeof(UA_BuildInfo), /* .memSize */
24339 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24340 false, /* .pointerFree */
24341 false, /* .overlayable */
24342 6, /* .membersSize */
24343 BuildInfo_members /* .members */
24344},
24345/* RedundancySupport */
24346{
24347 UA_TYPENAME("RedundancySupport") /* .typeName */
24348 {0, UA_NODEIDTYPE_NUMERIC, {851LU}}, /* .typeId */
24349 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
24350 sizeof(UA_RedundancySupport), /* .memSize */
24351 UA_DATATYPEKIND_ENUM, /* .typeKind */
24352 true, /* .pointerFree */
24353 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
24354 0, /* .membersSize */
24355 RedundancySupport_members /* .members */
24356},
24357/* ServerState */
24358{
24359 UA_TYPENAME("ServerState") /* .typeName */
24360 {0, UA_NODEIDTYPE_NUMERIC, {852LU}}, /* .typeId */
24361 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
24362 sizeof(UA_ServerState), /* .memSize */
24363 UA_DATATYPEKIND_ENUM, /* .typeKind */
24364 true, /* .pointerFree */
24365 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
24366 0, /* .membersSize */
24367 ServerState_members /* .members */
24368},
24369/* RedundantServerDataType */
24370{
24371 UA_TYPENAME("RedundantServerDataType") /* .typeName */
24372 {0, UA_NODEIDTYPE_NUMERIC, {853LU}}, /* .typeId */
24373 {0, UA_NODEIDTYPE_NUMERIC, {855LU}}, /* .binaryEncodingId */
24374 sizeof(UA_RedundantServerDataType), /* .memSize */
24375 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24376 false, /* .pointerFree */
24377 false, /* .overlayable */
24378 3, /* .membersSize */
24379 RedundantServerDataType_members /* .members */
24380},
24381/* EndpointUrlListDataType */
24382{
24383 UA_TYPENAME("EndpointUrlListDataType") /* .typeName */
24384 {0, UA_NODEIDTYPE_NUMERIC, {11943LU}}, /* .typeId */
24385 {0, UA_NODEIDTYPE_NUMERIC, {11957LU}}, /* .binaryEncodingId */
24386 sizeof(UA_EndpointUrlListDataType), /* .memSize */
24387 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24388 false, /* .pointerFree */
24389 false, /* .overlayable */
24390 1, /* .membersSize */
24391 EndpointUrlListDataType_members /* .members */
24392},
24393/* NetworkGroupDataType */
24394{
24395 UA_TYPENAME("NetworkGroupDataType") /* .typeName */
24396 {0, UA_NODEIDTYPE_NUMERIC, {11944LU}}, /* .typeId */
24397 {0, UA_NODEIDTYPE_NUMERIC, {11958LU}}, /* .binaryEncodingId */
24398 sizeof(UA_NetworkGroupDataType), /* .memSize */
24399 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24400 false, /* .pointerFree */
24401 false, /* .overlayable */
24402 2, /* .membersSize */
24403 NetworkGroupDataType_members /* .members */
24404},
24405/* SamplingIntervalDiagnosticsDataType */
24406{
24407 UA_TYPENAME("SamplingIntervalDiagnosticsDataType") /* .typeName */
24408 {0, UA_NODEIDTYPE_NUMERIC, {856LU}}, /* .typeId */
24409 {0, UA_NODEIDTYPE_NUMERIC, {858LU}}, /* .binaryEncodingId */
24410 sizeof(UA_SamplingIntervalDiagnosticsDataType), /* .memSize */
24411 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24412 true, /* .pointerFree */
24413 false, /* .overlayable */
24414 4, /* .membersSize */
24415 SamplingIntervalDiagnosticsDataType_members /* .members */
24416},
24417/* ServerDiagnosticsSummaryDataType */
24418{
24419 UA_TYPENAME("ServerDiagnosticsSummaryDataType") /* .typeName */
24420 {0, UA_NODEIDTYPE_NUMERIC, {859LU}}, /* .typeId */
24421 {0, UA_NODEIDTYPE_NUMERIC, {861LU}}, /* .binaryEncodingId */
24422 sizeof(UA_ServerDiagnosticsSummaryDataType), /* .memSize */
24423 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24424 true, /* .pointerFree */
24425 false, /* .overlayable */
24426 12, /* .membersSize */
24427 ServerDiagnosticsSummaryDataType_members /* .members */
24428},
24429/* ServerStatusDataType */
24430{
24431 UA_TYPENAME("ServerStatusDataType") /* .typeName */
24432 {0, UA_NODEIDTYPE_NUMERIC, {862LU}}, /* .typeId */
24433 {0, UA_NODEIDTYPE_NUMERIC, {864LU}}, /* .binaryEncodingId */
24434 sizeof(UA_ServerStatusDataType), /* .memSize */
24435 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24436 false, /* .pointerFree */
24437 false, /* .overlayable */
24438 6, /* .membersSize */
24439 ServerStatusDataType_members /* .members */
24440},
24441/* SessionSecurityDiagnosticsDataType */
24442{
24443 UA_TYPENAME("SessionSecurityDiagnosticsDataType") /* .typeName */
24444 {0, UA_NODEIDTYPE_NUMERIC, {868LU}}, /* .typeId */
24445 {0, UA_NODEIDTYPE_NUMERIC, {870LU}}, /* .binaryEncodingId */
24446 sizeof(UA_SessionSecurityDiagnosticsDataType), /* .memSize */
24447 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24448 false, /* .pointerFree */
24449 false, /* .overlayable */
24450 9, /* .membersSize */
24451 SessionSecurityDiagnosticsDataType_members /* .members */
24452},
24453/* ServiceCounterDataType */
24454{
24455 UA_TYPENAME("ServiceCounterDataType") /* .typeName */
24456 {0, UA_NODEIDTYPE_NUMERIC, {871LU}}, /* .typeId */
24457 {0, UA_NODEIDTYPE_NUMERIC, {873LU}}, /* .binaryEncodingId */
24458 sizeof(UA_ServiceCounterDataType), /* .memSize */
24459 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24460 true, /* .pointerFree */
24461 false, /* .overlayable */
24462 2, /* .membersSize */
24463 ServiceCounterDataType_members /* .members */
24464},
24465/* StatusResult */
24466{
24467 UA_TYPENAME("StatusResult") /* .typeName */
24468 {0, UA_NODEIDTYPE_NUMERIC, {299LU}}, /* .typeId */
24469 {0, UA_NODEIDTYPE_NUMERIC, {301LU}}, /* .binaryEncodingId */
24470 sizeof(UA_StatusResult), /* .memSize */
24471 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24472 false, /* .pointerFree */
24473 false, /* .overlayable */
24474 2, /* .membersSize */
24475 StatusResult_members /* .members */
24476},
24477/* SubscriptionDiagnosticsDataType */
24478{
24479 UA_TYPENAME("SubscriptionDiagnosticsDataType") /* .typeName */
24480 {0, UA_NODEIDTYPE_NUMERIC, {874LU}}, /* .typeId */
24481 {0, UA_NODEIDTYPE_NUMERIC, {876LU}}, /* .binaryEncodingId */
24482 sizeof(UA_SubscriptionDiagnosticsDataType), /* .memSize */
24483 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24484 false, /* .pointerFree */
24485 false, /* .overlayable */
24486 31, /* .membersSize */
24487 SubscriptionDiagnosticsDataType_members /* .members */
24488},
24489/* ModelChangeStructureVerbMask */
24490{
24491 UA_TYPENAME("ModelChangeStructureVerbMask") /* .typeName */
24492 {0, UA_NODEIDTYPE_NUMERIC, {11941LU}}, /* .typeId */
24493 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
24494 sizeof(UA_ModelChangeStructureVerbMask), /* .memSize */
24495 UA_DATATYPEKIND_ENUM, /* .typeKind */
24496 true, /* .pointerFree */
24497 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
24498 0, /* .membersSize */
24499 ModelChangeStructureVerbMask_members /* .members */
24500},
24501/* ModelChangeStructureDataType */
24502{
24503 UA_TYPENAME("ModelChangeStructureDataType") /* .typeName */
24504 {0, UA_NODEIDTYPE_NUMERIC, {877LU}}, /* .typeId */
24505 {0, UA_NODEIDTYPE_NUMERIC, {879LU}}, /* .binaryEncodingId */
24506 sizeof(UA_ModelChangeStructureDataType), /* .memSize */
24507 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24508 false, /* .pointerFree */
24509 false, /* .overlayable */
24510 3, /* .membersSize */
24511 ModelChangeStructureDataType_members /* .members */
24512},
24513/* SemanticChangeStructureDataType */
24514{
24515 UA_TYPENAME("SemanticChangeStructureDataType") /* .typeName */
24516 {0, UA_NODEIDTYPE_NUMERIC, {897LU}}, /* .typeId */
24517 {0, UA_NODEIDTYPE_NUMERIC, {899LU}}, /* .binaryEncodingId */
24518 sizeof(UA_SemanticChangeStructureDataType), /* .memSize */
24519 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24520 false, /* .pointerFree */
24521 false, /* .overlayable */
24522 2, /* .membersSize */
24523 SemanticChangeStructureDataType_members /* .members */
24524},
24525/* Range */
24526{
24527 UA_TYPENAME("Range") /* .typeName */
24528 {0, UA_NODEIDTYPE_NUMERIC, {884LU}}, /* .typeId */
24529 {0, UA_NODEIDTYPE_NUMERIC, {886LU}}, /* .binaryEncodingId */
24530 sizeof(UA_Range), /* .memSize */
24531 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24532 true, /* .pointerFree */
24533 false, /* .overlayable */
24534 2, /* .membersSize */
24535 Range_members /* .members */
24536},
24537/* EUInformation */
24538{
24539 UA_TYPENAME("EUInformation") /* .typeName */
24540 {0, UA_NODEIDTYPE_NUMERIC, {887LU}}, /* .typeId */
24541 {0, UA_NODEIDTYPE_NUMERIC, {889LU}}, /* .binaryEncodingId */
24542 sizeof(UA_EUInformation), /* .memSize */
24543 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24544 false, /* .pointerFree */
24545 false, /* .overlayable */
24546 4, /* .membersSize */
24547 EUInformation_members /* .members */
24548},
24549/* AxisScaleEnumeration */
24550{
24551 UA_TYPENAME("AxisScaleEnumeration") /* .typeName */
24552 {0, UA_NODEIDTYPE_NUMERIC, {12077LU}}, /* .typeId */
24553 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
24554 sizeof(UA_AxisScaleEnumeration), /* .memSize */
24555 UA_DATATYPEKIND_ENUM, /* .typeKind */
24556 true, /* .pointerFree */
24557 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
24558 0, /* .membersSize */
24559 AxisScaleEnumeration_members /* .members */
24560},
24561/* ComplexNumberType */
24562{
24563 UA_TYPENAME("ComplexNumberType") /* .typeName */
24564 {0, UA_NODEIDTYPE_NUMERIC, {12171LU}}, /* .typeId */
24565 {0, UA_NODEIDTYPE_NUMERIC, {12181LU}}, /* .binaryEncodingId */
24566 sizeof(UA_ComplexNumberType), /* .memSize */
24567 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24568 true, /* .pointerFree */
24569 false, /* .overlayable */
24570 2, /* .membersSize */
24571 ComplexNumberType_members /* .members */
24572},
24573/* DoubleComplexNumberType */
24574{
24575 UA_TYPENAME("DoubleComplexNumberType") /* .typeName */
24576 {0, UA_NODEIDTYPE_NUMERIC, {12172LU}}, /* .typeId */
24577 {0, UA_NODEIDTYPE_NUMERIC, {12182LU}}, /* .binaryEncodingId */
24578 sizeof(UA_DoubleComplexNumberType), /* .memSize */
24579 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24580 true, /* .pointerFree */
24581 false, /* .overlayable */
24582 2, /* .membersSize */
24583 DoubleComplexNumberType_members /* .members */
24584},
24585/* AxisInformation */
24586{
24587 UA_TYPENAME("AxisInformation") /* .typeName */
24588 {0, UA_NODEIDTYPE_NUMERIC, {12079LU}}, /* .typeId */
24589 {0, UA_NODEIDTYPE_NUMERIC, {12089LU}}, /* .binaryEncodingId */
24590 sizeof(UA_AxisInformation), /* .memSize */
24591 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24592 false, /* .pointerFree */
24593 false, /* .overlayable */
24594 5, /* .membersSize */
24595 AxisInformation_members /* .members */
24596},
24597/* XVType */
24598{
24599 UA_TYPENAME("XVType") /* .typeName */
24600 {0, UA_NODEIDTYPE_NUMERIC, {12080LU}}, /* .typeId */
24601 {0, UA_NODEIDTYPE_NUMERIC, {12090LU}}, /* .binaryEncodingId */
24602 sizeof(UA_XVType), /* .memSize */
24603 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24604 true, /* .pointerFree */
24605 false, /* .overlayable */
24606 2, /* .membersSize */
24607 XVType_members /* .members */
24608},
24609/* ProgramDiagnosticDataType */
24610{
24611 UA_TYPENAME("ProgramDiagnosticDataType") /* .typeName */
24612 {0, UA_NODEIDTYPE_NUMERIC, {894LU}}, /* .typeId */
24613 {0, UA_NODEIDTYPE_NUMERIC, {896LU}}, /* .binaryEncodingId */
24614 sizeof(UA_ProgramDiagnosticDataType), /* .memSize */
24615 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24616 false, /* .pointerFree */
24617 false, /* .overlayable */
24618 10, /* .membersSize */
24619 ProgramDiagnosticDataType_members /* .members */
24620},
24621/* ProgramDiagnostic2DataType */
24622{
24623 UA_TYPENAME("ProgramDiagnostic2DataType") /* .typeName */
24624 {0, UA_NODEIDTYPE_NUMERIC, {24033LU}}, /* .typeId */
24625 {0, UA_NODEIDTYPE_NUMERIC, {24034LU}}, /* .binaryEncodingId */
24626 sizeof(UA_ProgramDiagnostic2DataType), /* .memSize */
24627 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24628 false, /* .pointerFree */
24629 false, /* .overlayable */
24630 12, /* .membersSize */
24631 ProgramDiagnostic2DataType_members /* .members */
24632},
24633/* Annotation */
24634{
24635 UA_TYPENAME("Annotation") /* .typeName */
24636 {0, UA_NODEIDTYPE_NUMERIC, {891LU}}, /* .typeId */
24637 {0, UA_NODEIDTYPE_NUMERIC, {893LU}}, /* .binaryEncodingId */
24638 sizeof(UA_Annotation), /* .memSize */
24639 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24640 false, /* .pointerFree */
24641 false, /* .overlayable */
24642 3, /* .membersSize */
24643 Annotation_members /* .members */
24644},
24645/* ExceptionDeviationFormat */
24646{
24647 UA_TYPENAME("ExceptionDeviationFormat") /* .typeName */
24648 {0, UA_NODEIDTYPE_NUMERIC, {890LU}}, /* .typeId */
24649 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
24650 sizeof(UA_ExceptionDeviationFormat), /* .memSize */
24651 UA_DATATYPEKIND_ENUM, /* .typeKind */
24652 true, /* .pointerFree */
24653 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
24654 0, /* .membersSize */
24655 ExceptionDeviationFormat_members /* .members */
24656},
24657/* EndpointType */
24658{
24659 UA_TYPENAME("EndpointType") /* .typeName */
24660 {0, UA_NODEIDTYPE_NUMERIC, {15528LU}}, /* .typeId */
24661 {0, UA_NODEIDTYPE_NUMERIC, {15671LU}}, /* .binaryEncodingId */
24662 sizeof(UA_EndpointType), /* .memSize */
24663 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24664 false, /* .pointerFree */
24665 false, /* .overlayable */
24666 4, /* .membersSize */
24667 EndpointType_members /* .members */
24668},
24669/* StructureDescription */
24670{
24671 UA_TYPENAME("StructureDescription") /* .typeName */
24672 {0, UA_NODEIDTYPE_NUMERIC, {15487LU}}, /* .typeId */
24673 {0, UA_NODEIDTYPE_NUMERIC, {126LU}}, /* .binaryEncodingId */
24674 sizeof(UA_StructureDescription), /* .memSize */
24675 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24676 false, /* .pointerFree */
24677 false, /* .overlayable */
24678 3, /* .membersSize */
24679 StructureDescription_members /* .members */
24680},
24681/* FieldMetaData */
24682{
24683 UA_TYPENAME("FieldMetaData") /* .typeName */
24684 {0, UA_NODEIDTYPE_NUMERIC, {14524LU}}, /* .typeId */
24685 {0, UA_NODEIDTYPE_NUMERIC, {14839LU}}, /* .binaryEncodingId */
24686 sizeof(UA_FieldMetaData), /* .memSize */
24687 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24688 false, /* .pointerFree */
24689 false, /* .overlayable */
24690 10, /* .membersSize */
24691 FieldMetaData_members /* .members */
24692},
24693/* PublishedEventsDataType */
24694{
24695 UA_TYPENAME("PublishedEventsDataType") /* .typeName */
24696 {0, UA_NODEIDTYPE_NUMERIC, {15582LU}}, /* .typeId */
24697 {0, UA_NODEIDTYPE_NUMERIC, {15681LU}}, /* .binaryEncodingId */
24698 sizeof(UA_PublishedEventsDataType), /* .memSize */
24699 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24700 false, /* .pointerFree */
24701 false, /* .overlayable */
24702 3, /* .membersSize */
24703 PublishedEventsDataType_members /* .members */
24704},
24705/* PubSubGroupDataType */
24706{
24707 UA_TYPENAME("PubSubGroupDataType") /* .typeName */
24708 {0, UA_NODEIDTYPE_NUMERIC, {15609LU}}, /* .typeId */
24709 {0, UA_NODEIDTYPE_NUMERIC, {15689LU}}, /* .binaryEncodingId */
24710 sizeof(UA_PubSubGroupDataType), /* .memSize */
24711 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24712 false, /* .pointerFree */
24713 false, /* .overlayable */
24714 7, /* .membersSize */
24715 PubSubGroupDataType_members /* .members */
24716},
24717/* WriterGroupDataType */
24718{
24719 UA_TYPENAME("WriterGroupDataType") /* .typeName */
24720 {0, UA_NODEIDTYPE_NUMERIC, {15480LU}}, /* .typeId */
24721 {0, UA_NODEIDTYPE_NUMERIC, {21150LU}}, /* .binaryEncodingId */
24722 sizeof(UA_WriterGroupDataType), /* .memSize */
24723 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24724 false, /* .pointerFree */
24725 false, /* .overlayable */
24726 16, /* .membersSize */
24727 WriterGroupDataType_members /* .members */
24728},
24729/* FieldTargetDataType */
24730{
24731 UA_TYPENAME("FieldTargetDataType") /* .typeName */
24732 {0, UA_NODEIDTYPE_NUMERIC, {14744LU}}, /* .typeId */
24733 {0, UA_NODEIDTYPE_NUMERIC, {14848LU}}, /* .binaryEncodingId */
24734 sizeof(UA_FieldTargetDataType), /* .memSize */
24735 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24736 false, /* .pointerFree */
24737 false, /* .overlayable */
24738 7, /* .membersSize */
24739 FieldTargetDataType_members /* .members */
24740},
24741/* SubscribedDataSetMirrorDataType */
24742{
24743 UA_TYPENAME("SubscribedDataSetMirrorDataType") /* .typeName */
24744 {0, UA_NODEIDTYPE_NUMERIC, {15635LU}}, /* .typeId */
24745 {0, UA_NODEIDTYPE_NUMERIC, {15713LU}}, /* .binaryEncodingId */
24746 sizeof(UA_SubscribedDataSetMirrorDataType), /* .memSize */
24747 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24748 false, /* .pointerFree */
24749 false, /* .overlayable */
24750 2, /* .membersSize */
24751 SubscribedDataSetMirrorDataType_members /* .members */
24752},
24753/* SecurityGroupDataType */
24754{
24755 UA_TYPENAME("SecurityGroupDataType") /* .typeName */
24756 {0, UA_NODEIDTYPE_NUMERIC, {23601LU}}, /* .typeId */
24757 {0, UA_NODEIDTYPE_NUMERIC, {23853LU}}, /* .binaryEncodingId */
24758 sizeof(UA_SecurityGroupDataType), /* .memSize */
24759 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24760 false, /* .pointerFree */
24761 false, /* .overlayable */
24762 9, /* .membersSize */
24763 SecurityGroupDataType_members /* .members */
24764},
24765/* PubSubKeyPushTargetDataType */
24766{
24767 UA_TYPENAME("PubSubKeyPushTargetDataType") /* .typeName */
24768 {0, UA_NODEIDTYPE_NUMERIC, {25270LU}}, /* .typeId */
24769 {0, UA_NODEIDTYPE_NUMERIC, {25530LU}}, /* .binaryEncodingId */
24770 sizeof(UA_PubSubKeyPushTargetDataType), /* .memSize */
24771 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24772 false, /* .pointerFree */
24773 false, /* .overlayable */
24774 9, /* .membersSize */
24775 PubSubKeyPushTargetDataType_members /* .members */
24776},
24777/* EnumDefinition */
24778{
24779 UA_TYPENAME("EnumDefinition") /* .typeName */
24780 {0, UA_NODEIDTYPE_NUMERIC, {100LU}}, /* .typeId */
24781 {0, UA_NODEIDTYPE_NUMERIC, {123LU}}, /* .binaryEncodingId */
24782 sizeof(UA_EnumDefinition), /* .memSize */
24783 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24784 false, /* .pointerFree */
24785 false, /* .overlayable */
24786 1, /* .membersSize */
24787 EnumDefinition_members /* .members */
24788},
24789/* ReadEventDetails */
24790{
24791 UA_TYPENAME("ReadEventDetails") /* .typeName */
24792 {0, UA_NODEIDTYPE_NUMERIC, {644LU}}, /* .typeId */
24793 {0, UA_NODEIDTYPE_NUMERIC, {646LU}}, /* .binaryEncodingId */
24794 sizeof(UA_ReadEventDetails), /* .memSize */
24795 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24796 false, /* .pointerFree */
24797 false, /* .overlayable */
24798 4, /* .membersSize */
24799 ReadEventDetails_members /* .members */
24800},
24801/* ReadProcessedDetails */
24802{
24803 UA_TYPENAME("ReadProcessedDetails") /* .typeName */
24804 {0, UA_NODEIDTYPE_NUMERIC, {650LU}}, /* .typeId */
24805 {0, UA_NODEIDTYPE_NUMERIC, {652LU}}, /* .binaryEncodingId */
24806 sizeof(UA_ReadProcessedDetails), /* .memSize */
24807 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24808 false, /* .pointerFree */
24809 false, /* .overlayable */
24810 5, /* .membersSize */
24811 ReadProcessedDetails_members /* .members */
24812},
24813/* ModificationInfo */
24814{
24815 UA_TYPENAME("ModificationInfo") /* .typeName */
24816 {0, UA_NODEIDTYPE_NUMERIC, {11216LU}}, /* .typeId */
24817 {0, UA_NODEIDTYPE_NUMERIC, {11226LU}}, /* .binaryEncodingId */
24818 sizeof(UA_ModificationInfo), /* .memSize */
24819 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24820 false, /* .pointerFree */
24821 false, /* .overlayable */
24822 3, /* .membersSize */
24823 ModificationInfo_members /* .members */
24824},
24825/* HistoryModifiedData */
24826{
24827 UA_TYPENAME("HistoryModifiedData") /* .typeName */
24828 {0, UA_NODEIDTYPE_NUMERIC, {11217LU}}, /* .typeId */
24829 {0, UA_NODEIDTYPE_NUMERIC, {11227LU}}, /* .binaryEncodingId */
24830 sizeof(UA_HistoryModifiedData), /* .memSize */
24831 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24832 false, /* .pointerFree */
24833 false, /* .overlayable */
24834 2, /* .membersSize */
24835 HistoryModifiedData_members /* .members */
24836},
24837/* HistoryEvent */
24838{
24839 UA_TYPENAME("HistoryEvent") /* .typeName */
24840 {0, UA_NODEIDTYPE_NUMERIC, {659LU}}, /* .typeId */
24841 {0, UA_NODEIDTYPE_NUMERIC, {661LU}}, /* .binaryEncodingId */
24842 sizeof(UA_HistoryEvent), /* .memSize */
24843 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24844 false, /* .pointerFree */
24845 false, /* .overlayable */
24846 1, /* .membersSize */
24847 HistoryEvent_members /* .members */
24848},
24849/* UpdateEventDetails */
24850{
24851 UA_TYPENAME("UpdateEventDetails") /* .typeName */
24852 {0, UA_NODEIDTYPE_NUMERIC, {683LU}}, /* .typeId */
24853 {0, UA_NODEIDTYPE_NUMERIC, {685LU}}, /* .binaryEncodingId */
24854 sizeof(UA_UpdateEventDetails), /* .memSize */
24855 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24856 false, /* .pointerFree */
24857 false, /* .overlayable */
24858 4, /* .membersSize */
24859 UpdateEventDetails_members /* .members */
24860},
24861/* DataChangeNotification */
24862{
24863 UA_TYPENAME("DataChangeNotification") /* .typeName */
24864 {0, UA_NODEIDTYPE_NUMERIC, {809LU}}, /* .typeId */
24865 {0, UA_NODEIDTYPE_NUMERIC, {811LU}}, /* .binaryEncodingId */
24866 sizeof(UA_DataChangeNotification), /* .memSize */
24867 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24868 false, /* .pointerFree */
24869 false, /* .overlayable */
24870 2, /* .membersSize */
24871 DataChangeNotification_members /* .members */
24872},
24873/* EventNotificationList */
24874{
24875 UA_TYPENAME("EventNotificationList") /* .typeName */
24876 {0, UA_NODEIDTYPE_NUMERIC, {914LU}}, /* .typeId */
24877 {0, UA_NODEIDTYPE_NUMERIC, {916LU}}, /* .binaryEncodingId */
24878 sizeof(UA_EventNotificationList), /* .memSize */
24879 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24880 false, /* .pointerFree */
24881 false, /* .overlayable */
24882 1, /* .membersSize */
24883 EventNotificationList_members /* .members */
24884},
24885/* SessionDiagnosticsDataType */
24886{
24887 UA_TYPENAME("SessionDiagnosticsDataType") /* .typeName */
24888 {0, UA_NODEIDTYPE_NUMERIC, {865LU}}, /* .typeId */
24889 {0, UA_NODEIDTYPE_NUMERIC, {867LU}}, /* .binaryEncodingId */
24890 sizeof(UA_SessionDiagnosticsDataType), /* .memSize */
24891 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24892 false, /* .pointerFree */
24893 false, /* .overlayable */
24894 43, /* .membersSize */
24895 SessionDiagnosticsDataType_members /* .members */
24896},
24897/* EnumDescription */
24898{
24899 UA_TYPENAME("EnumDescription") /* .typeName */
24900 {0, UA_NODEIDTYPE_NUMERIC, {15488LU}}, /* .typeId */
24901 {0, UA_NODEIDTYPE_NUMERIC, {127LU}}, /* .binaryEncodingId */
24902 sizeof(UA_EnumDescription), /* .memSize */
24903 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24904 false, /* .pointerFree */
24905 false, /* .overlayable */
24906 4, /* .membersSize */
24907 EnumDescription_members /* .members */
24908},
24909/* UABinaryFileDataType */
24910{
24911 UA_TYPENAME("UABinaryFileDataType") /* .typeName */
24912 {0, UA_NODEIDTYPE_NUMERIC, {15006LU}}, /* .typeId */
24913 {0, UA_NODEIDTYPE_NUMERIC, {15422LU}}, /* .binaryEncodingId */
24914 sizeof(UA_UABinaryFileDataType), /* .memSize */
24915 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24916 false, /* .pointerFree */
24917 false, /* .overlayable */
24918 7, /* .membersSize */
24919 UABinaryFileDataType_members /* .members */
24920},
24921/* DataSetMetaDataType */
24922{
24923 UA_TYPENAME("DataSetMetaDataType") /* .typeName */
24924 {0, UA_NODEIDTYPE_NUMERIC, {14523LU}}, /* .typeId */
24925 {0, UA_NODEIDTYPE_NUMERIC, {124LU}}, /* .binaryEncodingId */
24926 sizeof(UA_DataSetMetaDataType), /* .memSize */
24927 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24928 false, /* .pointerFree */
24929 false, /* .overlayable */
24930 9, /* .membersSize */
24931 DataSetMetaDataType_members /* .members */
24932},
24933/* PublishedDataSetDataType */
24934{
24935 UA_TYPENAME("PublishedDataSetDataType") /* .typeName */
24936 {0, UA_NODEIDTYPE_NUMERIC, {15578LU}}, /* .typeId */
24937 {0, UA_NODEIDTYPE_NUMERIC, {15677LU}}, /* .binaryEncodingId */
24938 sizeof(UA_PublishedDataSetDataType), /* .memSize */
24939 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24940 false, /* .pointerFree */
24941 false, /* .overlayable */
24942 5, /* .membersSize */
24943 PublishedDataSetDataType_members /* .members */
24944},
24945/* DataSetReaderDataType */
24946{
24947 UA_TYPENAME("DataSetReaderDataType") /* .typeName */
24948 {0, UA_NODEIDTYPE_NUMERIC, {15623LU}}, /* .typeId */
24949 {0, UA_NODEIDTYPE_NUMERIC, {15703LU}}, /* .binaryEncodingId */
24950 sizeof(UA_DataSetReaderDataType), /* .memSize */
24951 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24952 false, /* .pointerFree */
24953 false, /* .overlayable */
24954 17, /* .membersSize */
24955 DataSetReaderDataType_members /* .members */
24956},
24957/* TargetVariablesDataType */
24958{
24959 UA_TYPENAME("TargetVariablesDataType") /* .typeName */
24960 {0, UA_NODEIDTYPE_NUMERIC, {15631LU}}, /* .typeId */
24961 {0, UA_NODEIDTYPE_NUMERIC, {15712LU}}, /* .binaryEncodingId */
24962 sizeof(UA_TargetVariablesDataType), /* .memSize */
24963 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24964 false, /* .pointerFree */
24965 false, /* .overlayable */
24966 1, /* .membersSize */
24967 TargetVariablesDataType_members /* .members */
24968},
24969/* StandaloneSubscribedDataSetDataType */
24970{
24971 UA_TYPENAME("StandaloneSubscribedDataSetDataType") /* .typeName */
24972 {0, UA_NODEIDTYPE_NUMERIC, {23600LU}}, /* .typeId */
24973 {0, UA_NODEIDTYPE_NUMERIC, {23852LU}}, /* .binaryEncodingId */
24974 sizeof(UA_StandaloneSubscribedDataSetDataType), /* .memSize */
24975 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24976 false, /* .pointerFree */
24977 false, /* .overlayable */
24978 4, /* .membersSize */
24979 StandaloneSubscribedDataSetDataType_members /* .members */
24980},
24981/* DataTypeSchemaHeader */
24982{
24983 UA_TYPENAME("DataTypeSchemaHeader") /* .typeName */
24984 {0, UA_NODEIDTYPE_NUMERIC, {15534LU}}, /* .typeId */
24985 {0, UA_NODEIDTYPE_NUMERIC, {15676LU}}, /* .binaryEncodingId */
24986 sizeof(UA_DataTypeSchemaHeader), /* .memSize */
24987 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
24988 false, /* .pointerFree */
24989 false, /* .overlayable */
24990 4, /* .membersSize */
24991 DataTypeSchemaHeader_members /* .members */
24992},
24993/* ReaderGroupDataType */
24994{
24995 UA_TYPENAME("ReaderGroupDataType") /* .typeName */
24996 {0, UA_NODEIDTYPE_NUMERIC, {15520LU}}, /* .typeId */
24997 {0, UA_NODEIDTYPE_NUMERIC, {21153LU}}, /* .binaryEncodingId */
24998 sizeof(UA_ReaderGroupDataType), /* .memSize */
24999 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
25000 false, /* .pointerFree */
25001 false, /* .overlayable */
25002 10, /* .membersSize */
25003 ReaderGroupDataType_members /* .members */
25004},
25005/* PubSubConnectionDataType */
25006{
25007 UA_TYPENAME("PubSubConnectionDataType") /* .typeName */
25008 {0, UA_NODEIDTYPE_NUMERIC, {15617LU}}, /* .typeId */
25009 {0, UA_NODEIDTYPE_NUMERIC, {15694LU}}, /* .binaryEncodingId */
25010 sizeof(UA_PubSubConnectionDataType), /* .memSize */
25011 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
25012 false, /* .pointerFree */
25013 false, /* .overlayable */
25014 9, /* .membersSize */
25015 PubSubConnectionDataType_members /* .members */
25016},
25017/* PubSubConfigurationDataType */
25018{
25019 UA_TYPENAME("PubSubConfigurationDataType") /* .typeName */
25020 {0, UA_NODEIDTYPE_NUMERIC, {15530LU}}, /* .typeId */
25021 {0, UA_NODEIDTYPE_NUMERIC, {21154LU}}, /* .binaryEncodingId */
25022 sizeof(UA_PubSubConfigurationDataType), /* .memSize */
25023 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
25024 false, /* .pointerFree */
25025 false, /* .overlayable */
25026 3, /* .membersSize */
25027 PubSubConfigurationDataType_members /* .members */
25028},
25029/* PubSubConfiguration2DataType */
25030{
25031 UA_TYPENAME("PubSubConfiguration2DataType") /* .typeName */
25032 {0, UA_NODEIDTYPE_NUMERIC, {23602LU}}, /* .typeId */
25033 {0, UA_NODEIDTYPE_NUMERIC, {23854LU}}, /* .binaryEncodingId */
25034 sizeof(UA_PubSubConfiguration2DataType), /* .memSize */
25035 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
25036 false, /* .pointerFree */
25037 false, /* .overlayable */
25038 10, /* .membersSize */
25039 PubSubConfiguration2DataType_members /* .members */
25040},
25041};
25042
25043
25044/**** amalgamated original file "/build/src_generated/open62541/transport_generated.c" ****/
25045
25046/**********************************
25047 * Autogenerated -- do not modify *
25048 **********************************/
25049
25050
25051/* MessageType */
25052#define MessageType_members NULL
25053
25054/* ChunkType */
25055#define ChunkType_members NULL
25056
25057/* TcpMessageHeader */
25058static UA_DataTypeMember TcpMessageHeader_members[2] = {
25059{
25060 UA_TYPENAME("MessageTypeAndChunkType") /* .memberName */
25061 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25062 0, /* .padding */
25063 false, /* .isArray */
25064 false /* .isOptional */
25065},
25066{
25067 UA_TYPENAME("MessageSize") /* .memberName */
25068 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25069 offsetof(UA_TcpMessageHeader, messageSize) - offsetof(UA_TcpMessageHeader, messageTypeAndChunkType) - sizeof(UA_UInt32), /* .padding */
25070 false, /* .isArray */
25071 false /* .isOptional */
25072},};
25073
25074/* TcpHelloMessage */
25075static UA_DataTypeMember TcpHelloMessage_members[6] = {
25076{
25077 UA_TYPENAME("ProtocolVersion") /* .memberName */
25078 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25079 0, /* .padding */
25080 false, /* .isArray */
25081 false /* .isOptional */
25082},
25083{
25084 UA_TYPENAME("ReceiveBufferSize") /* .memberName */
25085 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25086 offsetof(UA_TcpHelloMessage, receiveBufferSize) - offsetof(UA_TcpHelloMessage, protocolVersion) - sizeof(UA_UInt32), /* .padding */
25087 false, /* .isArray */
25088 false /* .isOptional */
25089},
25090{
25091 UA_TYPENAME("SendBufferSize") /* .memberName */
25092 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25093 offsetof(UA_TcpHelloMessage, sendBufferSize) - offsetof(UA_TcpHelloMessage, receiveBufferSize) - sizeof(UA_UInt32), /* .padding */
25094 false, /* .isArray */
25095 false /* .isOptional */
25096},
25097{
25098 UA_TYPENAME("MaxMessageSize") /* .memberName */
25099 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25100 offsetof(UA_TcpHelloMessage, maxMessageSize) - offsetof(UA_TcpHelloMessage, sendBufferSize) - sizeof(UA_UInt32), /* .padding */
25101 false, /* .isArray */
25102 false /* .isOptional */
25103},
25104{
25105 UA_TYPENAME("MaxChunkCount") /* .memberName */
25106 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25107 offsetof(UA_TcpHelloMessage, maxChunkCount) - offsetof(UA_TcpHelloMessage, maxMessageSize) - sizeof(UA_UInt32), /* .padding */
25108 false, /* .isArray */
25109 false /* .isOptional */
25110},
25111{
25112 UA_TYPENAME("EndpointUrl") /* .memberName */
25113 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
25114 offsetof(UA_TcpHelloMessage, endpointUrl) - offsetof(UA_TcpHelloMessage, maxChunkCount) - sizeof(UA_UInt32), /* .padding */
25115 false, /* .isArray */
25116 false /* .isOptional */
25117},};
25118
25119/* TcpReverseHelloMessage */
25120static UA_DataTypeMember TcpReverseHelloMessage_members[2] = {
25121{
25122 UA_TYPENAME("ServerUri") /* .memberName */
25123 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
25124 0, /* .padding */
25125 false, /* .isArray */
25126 false /* .isOptional */
25127},
25128{
25129 UA_TYPENAME("EndpointUrl") /* .memberName */
25130 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
25131 offsetof(UA_TcpReverseHelloMessage, endpointUrl) - offsetof(UA_TcpReverseHelloMessage, serverUri) - sizeof(UA_String), /* .padding */
25132 false, /* .isArray */
25133 false /* .isOptional */
25134},};
25135
25136/* TcpAcknowledgeMessage */
25137static UA_DataTypeMember TcpAcknowledgeMessage_members[5] = {
25138{
25139 UA_TYPENAME("ProtocolVersion") /* .memberName */
25140 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25141 0, /* .padding */
25142 false, /* .isArray */
25143 false /* .isOptional */
25144},
25145{
25146 UA_TYPENAME("ReceiveBufferSize") /* .memberName */
25147 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25148 offsetof(UA_TcpAcknowledgeMessage, receiveBufferSize) - offsetof(UA_TcpAcknowledgeMessage, protocolVersion) - sizeof(UA_UInt32), /* .padding */
25149 false, /* .isArray */
25150 false /* .isOptional */
25151},
25152{
25153 UA_TYPENAME("SendBufferSize") /* .memberName */
25154 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25155 offsetof(UA_TcpAcknowledgeMessage, sendBufferSize) - offsetof(UA_TcpAcknowledgeMessage, receiveBufferSize) - sizeof(UA_UInt32), /* .padding */
25156 false, /* .isArray */
25157 false /* .isOptional */
25158},
25159{
25160 UA_TYPENAME("MaxMessageSize") /* .memberName */
25161 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25162 offsetof(UA_TcpAcknowledgeMessage, maxMessageSize) - offsetof(UA_TcpAcknowledgeMessage, sendBufferSize) - sizeof(UA_UInt32), /* .padding */
25163 false, /* .isArray */
25164 false /* .isOptional */
25165},
25166{
25167 UA_TYPENAME("MaxChunkCount") /* .memberName */
25168 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25169 offsetof(UA_TcpAcknowledgeMessage, maxChunkCount) - offsetof(UA_TcpAcknowledgeMessage, maxMessageSize) - sizeof(UA_UInt32), /* .padding */
25170 false, /* .isArray */
25171 false /* .isOptional */
25172},};
25173
25174/* TcpErrorMessage */
25175static UA_DataTypeMember TcpErrorMessage_members[2] = {
25176{
25177 UA_TYPENAME("Error") /* .memberName */
25178 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25179 0, /* .padding */
25180 false, /* .isArray */
25181 false /* .isOptional */
25182},
25183{
25184 UA_TYPENAME("Reason") /* .memberName */
25185 &UA_TYPES[UA_TYPES_STRING], /* .memberType */
25186 offsetof(UA_TcpErrorMessage, reason) - offsetof(UA_TcpErrorMessage, error) - sizeof(UA_UInt32), /* .padding */
25187 false, /* .isArray */
25188 false /* .isOptional */
25189},};
25190
25191/* AsymmetricAlgorithmSecurityHeader */
25192static UA_DataTypeMember AsymmetricAlgorithmSecurityHeader_members[3] = {
25193{
25194 UA_TYPENAME("SecurityPolicyUri") /* .memberName */
25195 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
25196 0, /* .padding */
25197 false, /* .isArray */
25198 false /* .isOptional */
25199},
25200{
25201 UA_TYPENAME("SenderCertificate") /* .memberName */
25202 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
25203 offsetof(UA_AsymmetricAlgorithmSecurityHeader, senderCertificate) - offsetof(UA_AsymmetricAlgorithmSecurityHeader, securityPolicyUri) - sizeof(UA_ByteString), /* .padding */
25204 false, /* .isArray */
25205 false /* .isOptional */
25206},
25207{
25208 UA_TYPENAME("ReceiverCertificateThumbprint") /* .memberName */
25209 &UA_TYPES[UA_TYPES_BYTESTRING], /* .memberType */
25210 offsetof(UA_AsymmetricAlgorithmSecurityHeader, receiverCertificateThumbprint) - offsetof(UA_AsymmetricAlgorithmSecurityHeader, senderCertificate) - sizeof(UA_ByteString), /* .padding */
25211 false, /* .isArray */
25212 false /* .isOptional */
25213},};
25214
25215/* SequenceHeader */
25216static UA_DataTypeMember SequenceHeader_members[2] = {
25217{
25218 UA_TYPENAME("SequenceNumber") /* .memberName */
25219 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25220 0, /* .padding */
25221 false, /* .isArray */
25222 false /* .isOptional */
25223},
25224{
25225 UA_TYPENAME("RequestId") /* .memberName */
25226 &UA_TYPES[UA_TYPES_UINT32], /* .memberType */
25227 offsetof(UA_SequenceHeader, requestId) - offsetof(UA_SequenceHeader, sequenceNumber) - sizeof(UA_UInt32), /* .padding */
25228 false, /* .isArray */
25229 false /* .isOptional */
25230},};
25231UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = {
25232/* MessageType */
25233{
25234 UA_TYPENAME("MessageType") /* .typeName */
25235 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */
25236 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
25237 sizeof(UA_MessageType), /* .memSize */
25238 UA_DATATYPEKIND_ENUM, /* .typeKind */
25239 true, /* .pointerFree */
25240 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
25241 0, /* .membersSize */
25242 MessageType_members /* .members */
25243},
25244/* ChunkType */
25245{
25246 UA_TYPENAME("ChunkType") /* .typeName */
25247 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */
25248 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
25249 sizeof(UA_ChunkType), /* .memSize */
25250 UA_DATATYPEKIND_ENUM, /* .typeKind */
25251 true, /* .pointerFree */
25252 UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */
25253 0, /* .membersSize */
25254 ChunkType_members /* .members */
25255},
25256/* TcpMessageHeader */
25257{
25258 UA_TYPENAME("TcpMessageHeader") /* .typeName */
25259 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */
25260 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
25261 sizeof(UA_TcpMessageHeader), /* .memSize */
25262 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
25263 true, /* .pointerFree */
25264 false, /* .overlayable */
25265 2, /* .membersSize */
25266 TcpMessageHeader_members /* .members */
25267},
25268/* TcpHelloMessage */
25269{
25270 UA_TYPENAME("TcpHelloMessage") /* .typeName */
25271 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */
25272 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
25273 sizeof(UA_TcpHelloMessage), /* .memSize */
25274 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
25275 false, /* .pointerFree */
25276 false, /* .overlayable */
25277 6, /* .membersSize */
25278 TcpHelloMessage_members /* .members */
25279},
25280/* TcpReverseHelloMessage */
25281{
25282 UA_TYPENAME("TcpReverseHelloMessage") /* .typeName */
25283 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */
25284 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
25285 sizeof(UA_TcpReverseHelloMessage), /* .memSize */
25286 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
25287 false, /* .pointerFree */
25288 false, /* .overlayable */
25289 2, /* .membersSize */
25290 TcpReverseHelloMessage_members /* .members */
25291},
25292/* TcpAcknowledgeMessage */
25293{
25294 UA_TYPENAME("TcpAcknowledgeMessage") /* .typeName */
25295 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */
25296 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
25297 sizeof(UA_TcpAcknowledgeMessage), /* .memSize */
25298 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
25299 true, /* .pointerFree */
25300 false, /* .overlayable */
25301 5, /* .membersSize */
25302 TcpAcknowledgeMessage_members /* .members */
25303},
25304/* TcpErrorMessage */
25305{
25306 UA_TYPENAME("TcpErrorMessage") /* .typeName */
25307 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */
25308 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
25309 sizeof(UA_TcpErrorMessage), /* .memSize */
25310 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
25311 false, /* .pointerFree */
25312 false, /* .overlayable */
25313 2, /* .membersSize */
25314 TcpErrorMessage_members /* .members */
25315},
25316/* AsymmetricAlgorithmSecurityHeader */
25317{
25318 UA_TYPENAME("AsymmetricAlgorithmSecurityHeader") /* .typeName */
25319 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */
25320 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
25321 sizeof(UA_AsymmetricAlgorithmSecurityHeader), /* .memSize */
25322 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
25323 false, /* .pointerFree */
25324 false, /* .overlayable */
25325 3, /* .membersSize */
25326 AsymmetricAlgorithmSecurityHeader_members /* .members */
25327},
25328/* SequenceHeader */
25329{
25330 UA_TYPENAME("SequenceHeader") /* .typeName */
25331 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */
25332 {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .binaryEncodingId */
25333 sizeof(UA_SequenceHeader), /* .memSize */
25334 UA_DATATYPEKIND_STRUCTURE, /* .typeKind */
25335 true, /* .pointerFree */
25336 false, /* .overlayable */
25337 2, /* .membersSize */
25338 SequenceHeader_members /* .members */
25339},
25340};
25341
25342
25343/**** amalgamated original file "/build/src_generated/open62541/statuscodes.c" ****/
25344
25345/**********************************
25346 * Autogenerated -- do not modify *
25347 **********************************/
25348
25349
25350typedef struct {
25351 UA_StatusCode code;
25352 const char *name;
25353} UA_StatusCodeName;
25354
25355#ifndef UA_ENABLE_STATUSCODE_DESCRIPTIONS
25356static const char * emptyStatusCodeName = "";
25357const char * UA_StatusCode_name(UA_StatusCode code) {
25358 return emptyStatusCodeName;
25359}
25360#else
25361static const size_t statusCodeDescriptionsSize = 252;
25362static const UA_StatusCodeName statusCodeDescriptions[252] = {
25363 {UA_STATUSCODE_GOOD, "Good"},
25364 {UA_STATUSCODE_GOOD, "Good"},
25365 {UA_STATUSCODE_UNCERTAIN, "Uncertain"},
25366 {UA_STATUSCODE_BAD, "Bad"},
25367 {UA_STATUSCODE_BADUNEXPECTEDERROR, "BadUnexpectedError"},
25368 {UA_STATUSCODE_BADINTERNALERROR, "BadInternalError"},
25369 {UA_STATUSCODE_BADOUTOFMEMORY, "BadOutOfMemory"},
25370 {UA_STATUSCODE_BADRESOURCEUNAVAILABLE, "BadResourceUnavailable"},
25371 {UA_STATUSCODE_BADCOMMUNICATIONERROR, "BadCommunicationError"},
25372 {UA_STATUSCODE_BADENCODINGERROR, "BadEncodingError"},
25373 {UA_STATUSCODE_BADDECODINGERROR, "BadDecodingError"},
25374 {UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED, "BadEncodingLimitsExceeded"},
25375 {UA_STATUSCODE_BADREQUESTTOOLARGE, "BadRequestTooLarge"},
25376 {UA_STATUSCODE_BADRESPONSETOOLARGE, "BadResponseTooLarge"},
25377 {UA_STATUSCODE_BADUNKNOWNRESPONSE, "BadUnknownResponse"},
25378 {UA_STATUSCODE_BADTIMEOUT, "BadTimeout"},
25379 {UA_STATUSCODE_BADSERVICEUNSUPPORTED, "BadServiceUnsupported"},
25380 {UA_STATUSCODE_BADSHUTDOWN, "BadShutdown"},
25381 {UA_STATUSCODE_BADSERVERNOTCONNECTED, "BadServerNotConnected"},
25382 {UA_STATUSCODE_BADSERVERHALTED, "BadServerHalted"},
25383 {UA_STATUSCODE_BADNOTHINGTODO, "BadNothingToDo"},
25384 {UA_STATUSCODE_BADTOOMANYOPERATIONS, "BadTooManyOperations"},
25385 {UA_STATUSCODE_BADTOOMANYMONITOREDITEMS, "BadTooManyMonitoredItems"},
25386 {UA_STATUSCODE_BADDATATYPEIDUNKNOWN, "BadDataTypeIdUnknown"},
25387 {UA_STATUSCODE_BADCERTIFICATEINVALID, "BadCertificateInvalid"},
25388 {UA_STATUSCODE_BADSECURITYCHECKSFAILED, "BadSecurityChecksFailed"},
25389 {UA_STATUSCODE_BADCERTIFICATEPOLICYCHECKFAILED, "BadCertificatePolicyCheckFailed"},
25390 {UA_STATUSCODE_BADCERTIFICATETIMEINVALID, "BadCertificateTimeInvalid"},
25391 {UA_STATUSCODE_BADCERTIFICATEISSUERTIMEINVALID, "BadCertificateIssuerTimeInvalid"},
25392 {UA_STATUSCODE_BADCERTIFICATEHOSTNAMEINVALID, "BadCertificateHostNameInvalid"},
25393 {UA_STATUSCODE_BADCERTIFICATEURIINVALID, "BadCertificateUriInvalid"},
25394 {UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED, "BadCertificateUseNotAllowed"},
25395 {UA_STATUSCODE_BADCERTIFICATEISSUERUSENOTALLOWED, "BadCertificateIssuerUseNotAllowed"},
25396 {UA_STATUSCODE_BADCERTIFICATEUNTRUSTED, "BadCertificateUntrusted"},
25397 {UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN, "BadCertificateRevocationUnknown"},
25398 {UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN, "BadCertificateIssuerRevocationUnknown"},
25399 {UA_STATUSCODE_BADCERTIFICATEREVOKED, "BadCertificateRevoked"},
25400 {UA_STATUSCODE_BADCERTIFICATEISSUERREVOKED, "BadCertificateIssuerRevoked"},
25401 {UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE, "BadCertificateChainIncomplete"},
25402 {UA_STATUSCODE_BADUSERACCESSDENIED, "BadUserAccessDenied"},
25403 {UA_STATUSCODE_BADIDENTITYTOKENINVALID, "BadIdentityTokenInvalid"},
25404 {UA_STATUSCODE_BADIDENTITYTOKENREJECTED, "BadIdentityTokenRejected"},
25405 {UA_STATUSCODE_BADSECURECHANNELIDINVALID, "BadSecureChannelIdInvalid"},
25406 {UA_STATUSCODE_BADINVALIDTIMESTAMP, "BadInvalidTimestamp"},
25407 {UA_STATUSCODE_BADNONCEINVALID, "BadNonceInvalid"},
25408 {UA_STATUSCODE_BADSESSIONIDINVALID, "BadSessionIdInvalid"},
25409 {UA_STATUSCODE_BADSESSIONCLOSED, "BadSessionClosed"},
25410 {UA_STATUSCODE_BADSESSIONNOTACTIVATED, "BadSessionNotActivated"},
25411 {UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID, "BadSubscriptionIdInvalid"},
25412 {UA_STATUSCODE_BADREQUESTHEADERINVALID, "BadRequestHeaderInvalid"},
25413 {UA_STATUSCODE_BADTIMESTAMPSTORETURNINVALID, "BadTimestampsToReturnInvalid"},
25414 {UA_STATUSCODE_BADREQUESTCANCELLEDBYCLIENT, "BadRequestCancelledByClient"},
25415 {UA_STATUSCODE_BADTOOMANYARGUMENTS, "BadTooManyArguments"},
25416 {UA_STATUSCODE_BADLICENSEEXPIRED, "BadLicenseExpired"},
25417 {UA_STATUSCODE_BADLICENSELIMITSEXCEEDED, "BadLicenseLimitsExceeded"},
25418 {UA_STATUSCODE_BADLICENSENOTAVAILABLE, "BadLicenseNotAvailable"},
25419 {UA_STATUSCODE_GOODSUBSCRIPTIONTRANSFERRED, "GoodSubscriptionTransferred"},
25420 {UA_STATUSCODE_GOODCOMPLETESASYNCHRONOUSLY, "GoodCompletesAsynchronously"},
25421 {UA_STATUSCODE_GOODOVERLOAD, "GoodOverload"},
25422 {UA_STATUSCODE_GOODCLAMPED, "GoodClamped"},
25423 {UA_STATUSCODE_BADNOCOMMUNICATION, "BadNoCommunication"},
25424 {UA_STATUSCODE_BADWAITINGFORINITIALDATA, "BadWaitingForInitialData"},
25425 {UA_STATUSCODE_BADNODEIDINVALID, "BadNodeIdInvalid"},
25426 {UA_STATUSCODE_BADNODEIDUNKNOWN, "BadNodeIdUnknown"},
25427 {UA_STATUSCODE_BADATTRIBUTEIDINVALID, "BadAttributeIdInvalid"},
25428 {UA_STATUSCODE_BADINDEXRANGEINVALID, "BadIndexRangeInvalid"},
25429 {UA_STATUSCODE_BADINDEXRANGENODATA, "BadIndexRangeNoData"},
25430 {UA_STATUSCODE_BADDATAENCODINGINVALID, "BadDataEncodingInvalid"},
25431 {UA_STATUSCODE_BADDATAENCODINGUNSUPPORTED, "BadDataEncodingUnsupported"},
25432 {UA_STATUSCODE_BADNOTREADABLE, "BadNotReadable"},
25433 {UA_STATUSCODE_BADNOTWRITABLE, "BadNotWritable"},
25434 {UA_STATUSCODE_BADOUTOFRANGE, "BadOutOfRange"},
25435 {UA_STATUSCODE_BADNOTSUPPORTED, "BadNotSupported"},
25436 {UA_STATUSCODE_BADNOTFOUND, "BadNotFound"},
25437 {UA_STATUSCODE_BADOBJECTDELETED, "BadObjectDeleted"},
25438 {UA_STATUSCODE_BADNOTIMPLEMENTED, "BadNotImplemented"},
25439 {UA_STATUSCODE_BADMONITORINGMODEINVALID, "BadMonitoringModeInvalid"},
25440 {UA_STATUSCODE_BADMONITOREDITEMIDINVALID, "BadMonitoredItemIdInvalid"},
25441 {UA_STATUSCODE_BADMONITOREDITEMFILTERINVALID, "BadMonitoredItemFilterInvalid"},
25442 {UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED, "BadMonitoredItemFilterUnsupported"},
25443 {UA_STATUSCODE_BADFILTERNOTALLOWED, "BadFilterNotAllowed"},
25444 {UA_STATUSCODE_BADSTRUCTUREMISSING, "BadStructureMissing"},
25445 {UA_STATUSCODE_BADEVENTFILTERINVALID, "BadEventFilterInvalid"},
25446 {UA_STATUSCODE_BADCONTENTFILTERINVALID, "BadContentFilterInvalid"},
25447 {UA_STATUSCODE_BADFILTEROPERATORINVALID, "BadFilterOperatorInvalid"},
25448 {UA_STATUSCODE_BADFILTEROPERATORUNSUPPORTED, "BadFilterOperatorUnsupported"},
25449 {UA_STATUSCODE_BADFILTEROPERANDCOUNTMISMATCH, "BadFilterOperandCountMismatch"},
25450 {UA_STATUSCODE_BADFILTEROPERANDINVALID, "BadFilterOperandInvalid"},
25451 {UA_STATUSCODE_BADFILTERELEMENTINVALID, "BadFilterElementInvalid"},
25452 {UA_STATUSCODE_BADFILTERLITERALINVALID, "BadFilterLiteralInvalid"},
25453 {UA_STATUSCODE_BADCONTINUATIONPOINTINVALID, "BadContinuationPointInvalid"},
25454 {UA_STATUSCODE_BADNOCONTINUATIONPOINTS, "BadNoContinuationPoints"},
25455 {UA_STATUSCODE_BADREFERENCETYPEIDINVALID, "BadReferenceTypeIdInvalid"},
25456 {UA_STATUSCODE_BADBROWSEDIRECTIONINVALID, "BadBrowseDirectionInvalid"},
25457 {UA_STATUSCODE_BADNODENOTINVIEW, "BadNodeNotInView"},
25458 {UA_STATUSCODE_BADNUMERICOVERFLOW, "BadNumericOverflow"},
25459 {UA_STATUSCODE_BADSERVERURIINVALID, "BadServerUriInvalid"},
25460 {UA_STATUSCODE_BADSERVERNAMEMISSING, "BadServerNameMissing"},
25461 {UA_STATUSCODE_BADDISCOVERYURLMISSING, "BadDiscoveryUrlMissing"},
25462 {UA_STATUSCODE_BADSEMPAHOREFILEMISSING, "BadSempahoreFileMissing"},
25463 {UA_STATUSCODE_BADREQUESTTYPEINVALID, "BadRequestTypeInvalid"},
25464 {UA_STATUSCODE_BADSECURITYMODEREJECTED, "BadSecurityModeRejected"},
25465 {UA_STATUSCODE_BADSECURITYPOLICYREJECTED, "BadSecurityPolicyRejected"},
25466 {UA_STATUSCODE_BADTOOMANYSESSIONS, "BadTooManySessions"},
25467 {UA_STATUSCODE_BADUSERSIGNATUREINVALID, "BadUserSignatureInvalid"},
25468 {UA_STATUSCODE_BADAPPLICATIONSIGNATUREINVALID, "BadApplicationSignatureInvalid"},
25469 {UA_STATUSCODE_BADNOVALIDCERTIFICATES, "BadNoValidCertificates"},
25470 {UA_STATUSCODE_BADIDENTITYCHANGENOTSUPPORTED, "BadIdentityChangeNotSupported"},
25471 {UA_STATUSCODE_BADREQUESTCANCELLEDBYREQUEST, "BadRequestCancelledByRequest"},
25472 {UA_STATUSCODE_BADPARENTNODEIDINVALID, "BadParentNodeIdInvalid"},
25473 {UA_STATUSCODE_BADREFERENCENOTALLOWED, "BadReferenceNotAllowed"},
25474 {UA_STATUSCODE_BADNODEIDREJECTED, "BadNodeIdRejected"},
25475 {UA_STATUSCODE_BADNODEIDEXISTS, "BadNodeIdExists"},
25476 {UA_STATUSCODE_BADNODECLASSINVALID, "BadNodeClassInvalid"},
25477 {UA_STATUSCODE_BADBROWSENAMEINVALID, "BadBrowseNameInvalid"},
25478 {UA_STATUSCODE_BADBROWSENAMEDUPLICATED, "BadBrowseNameDuplicated"},
25479 {UA_STATUSCODE_BADNODEATTRIBUTESINVALID, "BadNodeAttributesInvalid"},
25480 {UA_STATUSCODE_BADTYPEDEFINITIONINVALID, "BadTypeDefinitionInvalid"},
25481 {UA_STATUSCODE_BADSOURCENODEIDINVALID, "BadSourceNodeIdInvalid"},
25482 {UA_STATUSCODE_BADTARGETNODEIDINVALID, "BadTargetNodeIdInvalid"},
25483 {UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED, "BadDuplicateReferenceNotAllowed"},
25484 {UA_STATUSCODE_BADINVALIDSELFREFERENCE, "BadInvalidSelfReference"},
25485 {UA_STATUSCODE_BADREFERENCELOCALONLY, "BadReferenceLocalOnly"},
25486 {UA_STATUSCODE_BADNODELETERIGHTS, "BadNoDeleteRights"},
25487 {UA_STATUSCODE_UNCERTAINREFERENCENOTDELETED, "UncertainReferenceNotDeleted"},
25488 {UA_STATUSCODE_BADSERVERINDEXINVALID, "BadServerIndexInvalid"},
25489 {UA_STATUSCODE_BADVIEWIDUNKNOWN, "BadViewIdUnknown"},
25490 {UA_STATUSCODE_BADVIEWTIMESTAMPINVALID, "BadViewTimestampInvalid"},
25491 {UA_STATUSCODE_BADVIEWPARAMETERMISMATCH, "BadViewParameterMismatch"},
25492 {UA_STATUSCODE_BADVIEWVERSIONINVALID, "BadViewVersionInvalid"},
25493 {UA_STATUSCODE_UNCERTAINNOTALLNODESAVAILABLE, "UncertainNotAllNodesAvailable"},
25494 {UA_STATUSCODE_GOODRESULTSMAYBEINCOMPLETE, "GoodResultsMayBeIncomplete"},
25495 {UA_STATUSCODE_BADNOTTYPEDEFINITION, "BadNotTypeDefinition"},
25496 {UA_STATUSCODE_UNCERTAINREFERENCEOUTOFSERVER, "UncertainReferenceOutOfServer"},
25497 {UA_STATUSCODE_BADTOOMANYMATCHES, "BadTooManyMatches"},
25498 {UA_STATUSCODE_BADQUERYTOOCOMPLEX, "BadQueryTooComplex"},
25499 {UA_STATUSCODE_BADNOMATCH, "BadNoMatch"},
25500 {UA_STATUSCODE_BADMAXAGEINVALID, "BadMaxAgeInvalid"},
25501 {UA_STATUSCODE_BADSECURITYMODEINSUFFICIENT, "BadSecurityModeInsufficient"},
25502 {UA_STATUSCODE_BADHISTORYOPERATIONINVALID, "BadHistoryOperationInvalid"},
25503 {UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED, "BadHistoryOperationUnsupported"},
25504 {UA_STATUSCODE_BADINVALIDTIMESTAMPARGUMENT, "BadInvalidTimestampArgument"},
25505 {UA_STATUSCODE_BADWRITENOTSUPPORTED, "BadWriteNotSupported"},
25506 {UA_STATUSCODE_BADTYPEMISMATCH, "BadTypeMismatch"},
25507 {UA_STATUSCODE_BADMETHODINVALID, "BadMethodInvalid"},
25508 {UA_STATUSCODE_BADARGUMENTSMISSING, "BadArgumentsMissing"},
25509 {UA_STATUSCODE_BADNOTEXECUTABLE, "BadNotExecutable"},
25510 {UA_STATUSCODE_BADTOOMANYSUBSCRIPTIONS, "BadTooManySubscriptions"},
25511 {UA_STATUSCODE_BADTOOMANYPUBLISHREQUESTS, "BadTooManyPublishRequests"},
25512 {UA_STATUSCODE_BADNOSUBSCRIPTION, "BadNoSubscription"},
25513 {UA_STATUSCODE_BADSEQUENCENUMBERUNKNOWN, "BadSequenceNumberUnknown"},
25514 {UA_STATUSCODE_GOODRETRANSMISSIONQUEUENOTSUPPORTED, "GoodRetransmissionQueueNotSupported"},
25515 {UA_STATUSCODE_BADMESSAGENOTAVAILABLE, "BadMessageNotAvailable"},
25516 {UA_STATUSCODE_BADINSUFFICIENTCLIENTPROFILE, "BadInsufficientClientProfile"},
25517 {UA_STATUSCODE_BADSTATENOTACTIVE, "BadStateNotActive"},
25518 {UA_STATUSCODE_BADALREADYEXISTS, "BadAlreadyExists"},
25519 {UA_STATUSCODE_BADTCPSERVERTOOBUSY, "BadTcpServerTooBusy"},
25520 {UA_STATUSCODE_BADTCPMESSAGETYPEINVALID, "BadTcpMessageTypeInvalid"},
25521 {UA_STATUSCODE_BADTCPSECURECHANNELUNKNOWN, "BadTcpSecureChannelUnknown"},
25522 {UA_STATUSCODE_BADTCPMESSAGETOOLARGE, "BadTcpMessageTooLarge"},
25523 {UA_STATUSCODE_BADTCPNOTENOUGHRESOURCES, "BadTcpNotEnoughResources"},
25524 {UA_STATUSCODE_BADTCPINTERNALERROR, "BadTcpInternalError"},
25525 {UA_STATUSCODE_BADTCPENDPOINTURLINVALID, "BadTcpEndpointUrlInvalid"},
25526 {UA_STATUSCODE_BADREQUESTINTERRUPTED, "BadRequestInterrupted"},
25527 {UA_STATUSCODE_BADREQUESTTIMEOUT, "BadRequestTimeout"},
25528 {UA_STATUSCODE_BADSECURECHANNELCLOSED, "BadSecureChannelClosed"},
25529 {UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN, "BadSecureChannelTokenUnknown"},
25530 {UA_STATUSCODE_BADSEQUENCENUMBERINVALID, "BadSequenceNumberInvalid"},
25531 {UA_STATUSCODE_BADPROTOCOLVERSIONUNSUPPORTED, "BadProtocolVersionUnsupported"},
25532 {UA_STATUSCODE_BADCONFIGURATIONERROR, "BadConfigurationError"},
25533 {UA_STATUSCODE_BADNOTCONNECTED, "BadNotConnected"},
25534 {UA_STATUSCODE_BADDEVICEFAILURE, "BadDeviceFailure"},
25535 {UA_STATUSCODE_BADSENSORFAILURE, "BadSensorFailure"},
25536 {UA_STATUSCODE_BADOUTOFSERVICE, "BadOutOfService"},
25537 {UA_STATUSCODE_BADDEADBANDFILTERINVALID, "BadDeadbandFilterInvalid"},
25538 {UA_STATUSCODE_UNCERTAINNOCOMMUNICATIONLASTUSABLEVALUE, "UncertainNoCommunicationLastUsableValue"},
25539 {UA_STATUSCODE_UNCERTAINLASTUSABLEVALUE, "UncertainLastUsableValue"},
25540 {UA_STATUSCODE_UNCERTAINSUBSTITUTEVALUE, "UncertainSubstituteValue"},
25541 {UA_STATUSCODE_UNCERTAININITIALVALUE, "UncertainInitialValue"},
25542 {UA_STATUSCODE_UNCERTAINSENSORNOTACCURATE, "UncertainSensorNotAccurate"},
25543 {UA_STATUSCODE_UNCERTAINENGINEERINGUNITSEXCEEDED, "UncertainEngineeringUnitsExceeded"},
25544 {UA_STATUSCODE_UNCERTAINSUBNORMAL, "UncertainSubNormal"},
25545 {UA_STATUSCODE_GOODLOCALOVERRIDE, "GoodLocalOverride"},
25546 {UA_STATUSCODE_BADREFRESHINPROGRESS, "BadRefreshInProgress"},
25547 {UA_STATUSCODE_BADCONDITIONALREADYDISABLED, "BadConditionAlreadyDisabled"},
25548 {UA_STATUSCODE_BADCONDITIONALREADYENABLED, "BadConditionAlreadyEnabled"},
25549 {UA_STATUSCODE_BADCONDITIONDISABLED, "BadConditionDisabled"},
25550 {UA_STATUSCODE_BADEVENTIDUNKNOWN, "BadEventIdUnknown"},
25551 {UA_STATUSCODE_BADEVENTNOTACKNOWLEDGEABLE, "BadEventNotAcknowledgeable"},
25552 {UA_STATUSCODE_BADDIALOGNOTACTIVE, "BadDialogNotActive"},
25553 {UA_STATUSCODE_BADDIALOGRESPONSEINVALID, "BadDialogResponseInvalid"},
25554 {UA_STATUSCODE_BADCONDITIONBRANCHALREADYACKED, "BadConditionBranchAlreadyAcked"},
25555 {UA_STATUSCODE_BADCONDITIONBRANCHALREADYCONFIRMED, "BadConditionBranchAlreadyConfirmed"},
25556 {UA_STATUSCODE_BADCONDITIONALREADYSHELVED, "BadConditionAlreadyShelved"},
25557 {UA_STATUSCODE_BADCONDITIONNOTSHELVED, "BadConditionNotShelved"},
25558 {UA_STATUSCODE_BADSHELVINGTIMEOUTOFRANGE, "BadShelvingTimeOutOfRange"},
25559 {UA_STATUSCODE_BADNODATA, "BadNoData"},
25560 {UA_STATUSCODE_BADBOUNDNOTFOUND, "BadBoundNotFound"},
25561 {UA_STATUSCODE_BADBOUNDNOTSUPPORTED, "BadBoundNotSupported"},
25562 {UA_STATUSCODE_BADDATALOST, "BadDataLost"},
25563 {UA_STATUSCODE_BADDATAUNAVAILABLE, "BadDataUnavailable"},
25564 {UA_STATUSCODE_BADENTRYEXISTS, "BadEntryExists"},
25565 {UA_STATUSCODE_BADNOENTRYEXISTS, "BadNoEntryExists"},
25566 {UA_STATUSCODE_BADTIMESTAMPNOTSUPPORTED, "BadTimestampNotSupported"},
25567 {UA_STATUSCODE_GOODENTRYINSERTED, "GoodEntryInserted"},
25568 {UA_STATUSCODE_GOODENTRYREPLACED, "GoodEntryReplaced"},
25569 {UA_STATUSCODE_UNCERTAINDATASUBNORMAL, "UncertainDataSubNormal"},
25570 {UA_STATUSCODE_GOODNODATA, "GoodNoData"},
25571 {UA_STATUSCODE_GOODMOREDATA, "GoodMoreData"},
25572 {UA_STATUSCODE_BADAGGREGATELISTMISMATCH, "BadAggregateListMismatch"},
25573 {UA_STATUSCODE_BADAGGREGATENOTSUPPORTED, "BadAggregateNotSupported"},
25574 {UA_STATUSCODE_BADAGGREGATEINVALIDINPUTS, "BadAggregateInvalidInputs"},
25575 {UA_STATUSCODE_BADAGGREGATECONFIGURATIONREJECTED, "BadAggregateConfigurationRejected"},
25576 {UA_STATUSCODE_GOODDATAIGNORED, "GoodDataIgnored"},
25577 {UA_STATUSCODE_BADREQUESTNOTALLOWED, "BadRequestNotAllowed"},
25578 {UA_STATUSCODE_BADREQUESTNOTCOMPLETE, "BadRequestNotComplete"},
25579 {UA_STATUSCODE_BADTICKETREQUIRED, "BadTicketRequired"},
25580 {UA_STATUSCODE_BADTICKETINVALID, "BadTicketInvalid"},
25581 {UA_STATUSCODE_GOODEDITED, "GoodEdited"},
25582 {UA_STATUSCODE_GOODPOSTACTIONFAILED, "GoodPostActionFailed"},
25583 {UA_STATUSCODE_UNCERTAINDOMINANTVALUECHANGED, "UncertainDominantValueChanged"},
25584 {UA_STATUSCODE_GOODDEPENDENTVALUECHANGED, "GoodDependentValueChanged"},
25585 {UA_STATUSCODE_BADDOMINANTVALUECHANGED, "BadDominantValueChanged"},
25586 {UA_STATUSCODE_UNCERTAINDEPENDENTVALUECHANGED, "UncertainDependentValueChanged"},
25587 {UA_STATUSCODE_BADDEPENDENTVALUECHANGED, "BadDependentValueChanged"},
25588 {UA_STATUSCODE_GOODEDITED_DEPENDENTVALUECHANGED, "GoodEdited_DependentValueChanged"},
25589 {UA_STATUSCODE_GOODEDITED_DOMINANTVALUECHANGED, "GoodEdited_DominantValueChanged"},
25590 {UA_STATUSCODE_GOODEDITED_DOMINANTVALUECHANGED_DEPENDENTVALUECHANGED, "GoodEdited_DominantValueChanged_DependentValueChanged"},
25591 {UA_STATUSCODE_BADEDITED_OUTOFRANGE, "BadEdited_OutOfRange"},
25592 {UA_STATUSCODE_BADINITIALVALUE_OUTOFRANGE, "BadInitialValue_OutOfRange"},
25593 {UA_STATUSCODE_BADOUTOFRANGE_DOMINANTVALUECHANGED, "BadOutOfRange_DominantValueChanged"},
25594 {UA_STATUSCODE_BADEDITED_OUTOFRANGE_DOMINANTVALUECHANGED, "BadEdited_OutOfRange_DominantValueChanged"},
25595 {UA_STATUSCODE_BADOUTOFRANGE_DOMINANTVALUECHANGED_DEPENDENTVALUECHANGED, "BadOutOfRange_DominantValueChanged_DependentValueChanged"},
25596 {UA_STATUSCODE_BADEDITED_OUTOFRANGE_DOMINANTVALUECHANGED_DEPENDENTVALUECHANGED, "BadEdited_OutOfRange_DominantValueChanged_DependentValueChanged"},
25597 {UA_STATUSCODE_GOODCOMMUNICATIONEVENT, "GoodCommunicationEvent"},
25598 {UA_STATUSCODE_GOODSHUTDOWNEVENT, "GoodShutdownEvent"},
25599 {UA_STATUSCODE_GOODCALLAGAIN, "GoodCallAgain"},
25600 {UA_STATUSCODE_GOODNONCRITICALTIMEOUT, "GoodNonCriticalTimeout"},
25601 {UA_STATUSCODE_BADINVALIDARGUMENT, "BadInvalidArgument"},
25602 {UA_STATUSCODE_BADCONNECTIONREJECTED, "BadConnectionRejected"},
25603 {UA_STATUSCODE_BADDISCONNECT, "BadDisconnect"},
25604 {UA_STATUSCODE_BADCONNECTIONCLOSED, "BadConnectionClosed"},
25605 {UA_STATUSCODE_BADINVALIDSTATE, "BadInvalidState"},
25606 {UA_STATUSCODE_BADENDOFSTREAM, "BadEndOfStream"},
25607 {UA_STATUSCODE_BADNODATAAVAILABLE, "BadNoDataAvailable"},
25608 {UA_STATUSCODE_BADWAITINGFORRESPONSE, "BadWaitingForResponse"},
25609 {UA_STATUSCODE_BADOPERATIONABANDONED, "BadOperationAbandoned"},
25610 {UA_STATUSCODE_BADEXPECTEDSTREAMTOBLOCK, "BadExpectedStreamToBlock"},
25611 {UA_STATUSCODE_BADWOULDBLOCK, "BadWouldBlock"},
25612 {UA_STATUSCODE_BADSYNTAXERROR, "BadSyntaxError"},
25613 {UA_STATUSCODE_BADMAXCONNECTIONSREACHED, "BadMaxConnectionsReached"},
25614 {0xffffffff, "Unknown StatusCode"}
25615};
25616
25617const char * UA_StatusCode_name(UA_StatusCode code) {
25618 for (size_t i = 0; i < statusCodeDescriptionsSize; ++i) {
25619 if (UA_StatusCode_isEqualTop(s1: statusCodeDescriptions[i].code,s2: code))
25620 return statusCodeDescriptions[i].name;
25621 }
25622 return statusCodeDescriptions[statusCodeDescriptionsSize-1].name;
25623}
25624
25625#endif
25626
25627/**** amalgamated original file "/src/ua_util.c" ****/
25628
25629/* This Source Code Form is subject to the terms of the Mozilla Public
25630 * License, v. 2.0. If a copy of the MPL was not distributed with this
25631 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
25632 *
25633 * Copyright 2014, 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
25634 * Copyright 2014 (c) Florian Palm
25635 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
25636 */
25637
25638/* If UA_ENABLE_INLINABLE_EXPORT is enabled, then this file is the compilation
25639 * unit for the generated code from UA_INLINABLE definitions. */
25640#define UA_INLINABLE_IMPL 1
25641
25642
25643
25644static UA_DataTypeKind
25645typeEquivalence(const UA_DataType *t) {
25646 UA_DataTypeKind k = (UA_DataTypeKind)t->typeKind;
25647 if(k == UA_DATATYPEKIND_ENUM)
25648 return UA_DATATYPEKIND_INT32;
25649 return k;
25650}
25651
25652void
25653adjustType(UA_Variant *value, const UA_DataType *targetType) {
25654 /* If the value is empty, there is nothing we can do here */
25655 const UA_DataType *type = value->type;
25656 if(!type || !targetType)
25657 return;
25658
25659 /* A string is written to a byte array. the valuerank and array dimensions
25660 * are checked later */
25661 if(targetType == &UA_TYPES[UA_TYPES_BYTE] &&
25662 type == &UA_TYPES[UA_TYPES_BYTESTRING] &&
25663 UA_Variant_isScalar(v: value)) {
25664 UA_ByteString *str = (UA_ByteString*)value->data;
25665 value->type = &UA_TYPES[UA_TYPES_BYTE];
25666 value->arrayLength = str->length;
25667 value->data = str->data;
25668 return;
25669 }
25670
25671 /* An enum was sent as an int32, or an opaque type as a bytestring. This
25672 * is detected with the typeKind indicating the "true" datatype. */
25673 UA_DataTypeKind te1 = typeEquivalence(t: targetType);
25674 UA_DataTypeKind te2 = typeEquivalence(t: type);
25675 if(te1 == te2 && te1 <= UA_DATATYPEKIND_ENUM) {
25676 value->type = targetType;
25677 return;
25678 }
25679
25680 /* Add more possible type adjustments here. What are they? */
25681}
25682
25683size_t
25684UA_readNumberWithBase(const UA_Byte *buf, size_t buflen, UA_UInt32 *number, UA_Byte base) {
25685 UA_assert(buf);
25686 UA_assert(number);
25687 u32 n = 0;
25688 size_t progress = 0;
25689 /* read numbers until the end or a non-number character appears */
25690 while(progress < buflen) {
25691 u8 c = buf[progress];
25692 if(c >= '0' && c <= '9' && c <= '0' + (base-1))
25693 n = (n * base) + c - '0';
25694 else if(base > 9 && c >= 'a' && c <= 'z' && c <= 'a' + (base-11))
25695 n = (n * base) + c-'a' + 10;
25696 else if(base > 9 && c >= 'A' && c <= 'Z' && c <= 'A' + (base-11))
25697 n = (n * base) + c-'A' + 10;
25698 else
25699 break;
25700 ++progress;
25701 }
25702 *number = n;
25703 return progress;
25704}
25705
25706size_t
25707UA_readNumber(const UA_Byte *buf, size_t buflen, UA_UInt32 *number) {
25708 return UA_readNumberWithBase(buf, buflen, number, base: 10);
25709}
25710
25711struct urlSchema {
25712 const char *schema;
25713};
25714
25715static const struct urlSchema schemas[] = {
25716 {"opc.tcp://"},
25717 {"opc.udp://"},
25718 {"opc.eth://"},
25719 {"opc.mqtt://"}
25720};
25721
25722static const unsigned scNumSchemas = sizeof(schemas) / sizeof(schemas[0]);
25723static const unsigned scEthSchemaIdx = 2;
25724
25725UA_StatusCode
25726UA_parseEndpointUrl(const UA_String *endpointUrl, UA_String *outHostname,
25727 UA_UInt16 *outPort, UA_String *outPath) {
25728 /* Url must begin with "opc.tcp://" or opc.udp:// (if pubsub enabled) */
25729 if(endpointUrl->length < 11) {
25730 return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
25731 }
25732
25733 /* Which type of schema is this? */
25734 unsigned schemaType = 0;
25735 for(; schemaType < scNumSchemas; schemaType++) {
25736 if(strncmp(s1: (char*)endpointUrl->data,
25737 s2: schemas[schemaType].schema,
25738 n: strlen(s: schemas[schemaType].schema)) == 0)
25739 break;
25740 }
25741 if(schemaType == scNumSchemas)
25742 return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
25743
25744 /* Forward the current position until the first colon or slash */
25745 size_t start = strlen(s: schemas[schemaType].schema);
25746 size_t curr = start;
25747 UA_Boolean ipv6 = false;
25748 if(endpointUrl->length > curr && endpointUrl->data[curr] == '[') {
25749 /* IPv6: opc.tcp://[2001:0db8:85a3::8a2e:0370:7334]:1234/path */
25750 for(; curr < endpointUrl->length; ++curr) {
25751 if(endpointUrl->data[curr] == ']')
25752 break;
25753 }
25754 if(curr == endpointUrl->length)
25755 return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
25756 curr++;
25757 ipv6 = true;
25758 } else {
25759 /* IPv4 or hostname: opc.tcp://something.something:1234/path */
25760 for(; curr < endpointUrl->length; ++curr) {
25761 if(endpointUrl->data[curr] == ':' || endpointUrl->data[curr] == '/')
25762 break;
25763 }
25764 }
25765
25766 /* Set the hostname */
25767 if(ipv6) {
25768 /* Skip the ipv6 '[]' container for getaddrinfo() later */
25769 outHostname->data = &endpointUrl->data[start+1];
25770 outHostname->length = curr - (start+2);
25771 } else {
25772 outHostname->data = &endpointUrl->data[start];
25773 outHostname->length = curr - start;
25774 }
25775
25776 /* Empty string? */
25777 if(outHostname->length == 0)
25778 outHostname->data = NULL;
25779
25780 /* Already at the end */
25781 if(curr == endpointUrl->length)
25782 return UA_STATUSCODE_GOOD;
25783
25784 /* Set the port - and for ETH set the VID.PCP postfix in the outpath string.
25785 * We have to parse that externally. */
25786 if(endpointUrl->data[curr] == ':') {
25787 if(++curr == endpointUrl->length)
25788 return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
25789
25790 /* ETH schema */
25791 if(schemaType == scEthSchemaIdx) {
25792 if(outPath != NULL) {
25793 outPath->data = &endpointUrl->data[curr];
25794 outPath->length = endpointUrl->length - curr;
25795 }
25796 return UA_STATUSCODE_GOOD;
25797 }
25798
25799 u32 largeNum;
25800 size_t progress = UA_readNumber(buf: &endpointUrl->data[curr],
25801 buflen: endpointUrl->length - curr, number: &largeNum);
25802 if(progress == 0 || largeNum > 65535)
25803 return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
25804 /* Test if the end of a valid port was reached */
25805 curr += progress;
25806 if(curr == endpointUrl->length || endpointUrl->data[curr] == '/')
25807 *outPort = (u16)largeNum;
25808 if(curr == endpointUrl->length)
25809 return UA_STATUSCODE_GOOD;
25810 }
25811
25812 /* Set the path */
25813 UA_assert(curr < endpointUrl->length);
25814 if(endpointUrl->data[curr] != '/')
25815 return UA_STATUSCODE_BADTCPENDPOINTURLINVALID;
25816 if(++curr == endpointUrl->length)
25817 return UA_STATUSCODE_GOOD;
25818 if(outPath != NULL) {
25819 outPath->data = &endpointUrl->data[curr];
25820 outPath->length = endpointUrl->length - curr;
25821
25822 /* Remove trailing slash from the path */
25823 if(endpointUrl->data[endpointUrl->length - 1] == '/')
25824 outPath->length--;
25825
25826 /* Empty string? */
25827 if(outPath->length == 0)
25828 outPath->data = NULL;
25829 }
25830
25831 return UA_STATUSCODE_GOOD;
25832}
25833
25834UA_StatusCode
25835UA_parseEndpointUrlEthernet(const UA_String *endpointUrl, UA_String *target,
25836 UA_UInt16 *vid, UA_Byte *pcp) {
25837 /* Url must begin with "opc.eth://" */
25838 if(endpointUrl->length < 11) {
25839 return UA_STATUSCODE_BADINTERNALERROR;
25840 }
25841 if(strncmp(s1: (char*) endpointUrl->data, s2: "opc.eth://", n: 10) != 0) {
25842 return UA_STATUSCODE_BADINTERNALERROR;
25843 }
25844
25845 /* Where does the host address end? */
25846 size_t curr = 10;
25847 for(; curr < endpointUrl->length; ++curr) {
25848 if(endpointUrl->data[curr] == ':') {
25849 break;
25850 }
25851 }
25852
25853 /* set host address */
25854 target->data = &endpointUrl->data[10];
25855 target->length = curr - 10;
25856 if(curr == endpointUrl->length) {
25857 return UA_STATUSCODE_GOOD;
25858 }
25859
25860 /* Set VLAN */
25861 u32 value = 0;
25862 curr++; /* skip ':' */
25863 size_t progress = UA_readNumber(buf: &endpointUrl->data[curr],
25864 buflen: endpointUrl->length - curr, number: &value);
25865 if(progress == 0 || value > 4096) {
25866 return UA_STATUSCODE_BADINTERNALERROR;
25867 }
25868 curr += progress;
25869 if(curr == endpointUrl->length || endpointUrl->data[curr] == '.') {
25870 *vid = (UA_UInt16) value;
25871 }
25872 if(curr == endpointUrl->length) {
25873 return UA_STATUSCODE_GOOD;
25874 }
25875
25876 /* Set priority */
25877 if(endpointUrl->data[curr] != '.') {
25878 return UA_STATUSCODE_BADINTERNALERROR;
25879 }
25880 curr++; /* skip '.' */
25881 progress = UA_readNumber(buf: &endpointUrl->data[curr],
25882 buflen: endpointUrl->length - curr, number: &value);
25883 if(progress == 0 || value > 7) {
25884 return UA_STATUSCODE_BADINTERNALERROR;
25885 }
25886 curr += progress;
25887 if(curr != endpointUrl->length) {
25888 return UA_STATUSCODE_BADINTERNALERROR;
25889 }
25890 *pcp = (UA_Byte) value;
25891
25892 return UA_STATUSCODE_GOOD;
25893}
25894
25895UA_StatusCode
25896UA_ByteString_toBase64(const UA_ByteString *byteString,
25897 UA_String *str) {
25898 UA_String_init(p: str);
25899 if(!byteString || !byteString->data)
25900 return UA_STATUSCODE_GOOD;
25901
25902 str->data = (UA_Byte*)
25903 UA_base64(src: byteString->data, len: byteString->length, out_len: &str->length);
25904 if(!str->data)
25905 return UA_STATUSCODE_BADOUTOFMEMORY;
25906
25907 return UA_STATUSCODE_GOOD;
25908}
25909
25910UA_StatusCode
25911UA_ByteString_fromBase64(UA_ByteString *bs,
25912 const UA_String *input) {
25913 UA_ByteString_init(p: bs);
25914 if(input->length == 0)
25915 return UA_STATUSCODE_GOOD;
25916 bs->data = UA_unbase64(src: (const unsigned char*)input->data,
25917 len: input->length, out_len: &bs->length);
25918 /* TODO: Differentiate between encoding and memory errors */
25919 if(!bs->data)
25920 return UA_STATUSCODE_BADINTERNALERROR;
25921 return UA_STATUSCODE_GOOD;
25922}
25923
25924/* Key Value Map */
25925
25926const UA_KeyValueMap UA_KEYVALUEMAP_NULL = {0, NULL};
25927
25928UA_KeyValueMap *
25929UA_KeyValueMap_new(void) {
25930 return (UA_KeyValueMap*)UA_calloc(nmemb: 1, size: sizeof(UA_KeyValueMap));
25931}
25932
25933UA_StatusCode
25934UA_KeyValueMap_set(UA_KeyValueMap *map,
25935 const UA_QualifiedName key,
25936 const UA_Variant *value) {
25937 if(map == NULL || value == NULL)
25938 return UA_STATUSCODE_BADINVALIDARGUMENT;
25939
25940 /* Key exists already */
25941 const UA_Variant *v = UA_KeyValueMap_get(map, key);
25942 if(v) {
25943 UA_Variant copyV;
25944 UA_StatusCode res = UA_Variant_copy(src: value, dst: &copyV);
25945 if(res != UA_STATUSCODE_GOOD)
25946 return res;
25947 UA_Variant *target = (UA_Variant*)(uintptr_t)v;
25948 UA_Variant_clear(p: target);
25949 *target = copyV;
25950 return UA_STATUSCODE_GOOD;
25951 }
25952
25953 /* Append to the array */
25954 UA_KeyValuePair pair;
25955 pair.key = key;
25956 pair.value = *value;
25957 return UA_Array_appendCopy(p: (void**)&map->map, size: &map->mapSize, newElem: &pair,
25958 type: &UA_TYPES[UA_TYPES_KEYVALUEPAIR]);
25959}
25960
25961UA_StatusCode
25962UA_KeyValueMap_setScalar(UA_KeyValueMap *map,
25963 const UA_QualifiedName key,
25964 void * UA_RESTRICT p,
25965 const UA_DataType *type) {
25966 if(p == NULL || type == NULL)
25967 return UA_STATUSCODE_BADINVALIDARGUMENT;
25968 UA_Variant v;
25969 UA_Variant_init(p: &v);
25970 v.type = type;
25971 v.arrayLength = 0;
25972 v.data = p;
25973 return UA_KeyValueMap_set(map, key, value: &v);
25974}
25975
25976const UA_Variant *
25977UA_KeyValueMap_get(const UA_KeyValueMap *map,
25978 const UA_QualifiedName key) {
25979 if(!map)
25980 return NULL;
25981 for(size_t i = 0; i < map->mapSize; i++) {
25982 if(map->map[i].key.namespaceIndex == key.namespaceIndex &&
25983 UA_String_equal(p1: &map->map[i].key.name, p2: &key.name))
25984 return &map->map[i].value;
25985
25986 }
25987 return NULL;
25988}
25989
25990UA_Boolean
25991UA_KeyValueMap_isEmpty(const UA_KeyValueMap *map) {
25992 if(!map)
25993 return true;
25994 return map->mapSize == 0;
25995}
25996
25997const void *
25998UA_KeyValueMap_getScalar(const UA_KeyValueMap *map,
25999 const UA_QualifiedName key,
26000 const UA_DataType *type) {
26001 const UA_Variant *v = UA_KeyValueMap_get(map, key);
26002 if(!v || !UA_Variant_hasScalarType(v, type))
26003 return NULL;
26004 return v->data;
26005}
26006
26007void
26008UA_KeyValueMap_clear(UA_KeyValueMap *map) {
26009 if(!map)
26010 return;
26011 if(map->mapSize > 0) {
26012 UA_Array_delete(p: map->map, size: map->mapSize, type: &UA_TYPES[UA_TYPES_KEYVALUEPAIR]);
26013 map->mapSize = 0;
26014 }
26015}
26016
26017void
26018UA_KeyValueMap_delete(UA_KeyValueMap *map) {
26019 UA_KeyValueMap_clear(map);
26020 UA_free(ptr: map);
26021}
26022
26023UA_StatusCode
26024UA_KeyValueMap_remove(UA_KeyValueMap *map,
26025 const UA_QualifiedName key) {
26026 if(!map)
26027 return UA_STATUSCODE_BADINVALIDARGUMENT;
26028
26029 UA_KeyValuePair *m = map->map;
26030 size_t s = map->mapSize;
26031 size_t i = 0;
26032 for(; i < s; i++) {
26033 if(m[i].key.namespaceIndex == key.namespaceIndex &&
26034 UA_String_equal(p1: &m[i].key.name, p2: &key.name))
26035 break;
26036 }
26037 if(i == s)
26038 return UA_STATUSCODE_BADNOTFOUND;
26039
26040 /* Clean the slot and move the last entry to fill the slot */
26041 UA_KeyValuePair_clear(p: &m[i]);
26042 if(s > 1 && i < s - 1) {
26043 m[i] = m[s-1];
26044 UA_KeyValuePair_init(p: &m[s-1]);
26045 }
26046
26047 /* Ignore the result. In case resize fails, keep the longer original array
26048 * around. Resize never fails when reducing the size to zero. */
26049 UA_StatusCode res =
26050 UA_Array_resize(p: (void**)&map->map, size: &map->mapSize, newSize: map->mapSize - 1,
26051 type: &UA_TYPES[UA_TYPES_KEYVALUEPAIR]);
26052 /* Adjust map->mapSize only when UA_Array_resize() failed. On success, the
26053 * value has already been decremented by UA_Array_resize(). */
26054 if(res != UA_STATUSCODE_GOOD)
26055 map->mapSize--;
26056 return UA_STATUSCODE_GOOD;
26057}
26058
26059UA_StatusCode
26060UA_KeyValueMap_copy(const UA_KeyValueMap *src, UA_KeyValueMap *dst) {
26061 if(!dst)
26062 return UA_STATUSCODE_BADINVALIDARGUMENT;
26063 if(!src) {
26064 dst->map = NULL;
26065 dst->mapSize = 0;
26066 return UA_STATUSCODE_GOOD;
26067 }
26068 UA_StatusCode res = UA_Array_copy(src: src->map, size: src->mapSize, dst: (void**)&dst->map,
26069 type: &UA_TYPES[UA_TYPES_KEYVALUEPAIR]);
26070 if(res == UA_STATUSCODE_GOOD)
26071 dst->mapSize = src->mapSize;
26072 return res;
26073}
26074
26075UA_Boolean
26076UA_KeyValueMap_contains(const UA_KeyValueMap *map, const UA_QualifiedName key) {
26077 if(!map)
26078 return false;
26079 for(size_t i = 0; i < map->mapSize; ++i) {
26080 if(UA_QualifiedName_equal(p1: &map->map[i].key, p2: &key))
26081 return true;
26082 }
26083 return false;
26084}
26085
26086UA_StatusCode
26087UA_KeyValueMap_merge(UA_KeyValueMap *lhs, const UA_KeyValueMap *rhs) {
26088 if(!lhs)
26089 return UA_STATUSCODE_BADINVALIDARGUMENT;
26090 if(!rhs)
26091 return UA_STATUSCODE_GOOD;
26092
26093 UA_KeyValueMap merge;
26094 UA_StatusCode res = UA_KeyValueMap_copy(src: lhs, dst: &merge);
26095 if(res != UA_STATUSCODE_GOOD)
26096 return res;
26097
26098 for(size_t i = 0; i < rhs->mapSize; ++i) {
26099 res = UA_KeyValueMap_set(map: &merge, key: rhs->map[i].key, value: &rhs->map[i].value);
26100 if(res != UA_STATUSCODE_GOOD) {
26101 UA_KeyValueMap_clear(map: &merge);
26102 return res;
26103 }
26104 }
26105
26106 UA_KeyValueMap_clear(map: lhs);
26107 *lhs = merge;
26108 return UA_STATUSCODE_GOOD;
26109}
26110
26111/***************************/
26112/* Random Number Generator */
26113/***************************/
26114
26115/* TODO is this safe for multithreading? */
26116static pcg32_random_t UA_rng = PCG32_INITIALIZER;
26117
26118void
26119UA_random_seed(u64 seed) {
26120 pcg32_srandom_r(rng: &UA_rng, initial_state: seed, initseq: (u64)UA_DateTime_now());
26121}
26122
26123u32
26124UA_UInt32_random(void) {
26125 return (u32)pcg32_random_r(rng: &UA_rng);
26126}
26127
26128UA_Guid
26129UA_Guid_random(void) {
26130 UA_Guid result;
26131 result.data1 = (u32)pcg32_random_r(rng: &UA_rng);
26132 u32 r = (u32)pcg32_random_r(rng: &UA_rng);
26133 result.data2 = (u16) r;
26134 result.data3 = (u16) (r >> 16);
26135 r = (u32)pcg32_random_r(rng: &UA_rng);
26136 result.data4[0] = (u8)r;
26137 result.data4[1] = (u8)(r >> 4);
26138 result.data4[2] = (u8)(r >> 8);
26139 result.data4[3] = (u8)(r >> 12);
26140 r = (u32)pcg32_random_r(rng: &UA_rng);
26141 result.data4[4] = (u8)r;
26142 result.data4[5] = (u8)(r >> 4);
26143 result.data4[6] = (u8)(r >> 8);
26144 result.data4[7] = (u8)(r >> 12);
26145 return result;
26146}
26147
26148/********************/
26149/* Malloc Singleton */
26150/********************/
26151
26152#ifdef UA_ENABLE_MALLOC_SINGLETON
26153# include <stdlib.h>
26154UA_EXPORT UA_THREAD_LOCAL void * (*UA_mallocSingleton)(size_t size) = malloc;
26155UA_EXPORT UA_THREAD_LOCAL void (*UA_freeSingleton)(void *ptr) = free;
26156UA_EXPORT UA_THREAD_LOCAL void * (*UA_callocSingleton)(size_t nelem, size_t elsize) = calloc;
26157UA_EXPORT UA_THREAD_LOCAL void * (*UA_reallocSingleton)(void *ptr, size_t size) = realloc;
26158#endif
26159
26160/************************/
26161/* Cryptography Helpers */
26162/************************/
26163
26164UA_ByteString
26165getLeafCertificate(UA_ByteString chain) {
26166 /* Detect DER encoded X.509 v3 certificate. If the DER detection fails,
26167 * return the entire chain.
26168 *
26169 * The OPC UA standard requires this to be DER. But we also allow other
26170 * formats like PEM. Afterwards it depends on the crypto backend to parse
26171 * it. mbedTLS and OpenSSL detect the format automatically. */
26172 if(chain.length < 4 || chain.data[0] != 0x30 || chain.data[1] != 0x82)
26173 return chain;
26174
26175 /* The certificate length is encoded in the next 2 bytes. */
26176 size_t leafLen = 4; /* Magic numbers + length bytes */
26177 leafLen += (size_t)(((uint16_t)chain.data[2]) << 8);
26178 leafLen += chain.data[3];
26179
26180 /* Consistency check */
26181 if(leafLen > chain.length)
26182 return UA_BYTESTRING_NULL;
26183
26184 /* Adjust the length and return */
26185 chain.length = leafLen;
26186 return chain;
26187}
26188
26189UA_Boolean
26190UA_constantTimeEqual(const void *ptr1, const void *ptr2, size_t length) {
26191 volatile const UA_Byte *a = (volatile const UA_Byte *)ptr1;
26192 volatile const UA_Byte *b = (volatile const UA_Byte *)ptr2;
26193 volatile UA_Byte c = 0;
26194 for(size_t i = 0; i < length; ++i) {
26195 UA_Byte x = a[i], y = b[i];
26196 c = c | (x ^ y);
26197 }
26198 return !c;
26199}
26200
26201void
26202UA_ByteString_memZero(UA_ByteString *bs) {
26203#if defined(__STDC_LIB_EXT1__)
26204 memset_s(bs->data, bs->length, 0, bs->length);
26205#elif defined(UA_ARCHITECTURE_WIN32)
26206 SecureZeroMemory(bs->data, bs->length);
26207#else
26208 volatile unsigned char *volatile ptr =
26209 (volatile unsigned char *)bs->data;
26210 size_t i = 0;
26211 size_t maxLen = bs->length;
26212 while(i < maxLen) {
26213 ptr[i++] = 0;
26214 }
26215#endif
26216}
26217
26218/**** amalgamated original file "/src/ua_securechannel.c" ****/
26219
26220/* This Source Code Form is subject to the terms of the Mozilla Public
26221 * License, v. 2.0. If a copy of the MPL was not distributed with this
26222 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
26223 *
26224 * Copyright 2014-2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
26225 * Copyright 2014, 2016-2017 (c) Florian Palm
26226 * Copyright 2015-2016 (c) Sten Grüner
26227 * Copyright 2015 (c) Oleksiy Vasylyev
26228 * Copyright 2016 (c) TorbenD
26229 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
26230 * Copyright 2017-2018 (c) Mark Giraud, Fraunhofer IOSB
26231 * Copyright 2018-2019 (c) HMS Industrial Networks AB (Author: Jonas Green)
26232 */
26233
26234
26235
26236#define UA_BITMASK_MESSAGETYPE 0x00ffffffu
26237#define UA_BITMASK_CHUNKTYPE 0xff000000u
26238
26239const UA_String UA_SECURITY_POLICY_NONE_URI =
26240 {47, (UA_Byte *)"http://opcfoundation.org/UA/SecurityPolicy#None"};
26241
26242void
26243UA_SecureChannel_init(UA_SecureChannel *channel) {
26244 /* Normal linked lists are initialized by zeroing out */
26245 memset(s: channel, c: 0, n: sizeof(UA_SecureChannel));
26246 TAILQ_INIT(&channel->chunks);
26247}
26248
26249UA_StatusCode
26250UA_SecureChannel_setSecurityPolicy(UA_SecureChannel *channel,
26251 UA_SecurityPolicy *securityPolicy,
26252 const UA_ByteString *remoteCertificate) {
26253 /* Is a policy already configured? */
26254 UA_CHECK_ERROR(!channel->securityPolicy, return UA_STATUSCODE_BADINTERNALERROR,
26255 securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
26256 "Security policy already configured");
26257
26258 /* Create the context */
26259 UA_StatusCode res = securityPolicy->channelModule.
26260 newContext(securityPolicy, remoteCertificate, &channel->channelContext);
26261 res |= UA_ByteString_copy(src: remoteCertificate, dst: &channel->remoteCertificate);
26262 UA_CHECK_STATUS_WARN(res, return res, securityPolicy->logger,
26263 UA_LOGCATEGORY_SECURITYPOLICY,
26264 "Could not set up the SecureChannel context");
26265
26266 /* Compute the certificate thumbprint */
26267 UA_ByteString remoteCertificateThumbprint =
26268 {20, channel->remoteCertificateThumbprint};
26269 res = securityPolicy->asymmetricModule.
26270 makeCertificateThumbprint(securityPolicy, &channel->remoteCertificate,
26271 &remoteCertificateThumbprint);
26272 UA_CHECK_STATUS_WARN(res, return res, securityPolicy->logger,
26273 UA_LOGCATEGORY_SECURITYPOLICY,
26274 "Could not create the certificate thumbprint");
26275
26276 /* Set the policy */
26277 channel->securityPolicy = securityPolicy;
26278 return UA_STATUSCODE_GOOD;
26279}
26280
26281/* Hides some errors before sending them to a client according to the
26282 * standard. */
26283static void
26284hideErrors(UA_TcpErrorMessage *const error) {
26285 switch(error->error) {
26286 case UA_STATUSCODE_BADCERTIFICATEUNTRUSTED:
26287 case UA_STATUSCODE_BADCERTIFICATEREVOKED:
26288 case UA_STATUSCODE_BADCERTIFICATEISSUERREVOKED:
26289 case UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE:
26290 case UA_STATUSCODE_BADCERTIFICATEISSUERUSENOTALLOWED:
26291 error->error = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
26292 error->reason = UA_STRING_NULL;
26293 break;
26294 // TODO: Check if these are all cases that need to be covered.
26295 default:
26296 break;
26297 }
26298}
26299
26300UA_Boolean
26301UA_SecureChannel_isConnected(UA_SecureChannel *channel) {
26302 return (channel->state > UA_SECURECHANNELSTATE_CLOSED &&
26303 channel->state < UA_SECURECHANNELSTATE_CLOSING);
26304}
26305
26306void
26307UA_SecureChannel_sendError(UA_SecureChannel *channel, UA_TcpErrorMessage *error) {
26308 if(!UA_SecureChannel_isConnected(channel))
26309 return;
26310
26311 hideErrors(error);
26312
26313 UA_TcpMessageHeader header;
26314 header.messageTypeAndChunkType = UA_MESSAGETYPE_ERR + UA_CHUNKTYPE_FINAL;
26315 /* Header + ErrorMessage (error + reasonLength_field + length) */
26316 header.messageSize = 8 + (4 + 4 + (UA_UInt32)error->reason.length);
26317
26318 /* Get the send buffer from the network layer */
26319 UA_ConnectionManager *cm = channel->connectionManager;
26320 UA_ByteString msg = UA_BYTESTRING_NULL;
26321 UA_StatusCode retval = cm->allocNetworkBuffer(cm, channel->connectionId,
26322 &msg, header.messageSize);
26323 if(retval != UA_STATUSCODE_GOOD)
26324 return;
26325
26326 /* Encode and send the response */
26327 UA_Byte *bufPos = msg.data;
26328 const UA_Byte *bufEnd = &msg.data[msg.length];
26329 retval |= UA_encodeBinaryInternal(src: &header,
26330 type: &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER],
26331 bufPos: &bufPos, bufEnd: &bufEnd, NULL, NULL);
26332 retval |= UA_encodeBinaryInternal(src: error,
26333 type: &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE],
26334 bufPos: &bufPos, bufEnd: &bufEnd, NULL, NULL);
26335 (void)retval; /* Encoding of these cannot fail */
26336 msg.length = header.messageSize;
26337 cm->sendWithConnection(cm, channel->connectionId, &UA_KEYVALUEMAP_NULL, &msg);
26338}
26339
26340static void
26341UA_Chunk_delete(UA_Chunk *chunk) {
26342 if(chunk->copied)
26343 UA_ByteString_clear(p: &chunk->bytes);
26344 UA_free(ptr: chunk);
26345}
26346
26347static void
26348deleteChunks(UA_SecureChannel *channel) {
26349 UA_Chunk *chunk, *chunk_tmp;
26350 TAILQ_FOREACH_SAFE(chunk, &channel->chunks, pointers, chunk_tmp) {
26351 TAILQ_REMOVE(&channel->chunks, chunk, pointers);
26352 UA_Chunk_delete(chunk);
26353 }
26354 channel->chunksCount = 0;
26355 channel->chunksLength = 0;
26356}
26357
26358void
26359UA_SecureChannel_deleteBuffered(UA_SecureChannel *channel) {
26360 deleteChunks(channel);
26361 if(channel->unprocessedCopied)
26362 UA_ByteString_clear(p: &channel->unprocessed);
26363}
26364
26365void
26366UA_SecureChannel_shutdown(UA_SecureChannel *channel,
26367 UA_ShutdownReason shutdownReason) {
26368 /* No open socket or already closing -> nothing to do */
26369 if(!UA_SecureChannel_isConnected(channel))
26370 return;
26371
26372 /* Set the shutdown event for diagnostics */
26373 channel->shutdownReason= shutdownReason;
26374
26375 /* Trigger the async closing of the connection */
26376 UA_ConnectionManager *cm = channel->connectionManager;
26377 cm->closeConnection(cm, channel->connectionId);
26378 channel->state = UA_SECURECHANNELSTATE_CLOSING;
26379}
26380
26381void
26382UA_SecureChannel_clear(UA_SecureChannel *channel) {
26383 /* Detach Sessions from the SecureChannel. This also removes outstanding
26384 * Publish requests whose RequestId is valid only for the SecureChannel. */
26385 UA_SessionHeader *sh, *sh_tmp;
26386 SLIST_FOREACH_SAFE(sh, &channel->sessions, next, sh_tmp) {
26387 if(sh->serverSession) {
26388 UA_Session_detachFromSecureChannel(session: (UA_Session *)sh);
26389 } else {
26390 sh->channel = NULL;
26391 SLIST_REMOVE_HEAD(&channel->sessions, next);
26392 }
26393 }
26394
26395 /* Delete the channel context for the security policy */
26396 if(channel->securityPolicy) {
26397 channel->securityPolicy->channelModule.deleteContext(channel->channelContext);
26398 channel->securityPolicy = NULL;
26399 channel->channelContext = NULL;
26400 }
26401
26402 /* Remove remaining delayed callback */
26403 if(channel->connectionManager &&
26404 channel->connectionManager->eventSource.eventLoop) {
26405 UA_EventLoop *el = channel->connectionManager->eventSource.eventLoop;
26406 el->removeDelayedCallback(el, &channel->unprocessedDelayed);
26407 }
26408
26409 /* The EventLoop connection is no longer valid */
26410 channel->connectionId = 0;
26411 channel->connectionManager = NULL;
26412
26413 /* Clean up the SecurityToken */
26414 UA_ChannelSecurityToken_clear(p: &channel->securityToken);
26415 UA_ChannelSecurityToken_clear(p: &channel->altSecurityToken);
26416
26417 /* Clean up certificate and nonces */
26418 UA_ByteString_clear(p: &channel->remoteCertificate);
26419 UA_ByteString_clear(p: &channel->localNonce);
26420 UA_ByteString_clear(p: &channel->remoteNonce);
26421
26422 /* Clean up endpointUrl */
26423 UA_String_clear(p: &channel->endpointUrl);
26424
26425 /* Delete remaining chunks */
26426 UA_SecureChannel_deleteBuffered(channel);
26427
26428 /* Reset the SecureChannel for reuse (in the client) */
26429 channel->securityMode = UA_MESSAGESECURITYMODE_INVALID;
26430 channel->shutdownReason = UA_SHUTDOWNREASON_CLOSE;
26431 memset(s: &channel->config, c: 0, n: sizeof(UA_ConnectionConfig));
26432 channel->receiveSequenceNumber = 0;
26433 channel->sendSequenceNumber = 0;
26434
26435 /* Set the state to closed */
26436 channel->state = UA_SECURECHANNELSTATE_CLOSED;
26437 channel->renewState = UA_SECURECHANNELRENEWSTATE_NORMAL;
26438}
26439
26440UA_StatusCode
26441UA_SecureChannel_processHELACK(UA_SecureChannel *channel,
26442 const UA_TcpAcknowledgeMessage *remoteConfig) {
26443 /* The lowest common version is used by both sides */
26444 if(channel->config.protocolVersion > remoteConfig->protocolVersion)
26445 channel->config.protocolVersion = remoteConfig->protocolVersion;
26446
26447 /* Can we receive the max send size? */
26448 if(channel->config.sendBufferSize > remoteConfig->receiveBufferSize)
26449 channel->config.sendBufferSize = remoteConfig->receiveBufferSize;
26450
26451 /* Can we send the max receive size? */
26452 if(channel->config.recvBufferSize > remoteConfig->sendBufferSize)
26453 channel->config.recvBufferSize = remoteConfig->sendBufferSize;
26454
26455 channel->config.remoteMaxMessageSize = remoteConfig->maxMessageSize;
26456 channel->config.remoteMaxChunkCount = remoteConfig->maxChunkCount;
26457
26458 /* Chunks of at least 8192 bytes must be permissible.
26459 * See Part 6, Clause 6.7.1 */
26460 if(channel->config.recvBufferSize < 8192 ||
26461 channel->config.sendBufferSize < 8192 ||
26462 (channel->config.remoteMaxMessageSize != 0 &&
26463 channel->config.remoteMaxMessageSize < 8192))
26464 return UA_STATUSCODE_BADINTERNALERROR;
26465
26466 return UA_STATUSCODE_GOOD;
26467}
26468
26469/* Sends an OPN message using asymmetric encryption if defined */
26470UA_StatusCode
26471UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel,
26472 UA_UInt32 requestId, const void *content,
26473 const UA_DataType *contentType) {
26474 UA_CHECK(channel->securityMode != UA_MESSAGESECURITYMODE_INVALID,
26475 return UA_STATUSCODE_BADSECURITYMODEREJECTED);
26476
26477 /* Can we use the connection manager? */
26478 UA_ConnectionManager *cm = channel->connectionManager;
26479 if(!UA_SecureChannel_isConnected(channel))
26480 return UA_STATUSCODE_BADCONNECTIONCLOSED;
26481
26482 const UA_SecurityPolicy *sp = channel->securityPolicy;
26483 UA_CHECK_MEM(sp, return UA_STATUSCODE_BADINTERNALERROR);
26484
26485 /* Allocate the message buffer */
26486 UA_ByteString buf = UA_BYTESTRING_NULL;
26487 UA_StatusCode res = cm->allocNetworkBuffer(cm, channel->connectionId, &buf,
26488 channel->config.sendBufferSize);
26489 UA_CHECK_STATUS(res, return res);
26490
26491 /* Restrict buffer to the available space for the payload */
26492 UA_Byte *buf_pos = buf.data;
26493 const UA_Byte *buf_end = &buf.data[buf.length];
26494 hideBytesAsym(channel, buf_start: &buf_pos, buf_end: &buf_end);
26495
26496 /* Define variables here to pacify some compilers wrt goto */
26497 size_t securityHeaderLength, pre_sig_length, total_length, encryptedLength;
26498
26499 /* Encode the message type and content */
26500 res |= UA_NodeId_encodeBinary(src: &contentType->binaryEncodingId, bufPos: &buf_pos, bufEnd: buf_end);
26501 res |= UA_encodeBinaryInternal(src: content, type: contentType, bufPos: &buf_pos, bufEnd: &buf_end, NULL, NULL);
26502 UA_CHECK_STATUS(res, goto error);
26503
26504 /* Compute the header length */
26505 securityHeaderLength = calculateAsymAlgSecurityHeaderLength(channel);
26506
26507 /* Add padding to the chunk. Also pad if the securityMode is SIGN_ONLY,
26508 * since we are using asymmetric communication to exchange keys and thus
26509 * need to encrypt. */
26510#ifdef UA_ENABLE_ENCRYPTION
26511 if(channel->securityMode != UA_MESSAGESECURITYMODE_NONE)
26512 padChunk(channel, cm: &channel->securityPolicy->asymmetricModule.cryptoModule,
26513 start: &buf.data[UA_SECURECHANNEL_CHANNELHEADER_LENGTH + securityHeaderLength],
26514 pos: &buf_pos);
26515#endif
26516
26517 /* The total message length */
26518 pre_sig_length = (uintptr_t)buf_pos - (uintptr_t)buf.data;
26519 total_length = pre_sig_length;
26520 if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
26521 channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
26522 total_length += sp->asymmetricModule.cryptoModule.signatureAlgorithm.
26523 getLocalSignatureSize(channel->channelContext);
26524
26525 /* The total message length is known here which is why we encode the headers
26526 * at this step and not earlier. */
26527 res = prependHeadersAsym(channel, header_pos: buf.data, buf_end, totalLength: total_length,
26528 securityHeaderLength, requestId, finalLength: &encryptedLength);
26529 UA_CHECK_STATUS(res, goto error);
26530
26531#ifdef UA_ENABLE_ENCRYPTION
26532 res = signAndEncryptAsym(channel, preSignLength: pre_sig_length, buf: &buf,
26533 securityHeaderLength, totalLength: total_length);
26534 UA_CHECK_STATUS(res, goto error);
26535#endif
26536
26537 /* Send the message, the buffer is freed in the network layer */
26538 buf.length = encryptedLength;
26539 return cm->sendWithConnection(cm, channel->connectionId, &UA_KEYVALUEMAP_NULL, &buf);
26540
26541 error:
26542 cm->freeNetworkBuffer(cm, channel->connectionId, &buf);
26543 return res;
26544}
26545
26546/* Will this chunk surpass the capacity of the SecureChannel for the message? */
26547static UA_StatusCode
26548adjustCheckMessageLimitsSym(UA_MessageContext *mc, size_t bodyLength) {
26549 mc->messageSizeSoFar += bodyLength;
26550 mc->chunksSoFar++;
26551
26552 UA_SecureChannel *channel = mc->channel;
26553 if(mc->messageSizeSoFar > channel->config.localMaxMessageSize &&
26554 channel->config.localMaxMessageSize != 0)
26555 return UA_STATUSCODE_BADRESPONSETOOLARGE;
26556
26557 if(mc->chunksSoFar > channel->config.localMaxChunkCount &&
26558 channel->config.localMaxChunkCount != 0)
26559 return UA_STATUSCODE_BADRESPONSETOOLARGE;
26560
26561 return UA_STATUSCODE_GOOD;
26562}
26563
26564static UA_StatusCode
26565encodeHeadersSym(UA_MessageContext *mc, size_t totalLength) {
26566 UA_SecureChannel *channel = mc->channel;
26567 UA_Byte *header_pos = mc->messageBuffer.data;
26568
26569 UA_TcpMessageHeader header;
26570 header.messageTypeAndChunkType = mc->messageType;
26571 header.messageSize = (UA_UInt32)totalLength;
26572 if(mc->final)
26573 header.messageTypeAndChunkType += UA_CHUNKTYPE_FINAL;
26574 else
26575 header.messageTypeAndChunkType += UA_CHUNKTYPE_INTERMEDIATE;
26576
26577 /* Increase the sequence number in the channel */
26578 channel->sendSequenceNumber++;
26579
26580 UA_SequenceHeader seqHeader;
26581 seqHeader.requestId = mc->requestId;
26582 seqHeader.sequenceNumber = channel->sendSequenceNumber;
26583
26584 UA_StatusCode res = UA_STATUSCODE_GOOD;
26585 res |= UA_encodeBinaryInternal(src: &header, type: &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER],
26586 bufPos: &header_pos, bufEnd: &mc->buf_end, NULL, NULL);
26587 res |= UA_UInt32_encodeBinary(src: &channel->securityToken.channelId,
26588 bufPos: &header_pos, bufEnd: mc->buf_end);
26589 res |= UA_UInt32_encodeBinary(src: &channel->securityToken.tokenId,
26590 bufPos: &header_pos, bufEnd: mc->buf_end);
26591 res |= UA_encodeBinaryInternal(src: &seqHeader, type: &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER],
26592 bufPos: &header_pos, bufEnd: &mc->buf_end, NULL, NULL);
26593 return res;
26594}
26595
26596static UA_StatusCode
26597sendSymmetricChunk(UA_MessageContext *mc) {
26598 UA_SecureChannel *channel = mc->channel;
26599 const UA_SecurityPolicy *sp = channel->securityPolicy;
26600 UA_ConnectionManager *cm = channel->connectionManager;
26601 if(!UA_SecureChannel_isConnected(channel))
26602 return UA_STATUSCODE_BADCONNECTIONCLOSED;
26603
26604 /* The size of the message payload */
26605 size_t bodyLength = (uintptr_t)mc->buf_pos -
26606 (uintptr_t)&mc->messageBuffer.data[UA_SECURECHANNEL_SYMMETRIC_HEADER_TOTALLENGTH];
26607
26608 /* Early-declare variables so we can use a goto in the error case */
26609 size_t total_length = 0;
26610 size_t pre_sig_length = 0;
26611
26612 /* Check if chunk exceeds the limits for the overall message */
26613 UA_StatusCode res = adjustCheckMessageLimitsSym(mc, bodyLength);
26614 UA_CHECK_STATUS(res, goto error);
26615
26616 UA_LOG_TRACE_CHANNEL(sp->logger, channel,
26617 "Send from a symmetric message buffer of length %lu "
26618 "a message of header+payload length of %lu",
26619 (long unsigned int)mc->messageBuffer.length,
26620 (long unsigned int)
26621 ((uintptr_t)mc->buf_pos - (uintptr_t)mc->messageBuffer.data));
26622
26623#ifdef UA_ENABLE_ENCRYPTION
26624 /* Add padding if the message is encrypted */
26625 if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
26626 padChunk(channel, cm: &sp->symmetricModule.cryptoModule,
26627 start: &mc->messageBuffer.data[UA_SECURECHANNEL_SYMMETRIC_HEADER_UNENCRYPTEDLENGTH],
26628 pos: &mc->buf_pos);
26629#endif
26630
26631 /* Compute the total message length */
26632 pre_sig_length = (uintptr_t)mc->buf_pos - (uintptr_t)mc->messageBuffer.data;
26633 total_length = pre_sig_length;
26634 if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
26635 channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
26636 total_length += sp->symmetricModule.cryptoModule.signatureAlgorithm.
26637 getLocalSignatureSize(channel->channelContext);
26638
26639 UA_LOG_TRACE_CHANNEL(sp->logger, channel,
26640 "Send from a symmetric message buffer of length %lu "
26641 "a message of length %lu",
26642 (long unsigned int)mc->messageBuffer.length,
26643 (long unsigned int)total_length);
26644
26645 /* Space for the padding and the signature have been reserved in setBufPos() */
26646 UA_assert(total_length <= channel->config.sendBufferSize);
26647
26648 /* Adjust the buffer size of the network layer */
26649 mc->messageBuffer.length = total_length;
26650
26651 /* Generate and encode the header for symmetric messages */
26652 res = encodeHeadersSym(mc, totalLength: total_length);
26653 UA_CHECK_STATUS(res, goto error);
26654
26655#ifdef UA_ENABLE_ENCRYPTION
26656 /* Sign and encrypt the messge */
26657 res = signAndEncryptSym(messageContext: mc, preSigLength: pre_sig_length, totalLength: total_length);
26658 UA_CHECK_STATUS(res, goto error);
26659#endif
26660
26661 /* Send the chunk. The buffer is freed in the network layer. If sending goes
26662 * wrong, the connection is removed in the next iteration of the
26663 * SecureChannel. Set the SecureChannel to closing already. */
26664 res = cm->sendWithConnection(cm, channel->connectionId,
26665 &UA_KEYVALUEMAP_NULL, &mc->messageBuffer);
26666 if(res != UA_STATUSCODE_GOOD && UA_SecureChannel_isConnected(channel))
26667 channel->state = UA_SECURECHANNELSTATE_CLOSING;
26668
26669 error:
26670 /* Free the unused message buffer */
26671 cm->freeNetworkBuffer(cm, channel->connectionId, &mc->messageBuffer);
26672 return res;
26673}
26674
26675/* Callback from the encoding layer. Send the chunk and replace the buffer. */
26676static UA_StatusCode
26677sendSymmetricEncodingCallback(void *data, UA_Byte **buf_pos,
26678 const UA_Byte **buf_end) {
26679 /* Set buf values from encoding in the messagecontext */
26680 UA_MessageContext *mc = (UA_MessageContext *)data;
26681 mc->buf_pos = *buf_pos;
26682 mc->buf_end = *buf_end;
26683
26684 /* Send out */
26685 UA_StatusCode res = sendSymmetricChunk(mc);
26686 UA_CHECK_STATUS(res, return res);
26687
26688 /* Set a new buffer for the next chunk */
26689 UA_ConnectionManager *cm = mc->channel->connectionManager;
26690 if(!UA_SecureChannel_isConnected(channel: mc->channel))
26691 return UA_STATUSCODE_BADCONNECTIONCLOSED;
26692
26693 res = cm->allocNetworkBuffer(cm, mc->channel->connectionId,
26694 &mc->messageBuffer,
26695 mc->channel->config.sendBufferSize);
26696 UA_CHECK_STATUS(res, return res);
26697
26698 /* Hide bytes for header, padding and signature */
26699 setBufPos(mc);
26700 *buf_pos = mc->buf_pos;
26701 *buf_end = mc->buf_end;
26702 return UA_STATUSCODE_GOOD;
26703}
26704
26705UA_StatusCode
26706UA_MessageContext_begin(UA_MessageContext *mc, UA_SecureChannel *channel,
26707 UA_UInt32 requestId, UA_MessageType messageType) {
26708 UA_CHECK(messageType == UA_MESSAGETYPE_MSG || messageType == UA_MESSAGETYPE_CLO,
26709 return UA_STATUSCODE_BADINTERNALERROR);
26710
26711 UA_ConnectionManager *cm = channel->connectionManager;
26712 if(!UA_SecureChannel_isConnected(channel))
26713 return UA_STATUSCODE_BADCONNECTIONCLOSED;
26714
26715 /* Create the chunking info structure */
26716 mc->channel = channel;
26717 mc->requestId = requestId;
26718 mc->chunksSoFar = 0;
26719 mc->messageSizeSoFar = 0;
26720 mc->final = false;
26721 mc->messageBuffer = UA_BYTESTRING_NULL;
26722 mc->messageType = messageType;
26723
26724 /* Allocate the message buffer */
26725 UA_StatusCode res =
26726 cm->allocNetworkBuffer(cm, channel->connectionId,
26727 &mc->messageBuffer,
26728 channel->config.sendBufferSize);
26729 UA_CHECK_STATUS(res, return res);
26730
26731 /* Hide bytes for header, padding and signature */
26732 setBufPos(mc);
26733 return UA_STATUSCODE_GOOD;
26734}
26735
26736UA_StatusCode
26737UA_MessageContext_encode(UA_MessageContext *mc, const void *content,
26738 const UA_DataType *contentType) {
26739 UA_StatusCode res =
26740 UA_encodeBinaryInternal(src: content, type: contentType, bufPos: &mc->buf_pos, bufEnd: &mc->buf_end,
26741 exchangeCallback: sendSymmetricEncodingCallback, exchangeHandle: mc);
26742 if(res != UA_STATUSCODE_GOOD && mc->messageBuffer.length > 0)
26743 UA_MessageContext_abort(mc);
26744 return res;
26745}
26746
26747UA_StatusCode
26748UA_MessageContext_finish(UA_MessageContext *mc) {
26749 mc->final = true;
26750 return sendSymmetricChunk(mc);
26751}
26752
26753void
26754UA_MessageContext_abort(UA_MessageContext *mc) {
26755 UA_ConnectionManager *cm = mc->channel->connectionManager;
26756 if(!UA_SecureChannel_isConnected(channel: mc->channel))
26757 return;
26758 cm->freeNetworkBuffer(cm, mc->channel->connectionId, &mc->messageBuffer);
26759}
26760
26761UA_StatusCode
26762UA_SecureChannel_sendSymmetricMessage(UA_SecureChannel *channel, UA_UInt32 requestId,
26763 UA_MessageType messageType, void *payload,
26764 const UA_DataType *payloadType) {
26765 if(!channel || !payload || !payloadType)
26766 return UA_STATUSCODE_BADINTERNALERROR;
26767
26768 if(channel->state != UA_SECURECHANNELSTATE_OPEN)
26769 return UA_STATUSCODE_BADCONNECTIONCLOSED;
26770
26771 UA_MessageContext mc;
26772 UA_StatusCode res = UA_MessageContext_begin(mc: &mc, channel, requestId, messageType);
26773 UA_CHECK_STATUS(res, return res);
26774
26775 /* Assert's required for clang-analyzer */
26776 UA_assert(mc.buf_pos ==
26777 &mc.messageBuffer.data[UA_SECURECHANNEL_SYMMETRIC_HEADER_TOTALLENGTH]);
26778 UA_assert(mc.buf_end <= &mc.messageBuffer.data[mc.messageBuffer.length]);
26779
26780 res = UA_MessageContext_encode(mc: &mc, content: &payloadType->binaryEncodingId,
26781 contentType: &UA_TYPES[UA_TYPES_NODEID]);
26782 UA_CHECK_STATUS(res, return res);
26783
26784 res = UA_MessageContext_encode(mc: &mc, content: payload, contentType: payloadType);
26785 UA_CHECK_STATUS(res, return res);
26786
26787 return UA_MessageContext_finish(mc: &mc);
26788}
26789
26790/********************************/
26791/* Receive and Process Messages */
26792/********************************/
26793
26794/* Does the sequence number match? Otherwise try to rollover. See Part 6,
26795 * Section 6.7.2.4 of the standard. */
26796#define UA_SEQUENCENUMBER_ROLLOVER 4294966271
26797
26798#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
26799static UA_StatusCode
26800processSequenceNumberSym(UA_SecureChannel *channel, UA_UInt32 sequenceNumber) {
26801 if(sequenceNumber != channel->receiveSequenceNumber + 1) {
26802 if(channel->receiveSequenceNumber + 1 <= UA_SEQUENCENUMBER_ROLLOVER ||
26803 sequenceNumber >= 1024)
26804 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
26805 channel->receiveSequenceNumber = sequenceNumber - 1; /* Roll over */
26806 }
26807 ++channel->receiveSequenceNumber;
26808 return UA_STATUSCODE_GOOD;
26809}
26810#endif
26811
26812static UA_StatusCode
26813unpackPayloadOPN(UA_SecureChannel *channel, UA_Chunk *chunk) {
26814 UA_assert(chunk->bytes.length >= UA_SECURECHANNEL_MESSAGE_MIN_LENGTH);
26815 size_t offset = UA_SECURECHANNEL_MESSAGEHEADER_LENGTH; /* Skip the message header */
26816 UA_UInt32 secureChannelId;
26817 UA_StatusCode res = UA_UInt32_decodeBinary(src: &chunk->bytes, offset: &offset, dst: &secureChannelId);
26818 UA_assert(res == UA_STATUSCODE_GOOD);
26819
26820 UA_AsymmetricAlgorithmSecurityHeader asymHeader;
26821 res = UA_decodeBinaryInternal(src: &chunk->bytes, offset: &offset, dst: &asymHeader,
26822 type: &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER], NULL);
26823 UA_CHECK_STATUS(res, return res);
26824
26825 if(asymHeader.senderCertificate.length > 0) {
26826 if(channel->certificateVerification && channel->certificateVerification->verifyCertificate)
26827 res = channel->certificateVerification->
26828 verifyCertificate(channel->certificateVerification,
26829 &asymHeader.senderCertificate);
26830 else
26831 res = UA_STATUSCODE_BADINTERNALERROR;
26832 UA_CHECK_STATUS(res, goto error);
26833 }
26834
26835 /* New channel, create a security policy context and attach */
26836 UA_assert(channel->processOPNHeader);
26837 res = channel->processOPNHeader(channel->processOPNHeaderApplication,
26838 channel, &asymHeader);
26839 UA_CHECK_STATUS(res, goto error);
26840
26841 /* On the client side, take the SecureChannelId from the first response */
26842 if(secureChannelId != 0 && channel->securityToken.channelId == 0)
26843 channel->securityToken.channelId = secureChannelId;
26844
26845 /* Check the ChannelId */
26846#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
26847 if(secureChannelId != channel->securityToken.channelId) {
26848 /* Allow the channel id to be different if the sent channel id is zero
26849 * and the SecurityToken is not initialized. This only happens on the
26850 * server side before we had a chance to tell the client which ChannelId
26851 * to use. */
26852 if(secureChannelId != 0 || channel->securityToken.tokenId != 0) {
26853 res = UA_STATUSCODE_BADSECURECHANNELIDINVALID;
26854 goto error;
26855 }
26856 }
26857#endif
26858
26859 /* Check the header for the channel's security policy */
26860 res = checkAsymHeader(channel, asymHeader: &asymHeader);
26861 UA_AsymmetricAlgorithmSecurityHeader_clear(p: &asymHeader);
26862 UA_CHECK_STATUS(res, return res);
26863
26864 /* Decrypt the chunk payload */
26865 res = decryptAndVerifyChunk(channel,
26866 cryptoModule: &channel->securityPolicy->asymmetricModule.cryptoModule,
26867 messageType: chunk->messageType, chunk: &chunk->bytes, offset);
26868 UA_CHECK_STATUS(res, return res);
26869
26870 /* Decode the SequenceHeader */
26871 UA_SequenceHeader sequenceHeader;
26872 res = UA_decodeBinaryInternal(src: &chunk->bytes, offset: &offset, dst: &sequenceHeader,
26873 type: &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER], NULL);
26874 UA_CHECK_STATUS(res, return res);
26875
26876 /* Set the sequence number for the channel from which to count up */
26877 channel->receiveSequenceNumber = sequenceHeader.sequenceNumber;
26878 chunk->requestId = sequenceHeader.requestId; /* Set the RequestId of the chunk */
26879
26880 /* Use only the payload */
26881 chunk->bytes.data += offset;
26882 chunk->bytes.length -= offset;
26883 return UA_STATUSCODE_GOOD;
26884
26885error:
26886 UA_AsymmetricAlgorithmSecurityHeader_clear(p: &asymHeader);
26887 return res;
26888}
26889
26890static UA_StatusCode
26891unpackPayloadMSG(UA_SecureChannel *channel, UA_Chunk *chunk) {
26892 UA_CHECK_MEM(channel->securityPolicy, return UA_STATUSCODE_BADINTERNALERROR);
26893
26894 UA_assert(chunk->bytes.length >= UA_SECURECHANNEL_MESSAGE_MIN_LENGTH);
26895 size_t offset = UA_SECURECHANNEL_MESSAGEHEADER_LENGTH; /* Skip the message header */
26896 UA_UInt32 secureChannelId;
26897 UA_UInt32 tokenId; /* SymmetricAlgorithmSecurityHeader */
26898 UA_StatusCode res = UA_STATUSCODE_GOOD;
26899 res |= UA_UInt32_decodeBinary(src: &chunk->bytes, offset: &offset, dst: &secureChannelId);
26900 res |= UA_UInt32_decodeBinary(src: &chunk->bytes, offset: &offset, dst: &tokenId);
26901 UA_assert(offset == UA_SECURECHANNEL_MESSAGE_MIN_LENGTH);
26902 UA_assert(res == UA_STATUSCODE_GOOD);
26903
26904#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
26905 /* Check the ChannelId. Non-opened channels have the id zero. */
26906 if(secureChannelId != channel->securityToken.channelId)
26907 return UA_STATUSCODE_BADSECURECHANNELIDINVALID;
26908#endif
26909
26910 /* Check (and revolve) the SecurityToken */
26911 res = checkSymHeader(channel, tokenId);
26912 UA_CHECK_STATUS(res, return res);
26913
26914 /* Decrypt the chunk payload */
26915 res = decryptAndVerifyChunk(channel,
26916 cryptoModule: &channel->securityPolicy->symmetricModule.cryptoModule,
26917 messageType: chunk->messageType, chunk: &chunk->bytes, offset);
26918 UA_CHECK_STATUS(res, return res);
26919
26920 /* Check the sequence number. Skip sequence number checking for fuzzer to
26921 * improve coverage */
26922 UA_SequenceHeader sequenceHeader;
26923 res = UA_decodeBinaryInternal(src: &chunk->bytes, offset: &offset, dst: &sequenceHeader,
26924 type: &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER], NULL);
26925#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
26926 res |= processSequenceNumberSym(channel, sequenceNumber: sequenceHeader.sequenceNumber);
26927#endif
26928 UA_CHECK_STATUS(res, return res);
26929
26930 chunk->requestId = sequenceHeader.requestId; /* Set the RequestId of the chunk */
26931
26932 /* Use only the payload */
26933 chunk->bytes.data += offset;
26934 chunk->bytes.length -= offset;
26935 return UA_STATUSCODE_GOOD;
26936}
26937
26938static UA_StatusCode
26939extractCompleteChunk(UA_SecureChannel *channel, UA_Chunk *chunk) {
26940 /* At least 8 byte needed for the header */
26941 size_t offset = channel->unprocessedOffset;
26942 size_t remaining = channel->unprocessed.length - offset;
26943 if(remaining < UA_SECURECHANNEL_MESSAGEHEADER_LENGTH)
26944 return UA_STATUSCODE_GOOD;
26945
26946 /* Decoding the header cannot fail */
26947 UA_TcpMessageHeader hdr;
26948 UA_StatusCode res =
26949 UA_decodeBinaryInternal(src: &channel->unprocessed, offset: &offset, dst: &hdr,
26950 type: &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER], NULL);
26951 UA_assert(res == UA_STATUSCODE_GOOD);
26952 (void)res; /* pacify compilers if assert is ignored */
26953 UA_MessageType msgType = (UA_MessageType)
26954 (hdr.messageTypeAndChunkType & UA_BITMASK_MESSAGETYPE);
26955 UA_ChunkType chunkType = (UA_ChunkType)
26956 (hdr.messageTypeAndChunkType & UA_BITMASK_CHUNKTYPE);
26957
26958 /* The message size is not allowed */
26959 if(hdr.messageSize < UA_SECURECHANNEL_MESSAGE_MIN_LENGTH)
26960 return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
26961 if(hdr.messageSize > channel->config.recvBufferSize)
26962 return UA_STATUSCODE_BADTCPMESSAGETOOLARGE;
26963
26964 /* Incomplete chunk. Continue processing later. */
26965 if(hdr.messageSize > remaining)
26966 return UA_STATUSCODE_GOOD;
26967
26968 /* Set the chunk information */
26969 chunk->bytes.data = channel->unprocessed.data + channel->unprocessedOffset;
26970 chunk->bytes.length = hdr.messageSize;
26971 chunk->messageType = msgType;
26972 chunk->chunkType = chunkType;
26973 chunk->requestId = 0;
26974 chunk->copied = false;
26975
26976 /* Increase the unprocessed offset */
26977 channel->unprocessedOffset += hdr.messageSize;
26978
26979 /* Validate, decrypt and unpack the chunk payload */
26980 switch(msgType) {
26981 case UA_MESSAGETYPE_OPN:
26982 if(chunkType != UA_CHUNKTYPE_FINAL)
26983 return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
26984 if(channel->state != UA_SECURECHANNELSTATE_OPEN &&
26985 channel->state != UA_SECURECHANNELSTATE_OPN_SENT &&
26986 channel->state != UA_SECURECHANNELSTATE_ACK_SENT)
26987 return UA_STATUSCODE_BADINVALIDSTATE;
26988 res = unpackPayloadOPN(channel, chunk);
26989 break;
26990
26991 case UA_MESSAGETYPE_MSG:
26992 case UA_MESSAGETYPE_CLO:
26993 if(chunkType != UA_CHUNKTYPE_FINAL &&
26994 chunkType != UA_CHUNKTYPE_INTERMEDIATE &&
26995 chunkType != UA_CHUNKTYPE_ABORT)
26996 return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
26997 if(channel->state != UA_SECURECHANNELSTATE_OPEN)
26998 return UA_STATUSCODE_BADINVALIDSTATE;
26999 res = unpackPayloadMSG(channel, chunk);
27000 break;
27001
27002 case UA_MESSAGETYPE_RHE:
27003 case UA_MESSAGETYPE_HEL:
27004 case UA_MESSAGETYPE_ACK:
27005 case UA_MESSAGETYPE_ERR:
27006 if(chunkType != UA_CHUNKTYPE_FINAL)
27007 return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
27008 /* Hide the message header */
27009 chunk->bytes.data += UA_SECURECHANNEL_MESSAGEHEADER_LENGTH;
27010 chunk->bytes.length -= UA_SECURECHANNEL_MESSAGEHEADER_LENGTH;
27011 break;
27012
27013 default:
27014 res = UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
27015 break;
27016 }
27017 return res;
27018}
27019
27020UA_StatusCode
27021UA_SecureChannel_loadBuffer(UA_SecureChannel *channel, const UA_ByteString buffer) {
27022 /* Append to the previous unprocessed buffer */
27023 if(channel->unprocessed.length > 0) {
27024 UA_assert(channel->unprocessedCopied == true);
27025
27026 UA_Byte *t = (UA_Byte*)
27027 UA_realloc(ptr: channel->unprocessed.data,
27028 size: channel->unprocessed.length + buffer.length);
27029 if(!t)
27030 return UA_STATUSCODE_BADOUTOFMEMORY;
27031
27032 memcpy(dest: t + channel->unprocessed.length, src: buffer.data, n: buffer.length);
27033 channel->unprocessed.data = t;
27034 channel->unprocessed.length += buffer.length;
27035 return UA_STATUSCODE_GOOD;
27036 }
27037
27038 /* Use the new buffer directly */
27039 channel->unprocessed = buffer;
27040 channel->unprocessedCopied = false;
27041 return UA_STATUSCODE_GOOD;
27042}
27043
27044UA_StatusCode
27045UA_SecureChannel_getCompleteMessage(UA_SecureChannel *channel,
27046 UA_MessageType *messageType, UA_UInt32 *requestId,
27047 UA_ByteString *payload, UA_Boolean *copied) {
27048 UA_Chunk chunk, *pchunk;
27049 UA_StatusCode res = UA_STATUSCODE_GOOD;
27050
27051 extract_chunk:
27052 /* Extract+decode the next chunk from the buffer */
27053 memset(s: &chunk, c: 0, n: sizeof(UA_Chunk));
27054 res = extractCompleteChunk(channel, chunk: &chunk);
27055 if(chunk.bytes.length == 0 || res != UA_STATUSCODE_GOOD)
27056 return res; /* Error or no complete chunk could be extracted */
27057
27058 /* Process the chunk */
27059 switch(chunk.chunkType) {
27060 case UA_CHUNKTYPE_ABORT:
27061 /* Remove all chunks received so far. Then continue extracting chunks. */
27062 deleteChunks(channel);
27063 if(chunk.copied)
27064 UA_ByteString_clear(p: &chunk.bytes);
27065 goto extract_chunk;
27066
27067 case UA_CHUNKTYPE_INTERMEDIATE:
27068 /* Validate the resource limits */
27069 if((channel->config.localMaxChunkCount != 0 &&
27070 channel->chunksCount >= channel->config.localMaxChunkCount) ||
27071 (channel->config.localMaxMessageSize != 0 &&
27072 channel->chunksLength + chunk.bytes.length > channel->config.localMaxMessageSize)) {
27073 if(chunk.copied)
27074 UA_ByteString_clear(p: &chunk.bytes);
27075 return UA_STATUSCODE_BADTCPMESSAGETOOLARGE;
27076 }
27077
27078 /* Add the chunk to the queue. Then continue extracting more chunks. */
27079 pchunk = (UA_Chunk*)UA_malloc(size: sizeof(UA_Chunk));
27080 if(!pchunk) {
27081 if(chunk.copied)
27082 UA_ByteString_clear(p: &chunk.bytes);
27083 return UA_STATUSCODE_BADOUTOFMEMORY;
27084 }
27085 *pchunk = chunk;
27086 TAILQ_INSERT_TAIL(&channel->chunks, pchunk, pointers);
27087 channel->chunksCount++;
27088 channel->chunksLength += pchunk->bytes.length;
27089 goto extract_chunk;
27090
27091 case UA_CHUNKTYPE_FINAL:
27092 default:
27093 UA_assert(chunk.chunkType == UA_CHUNKTYPE_FINAL); /* Was checked before */
27094 break; /* A final chunk was received -- assemble the message */
27095 }
27096
27097 /* Compute the message size */
27098 size_t messageSize = chunk.bytes.length;
27099 UA_Chunk *first = NULL;
27100 TAILQ_FOREACH(pchunk, &channel->chunks, pointers) {
27101 if(chunk.requestId != pchunk->requestId)
27102 continue;
27103 if(chunk.messageType != pchunk->messageType) {
27104 if(chunk.copied)
27105 UA_ByteString_clear(p: &chunk.bytes);
27106 return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
27107 }
27108 if(!first)
27109 first = pchunk;
27110 messageSize += pchunk->bytes.length;
27111 }
27112
27113 /* Validate the assembled message size */
27114 if(channel->config.localMaxMessageSize != 0 &&
27115 channel->chunksLength > channel->config.localMaxMessageSize) {
27116 if(chunk.copied)
27117 UA_ByteString_clear(p: &chunk.bytes);
27118 return UA_STATUSCODE_BADTCPMESSAGETOOLARGE;
27119 }
27120
27121 /* Assemble the full payload and store it in chunk.bytes */
27122 if(messageSize > chunk.bytes.length) {
27123 UA_assert(first != NULL);
27124
27125 /* Allocate the full memory and initialize with the first chunk content.
27126 * Use realloc to speed up. */
27127 UA_ByteString message;
27128 if(first->copied) {
27129 message.data = (UA_Byte*)UA_realloc(ptr: first->bytes.data, size: messageSize);
27130 } else {
27131 message.data = (UA_Byte*)UA_malloc(size: messageSize);
27132 if(message.data)
27133 memcpy(dest: message.data, src: first->bytes.data, n: first->bytes.length);
27134 }
27135 if(!message.data) {
27136 if(chunk.copied)
27137 UA_ByteString_clear(p: &chunk.bytes);
27138 return UA_STATUSCODE_BADOUTOFMEMORY;
27139 }
27140 message.length = first->bytes.length;
27141
27142 /* Remove the the first chunk */
27143 pchunk = TAILQ_NEXT(first, pointers);
27144 first->copied = false;
27145 channel->chunksCount--;
27146 channel->chunksLength -= first->bytes.length;
27147 TAILQ_REMOVE(&channel->chunks, first, pointers);
27148 UA_Chunk_delete(chunk: first);
27149
27150 /* Copy over the content from the remaining intermediate chunks.
27151 * And remove them right away. */
27152 UA_Chunk *next;
27153 for(; pchunk; pchunk = next) {
27154 next = TAILQ_NEXT(pchunk, pointers);
27155 if(chunk.requestId != pchunk->requestId)
27156 continue;
27157 memcpy(dest: message.data + message.length, src: pchunk->bytes.data, n: pchunk->bytes.length);
27158 message.length += pchunk->bytes.length;
27159 channel->chunksCount--;
27160 channel->chunksLength -= pchunk->bytes.length;
27161 TAILQ_REMOVE(&channel->chunks, pchunk, pointers);
27162 UA_Chunk_delete(chunk: pchunk);
27163 }
27164
27165 /* Copy over the content from the final chunk */
27166 memcpy(dest: message.data + message.length, src: chunk.bytes.data, n: chunk.bytes.length);
27167 message.length += chunk.bytes.length;
27168 UA_assert(message.length == messageSize);
27169
27170 /* Set assembled message as the content of the final chunk */
27171 if(chunk.copied)
27172 UA_ByteString_clear(p: &chunk.bytes);
27173 chunk.bytes = message;
27174 chunk.copied = true;
27175 }
27176
27177 /* Return the assembled message */
27178 *requestId = chunk.requestId;
27179 *messageType = chunk.messageType;
27180 *payload = chunk.bytes;
27181 *copied = chunk.copied;
27182 return UA_STATUSCODE_GOOD;
27183}
27184
27185UA_StatusCode
27186UA_SecureChannel_persistBuffer(UA_SecureChannel *channel) {
27187 UA_StatusCode res = UA_STATUSCODE_GOOD;
27188
27189 /* Persist the chunks */
27190 UA_Chunk *chunk;
27191 TAILQ_FOREACH(chunk, &channel->chunks, pointers) {
27192 if(chunk->copied)
27193 continue;
27194 UA_ByteString tmp = UA_BYTESTRING_NULL;
27195 res |= UA_ByteString_copy(src: &chunk->bytes, dst: &tmp);
27196 chunk->bytes = tmp;
27197 chunk->copied = true;
27198 }
27199
27200 /* No unprocessed bytes remaining */
27201 UA_assert(channel->unprocessed.length >= channel->unprocessedOffset);
27202 if(channel->unprocessed.length == channel->unprocessedOffset) {
27203 if(channel->unprocessedCopied)
27204 UA_ByteString_clear(p: &channel->unprocessed);
27205 else
27206 UA_ByteString_init(p: &channel->unprocessed);
27207 channel->unprocessedOffset = 0;
27208 return res;
27209 }
27210
27211 /* Allocate a new unprocessed ByteString.
27212 * tmp is the empty string if malloc fails. */
27213 UA_ByteString tmp = UA_BYTESTRING_NULL;
27214 UA_ByteString remaining = channel->unprocessed;
27215 remaining.data += channel->unprocessedOffset;
27216 remaining.length -= channel->unprocessedOffset;
27217 res |= UA_ByteString_copy(src: &remaining, dst: &tmp);
27218 if(channel->unprocessedCopied)
27219 UA_ByteString_clear(p: &channel->unprocessed);
27220 channel->unprocessed = tmp;
27221 channel->unprocessedOffset = 0;
27222 channel->unprocessedCopied = true;
27223 return res;
27224}
27225
27226/**** amalgamated original file "/src/ua_securechannel_crypto.c" ****/
27227
27228/* This Source Code Form is subject to the terms of the Mozilla Public
27229 * License, v. 2.0. If a copy of the MPL was not distributed with this
27230 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27231 *
27232 * Copyright 2014-2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
27233 * Copyright 2014, 2016-2017 (c) Florian Palm
27234 * Copyright 2015-2016 (c) Sten Grüner
27235 * Copyright 2015 (c) Oleksiy Vasylyev
27236 * Copyright 2016 (c) TorbenD
27237 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
27238 * Copyright 2017-2018 (c) Mark Giraud, Fraunhofer IOSB
27239 */
27240
27241
27242
27243UA_StatusCode
27244UA_SecureChannel_generateLocalNonce(UA_SecureChannel *channel) {
27245 const UA_SecurityPolicy *sp = channel->securityPolicy;
27246 UA_CHECK_MEM(sp, return UA_STATUSCODE_BADINTERNALERROR);
27247 UA_LOG_DEBUG_CHANNEL(sp->logger, channel, "Generating new local nonce");
27248
27249 /* Is the length of the previous nonce correct? */
27250 size_t nonceLength = sp->symmetricModule.secureChannelNonceLength;
27251 if(channel->localNonce.length != nonceLength) {
27252 UA_ByteString_clear(p: &channel->localNonce);
27253 UA_StatusCode res = UA_ByteString_allocBuffer(bs: &channel->localNonce, length: nonceLength);
27254 UA_CHECK_STATUS(res, return res);
27255 }
27256
27257 /* Generate the nonce */
27258 return sp->symmetricModule.generateNonce(sp->policyContext, &channel->localNonce);
27259}
27260
27261UA_StatusCode
27262UA_SecureChannel_generateLocalKeys(const UA_SecureChannel *channel) {
27263 const UA_SecurityPolicy *sp = channel->securityPolicy;
27264 UA_CHECK_MEM(sp, return UA_STATUSCODE_BADINTERNALERROR);
27265 UA_LOG_TRACE_CHANNEL(sp->logger, channel, "Generating new local keys");
27266
27267 void *cc = channel->channelContext;
27268 const UA_SecurityPolicyChannelModule *cm = &sp->channelModule;
27269 const UA_SecurityPolicySymmetricModule *sm = &sp->symmetricModule;
27270 const UA_SecurityPolicyCryptoModule *crm = &sm->cryptoModule;
27271
27272 /* Generate symmetric key buffer of the required length. The block size is
27273 * identical for local/remote. */
27274 UA_ByteString buf;
27275 size_t encrKL = crm->encryptionAlgorithm.getLocalKeyLength(cc);
27276 size_t encrBS = crm->encryptionAlgorithm.getRemoteBlockSize(cc);
27277 size_t signKL = crm->signatureAlgorithm.getLocalKeyLength(cc);
27278 if(encrBS + signKL + encrKL == 0)
27279 return UA_STATUSCODE_GOOD; /* No keys to generate */
27280
27281 UA_StatusCode retval = UA_ByteString_allocBuffer(bs: &buf, length: encrBS + signKL + encrKL);
27282 UA_CHECK_STATUS(retval, return retval);
27283 UA_ByteString localSigningKey = {signKL, buf.data};
27284 UA_ByteString localEncryptingKey = {encrKL, &buf.data[signKL]};
27285 UA_ByteString localIv = {encrBS, &buf.data[signKL + encrKL]};
27286
27287 /* Generate key */
27288 retval = sm->generateKey(sp->policyContext, &channel->remoteNonce,
27289 &channel->localNonce, &buf);
27290 UA_CHECK_STATUS(retval, goto error);
27291
27292 /* Set the channel context */
27293 retval |= cm->setLocalSymSigningKey(cc, &localSigningKey);
27294 retval |= cm->setLocalSymEncryptingKey(cc, &localEncryptingKey);
27295 retval |= cm->setLocalSymIv(cc, &localIv);
27296
27297 error:
27298 UA_CHECK_STATUS(retval, UA_LOG_WARNING_CHANNEL(sp->logger, channel,
27299 "Could not generate local keys (statuscode: %s)",
27300 UA_StatusCode_name(retval)));
27301 UA_ByteString_clear(p: &buf);
27302 return retval;
27303}
27304
27305UA_StatusCode
27306generateRemoteKeys(const UA_SecureChannel *channel) {
27307 const UA_SecurityPolicy *sp = channel->securityPolicy;
27308 UA_CHECK_MEM(sp, return UA_STATUSCODE_BADINTERNALERROR);
27309 UA_LOG_TRACE_CHANNEL(sp->logger, channel, "Generating new remote keys");
27310
27311 void *cc = channel->channelContext;
27312 const UA_SecurityPolicyChannelModule *cm = &sp->channelModule;
27313 const UA_SecurityPolicySymmetricModule *sm = &sp->symmetricModule;
27314 const UA_SecurityPolicyCryptoModule *crm = &sm->cryptoModule;
27315
27316 /* Generate symmetric key buffer of the required length */
27317 UA_ByteString buf;
27318 size_t encrKL = crm->encryptionAlgorithm.getRemoteKeyLength(cc);
27319 size_t encrBS = crm->encryptionAlgorithm.getRemoteBlockSize(cc);
27320 size_t signKL = crm->signatureAlgorithm.getRemoteKeyLength(cc);
27321 if(encrBS + signKL + encrKL == 0)
27322 return UA_STATUSCODE_GOOD; /* No keys to generate */
27323
27324 UA_StatusCode retval = UA_ByteString_allocBuffer(bs: &buf, length: encrBS + signKL + encrKL);
27325 UA_CHECK_STATUS(retval, return retval);
27326 UA_ByteString remoteSigningKey = {signKL, buf.data};
27327 UA_ByteString remoteEncryptingKey = {encrKL, &buf.data[signKL]};
27328 UA_ByteString remoteIv = {encrBS, &buf.data[signKL + encrKL]};
27329
27330 /* Generate key */
27331 retval = sm->generateKey(sp->policyContext, &channel->localNonce,
27332 &channel->remoteNonce, &buf);
27333 UA_CHECK_STATUS(retval, goto error);
27334
27335 /* Set the channel context */
27336 retval |= cm->setRemoteSymSigningKey(cc, &remoteSigningKey);
27337 retval |= cm->setRemoteSymEncryptingKey(cc, &remoteEncryptingKey);
27338 retval |= cm->setRemoteSymIv(cc, &remoteIv);
27339
27340 error:
27341 UA_CHECK_STATUS(retval, UA_LOG_WARNING_CHANNEL(sp->logger, channel,
27342 "Could not generate remote keys (statuscode: %s)",
27343 UA_StatusCode_name(retval)));
27344 UA_ByteString_clear(p: &buf);
27345 return retval;
27346}
27347
27348/***************************/
27349/* Send Asymmetric Message */
27350/***************************/
27351
27352/* The length of the static header content */
27353#define UA_SECURECHANNEL_ASYMMETRIC_SECURITYHEADER_FIXED_LENGTH 12
27354
27355size_t
27356calculateAsymAlgSecurityHeaderLength(const UA_SecureChannel *channel) {
27357 const UA_SecurityPolicy *sp = channel->securityPolicy;
27358 UA_CHECK_MEM(sp, return UA_STATUSCODE_BADINTERNALERROR);
27359
27360 size_t asymHeaderLength = UA_SECURECHANNEL_ASYMMETRIC_SECURITYHEADER_FIXED_LENGTH +
27361 sp->policyUri.length;
27362 if(channel->securityMode == UA_MESSAGESECURITYMODE_NONE)
27363 return asymHeaderLength;
27364
27365 /* OPN is always encrypted even if the mode is sign only */
27366 asymHeaderLength += 20; /* Thumbprints are always 20 byte long */
27367 asymHeaderLength += sp->localCertificate.length;
27368 return asymHeaderLength;
27369}
27370
27371UA_StatusCode
27372prependHeadersAsym(UA_SecureChannel *const channel, UA_Byte *header_pos,
27373 const UA_Byte *buf_end, size_t totalLength,
27374 size_t securityHeaderLength, UA_UInt32 requestId,
27375 size_t *const encryptedLength) {
27376 const UA_SecurityPolicy *sp = channel->securityPolicy;
27377 UA_CHECK_MEM(sp, return UA_STATUSCODE_BADINTERNALERROR);
27378
27379 if(channel->securityMode == UA_MESSAGESECURITYMODE_NONE) {
27380 *encryptedLength = totalLength;
27381 } else {
27382 size_t dataToEncryptLength = totalLength -
27383 (UA_SECURECHANNEL_CHANNELHEADER_LENGTH + securityHeaderLength);
27384 size_t plainTextBlockSize = sp->asymmetricModule.cryptoModule.
27385 encryptionAlgorithm.getRemotePlainTextBlockSize(channel->channelContext);
27386 size_t encryptedBlockSize = sp->asymmetricModule.cryptoModule.
27387 encryptionAlgorithm.getRemoteBlockSize(channel->channelContext);
27388
27389 /* Padding always fills up the last block */
27390 UA_assert(dataToEncryptLength % plainTextBlockSize == 0);
27391 size_t blocks = dataToEncryptLength / plainTextBlockSize;
27392 *encryptedLength = totalLength + blocks * (encryptedBlockSize - plainTextBlockSize);
27393 }
27394
27395 UA_TcpMessageHeader messageHeader;
27396 messageHeader.messageTypeAndChunkType = UA_MESSAGETYPE_OPN + UA_CHUNKTYPE_FINAL;
27397 messageHeader.messageSize = (UA_UInt32)*encryptedLength;
27398 UA_UInt32 secureChannelId = channel->securityToken.channelId;
27399 UA_StatusCode retval = UA_STATUSCODE_GOOD;
27400 retval |= UA_encodeBinaryInternal(src: &messageHeader,
27401 type: &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER],
27402 bufPos: &header_pos, bufEnd: &buf_end, NULL, NULL);
27403 retval |= UA_UInt32_encodeBinary(src: &secureChannelId, bufPos: &header_pos, bufEnd: buf_end);
27404 UA_CHECK_STATUS(retval, return retval);
27405
27406 UA_AsymmetricAlgorithmSecurityHeader asymHeader;
27407 UA_AsymmetricAlgorithmSecurityHeader_init(p: &asymHeader);
27408 asymHeader.securityPolicyUri = sp->policyUri;
27409 if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
27410 channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
27411 asymHeader.senderCertificate = sp->localCertificate;
27412 asymHeader.receiverCertificateThumbprint.length = 20;
27413 asymHeader.receiverCertificateThumbprint.data = channel->remoteCertificateThumbprint;
27414 }
27415 retval = UA_encodeBinaryInternal(src: &asymHeader,
27416 type: &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER],
27417 bufPos: &header_pos, bufEnd: &buf_end, NULL, NULL);
27418 UA_CHECK_STATUS(retval, return retval);
27419
27420 /* Increase the sequence number in the channel */
27421 channel->sendSequenceNumber++;
27422
27423 UA_SequenceHeader seqHeader;
27424 seqHeader.requestId = requestId;
27425 seqHeader.sequenceNumber = channel->sendSequenceNumber;
27426 retval = UA_encodeBinaryInternal(src: &seqHeader, type: &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER],
27427 bufPos: &header_pos, bufEnd: &buf_end, NULL, NULL);
27428 return retval;
27429}
27430
27431void
27432hideBytesAsym(const UA_SecureChannel *channel, UA_Byte **buf_start,
27433 const UA_Byte **buf_end) {
27434 /* Set buf_start to the beginning of the payload body */
27435 *buf_start += UA_SECURECHANNEL_CHANNELHEADER_LENGTH;
27436 *buf_start += calculateAsymAlgSecurityHeaderLength(channel);
27437 *buf_start += UA_SECURECHANNEL_SEQUENCEHEADER_LENGTH;
27438
27439#ifdef UA_ENABLE_ENCRYPTION
27440 if(channel->securityMode == UA_MESSAGESECURITYMODE_NONE)
27441 return;
27442
27443 /* Make space for the certificate */
27444 const UA_SecurityPolicy *sp = channel->securityPolicy;
27445 *buf_end -= sp->asymmetricModule.cryptoModule.signatureAlgorithm.
27446 getLocalSignatureSize(channel->channelContext);
27447
27448 /* Block sizes depend on the remote key (certificate) */
27449 size_t plainTextBlockSize = sp->asymmetricModule.cryptoModule.
27450 encryptionAlgorithm.getRemotePlainTextBlockSize(channel->channelContext);
27451 size_t encryptedBlockSize = sp->asymmetricModule.cryptoModule.
27452 encryptionAlgorithm.getRemoteBlockSize(channel->channelContext);
27453 UA_Boolean extraPadding = (sp->asymmetricModule.cryptoModule.encryptionAlgorithm.
27454 getRemoteKeyLength(channel->channelContext) > 2048);
27455
27456 /* Compute the maximum number of encrypted blocks that can fit entirely
27457 * before the signature. From that compute the maximum usable plaintext
27458 * size. */
27459 size_t maxEncrypted = (size_t)(*buf_end - *buf_start) +
27460 UA_SECURECHANNEL_SEQUENCEHEADER_LENGTH;
27461 size_t max_blocks = maxEncrypted / encryptedBlockSize;
27462 size_t paddingBytes = (UA_LIKELY(!extraPadding)) ? 1u : 2u;
27463 *buf_end = *buf_start + (max_blocks * plainTextBlockSize) -
27464 UA_SECURECHANNEL_SEQUENCEHEADER_LENGTH - paddingBytes;
27465#endif
27466}
27467
27468#ifdef UA_ENABLE_ENCRYPTION
27469
27470/* Assumes that pos can be advanced to the end of the current block */
27471void
27472padChunk(UA_SecureChannel *channel, const UA_SecurityPolicyCryptoModule *cm,
27473 const UA_Byte *start, UA_Byte **pos) {
27474 const size_t bytesToWrite = (uintptr_t)*pos - (uintptr_t)start;
27475 size_t signatureSize = cm->signatureAlgorithm.
27476 getLocalSignatureSize(channel->channelContext);
27477 size_t plainTextBlockSize = cm->encryptionAlgorithm.
27478 getRemotePlainTextBlockSize(channel->channelContext);
27479 UA_Boolean extraPadding = (cm->encryptionAlgorithm.
27480 getRemoteKeyLength(channel->channelContext) > 2048);
27481 size_t paddingBytes = (UA_LIKELY(!extraPadding)) ? 1u : 2u;
27482
27483 size_t lastBlock = ((bytesToWrite + signatureSize + paddingBytes) % plainTextBlockSize);
27484 size_t paddingLength = (lastBlock != 0) ? plainTextBlockSize - lastBlock : 0;
27485
27486 UA_LOG_TRACE_CHANNEL(channel->securityPolicy->logger, channel,
27487 "Add %lu bytes of padding plus %lu padding size bytes",
27488 (long unsigned int)paddingLength,
27489 (long unsigned int)paddingBytes);
27490
27491 /* Write the padding. This is <= because the paddingSize byte also has to be
27492 * written */
27493 UA_Byte paddingByte = (UA_Byte)paddingLength;
27494 for(UA_UInt16 i = 0; i <= paddingLength; ++i) {
27495 **pos = paddingByte;
27496 ++*pos;
27497 }
27498
27499 /* Write the extra padding byte if required */
27500 if(extraPadding) {
27501 **pos = (UA_Byte)(paddingLength >> 8u);
27502 ++*pos;
27503 }
27504}
27505
27506UA_StatusCode
27507signAndEncryptAsym(UA_SecureChannel *channel, size_t preSignLength,
27508 UA_ByteString *buf, size_t securityHeaderLength,
27509 size_t totalLength) {
27510 if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN &&
27511 channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
27512 return UA_STATUSCODE_GOOD;
27513
27514 /* Sign message */
27515 const UA_SecurityPolicy *sp = channel->securityPolicy;
27516 const UA_ByteString dataToSign = {preSignLength, buf->data};
27517 size_t sigsize = sp->asymmetricModule.cryptoModule.signatureAlgorithm.
27518 getLocalSignatureSize(channel->channelContext);
27519 UA_ByteString signature = {sigsize, buf->data + preSignLength};
27520 UA_StatusCode retval = sp->asymmetricModule.cryptoModule.signatureAlgorithm.
27521 sign(channel->channelContext, &dataToSign, &signature);
27522 UA_CHECK_STATUS(retval, return retval);
27523
27524 /* Specification part 6, 6.7.4: The OpenSecureChannel Messages are
27525 * signed and encrypted if the SecurityMode is not None (even if the
27526 * SecurityMode is SignOnly). */
27527 size_t unencrypted_length =
27528 UA_SECURECHANNEL_CHANNELHEADER_LENGTH + securityHeaderLength;
27529 UA_ByteString dataToEncrypt = {totalLength - unencrypted_length,
27530 &buf->data[unencrypted_length]};
27531 return sp->asymmetricModule.cryptoModule.encryptionAlgorithm.
27532 encrypt(channel->channelContext, &dataToEncrypt);
27533}
27534
27535/**************************/
27536/* Send Symmetric Message */
27537/**************************/
27538
27539UA_StatusCode
27540signAndEncryptSym(UA_MessageContext *messageContext,
27541 size_t preSigLength, size_t totalLength) {
27542 const UA_SecureChannel *channel = messageContext->channel;
27543 if(channel->securityMode == UA_MESSAGESECURITYMODE_NONE)
27544 return UA_STATUSCODE_GOOD;
27545
27546 /* Sign */
27547 const UA_SecurityPolicy *sp = channel->securityPolicy;
27548 UA_ByteString dataToSign = messageContext->messageBuffer;
27549 dataToSign.length = preSigLength;
27550 UA_ByteString signature;
27551 signature.length = sp->symmetricModule.cryptoModule.signatureAlgorithm.
27552 getLocalSignatureSize(channel->channelContext);
27553 signature.data = messageContext->buf_pos;
27554 UA_StatusCode res = sp->symmetricModule.cryptoModule.signatureAlgorithm.
27555 sign(channel->channelContext, &dataToSign, &signature);
27556 UA_CHECK_STATUS(res, return res);
27557
27558 if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
27559 return UA_STATUSCODE_GOOD;
27560
27561 /* Encrypt */
27562 UA_ByteString dataToEncrypt;
27563 dataToEncrypt.data = messageContext->messageBuffer.data +
27564 UA_SECURECHANNEL_CHANNELHEADER_LENGTH +
27565 UA_SECURECHANNEL_SYMMETRIC_SECURITYHEADER_LENGTH;
27566 dataToEncrypt.length = totalLength -
27567 (UA_SECURECHANNEL_CHANNELHEADER_LENGTH +
27568 UA_SECURECHANNEL_SYMMETRIC_SECURITYHEADER_LENGTH);
27569 return sp->symmetricModule.cryptoModule.encryptionAlgorithm.
27570 encrypt(channel->channelContext, &dataToEncrypt);
27571}
27572
27573#endif /* UA_ENABLE_ENCRYPTION */
27574
27575void
27576setBufPos(UA_MessageContext *mc) {
27577 /* Forward the data pointer so that the payload is encoded after the message
27578 * header. This has to be a symmetric message because OPN (with asymmetric
27579 * encryption) does not support chunking. */
27580 mc->buf_pos = &mc->messageBuffer.data[UA_SECURECHANNEL_SYMMETRIC_HEADER_TOTALLENGTH];
27581 mc->buf_end = &mc->messageBuffer.data[mc->messageBuffer.length];
27582
27583#ifdef UA_ENABLE_ENCRYPTION
27584 if(mc->channel->securityMode == UA_MESSAGESECURITYMODE_NONE)
27585 return;
27586
27587 const UA_SecureChannel *channel = mc->channel;
27588 const UA_SecurityPolicy *sp = channel->securityPolicy;
27589 size_t sigsize = sp->symmetricModule.cryptoModule.signatureAlgorithm.
27590 getLocalSignatureSize(channel->channelContext);
27591 size_t plainBlockSize = sp->symmetricModule.cryptoModule.
27592 encryptionAlgorithm.getRemotePlainTextBlockSize(channel->channelContext);
27593
27594 /* Assuming that for symmetric encryption the plainTextBlockSize ==
27595 * cypherTextBlockSize. For symmetric encryption the remote/local block
27596 * sizes are identical. */
27597 UA_assert(sp->symmetricModule.cryptoModule.encryptionAlgorithm.
27598 getRemoteBlockSize(channel->channelContext) == plainBlockSize);
27599
27600 /* Leave enough space for the signature and padding */
27601 mc->buf_end -= sigsize;
27602 mc->buf_end -= mc->messageBuffer.length % plainBlockSize;
27603
27604 if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
27605 /* Reserve space for the padding bytes */
27606 UA_Boolean extraPadding =
27607 (sp->symmetricModule.cryptoModule.encryptionAlgorithm.
27608 getRemoteKeyLength(channel->channelContext) > 2048);
27609 mc->buf_end -= (UA_LIKELY(!extraPadding)) ? 1 : 2;
27610 }
27611
27612 UA_LOG_TRACE_CHANNEL(sp->logger, channel,
27613 "Prepare a symmetric message buffer of length %lu "
27614 "with a usable maximum payload length of %lu",
27615 (long unsigned)mc->messageBuffer.length,
27616 (long unsigned)((uintptr_t)mc->buf_end -
27617 (uintptr_t)mc->messageBuffer.data));
27618#endif
27619}
27620
27621/****************************/
27622/* Process a received Chunk */
27623/****************************/
27624
27625static size_t
27626decodePadding(const UA_SecureChannel *channel,
27627 const UA_SecurityPolicyCryptoModule *cryptoModule,
27628 const UA_ByteString *chunk, size_t sigsize) {
27629 /* Read the byte with the padding size */
27630 size_t paddingSize = chunk->data[chunk->length - sigsize - 1];
27631
27632 /* Extra padding size */
27633 if(cryptoModule->encryptionAlgorithm.
27634 getLocalKeyLength(channel->channelContext) > 2048) {
27635 paddingSize <<= 8u;
27636 paddingSize += chunk->data[chunk->length - sigsize - 2];
27637 paddingSize += 1; /* Extra padding byte itself */
27638 }
27639
27640 /* Add one since the paddingSize byte itself needs to be removed as well */
27641 return paddingSize + 1;
27642}
27643
27644static UA_StatusCode
27645verifySignature(const UA_SecureChannel *channel,
27646 const UA_SecurityPolicyCryptoModule *cryptoModule,
27647 const UA_ByteString *chunk, size_t sigsize) {
27648 UA_LOG_TRACE_CHANNEL(channel->securityPolicy->logger, channel,
27649 "Verifying chunk signature");
27650 UA_CHECK(sigsize < chunk->length, return UA_STATUSCODE_BADSECURITYCHECKSFAILED);
27651 const UA_ByteString content = {chunk->length - sigsize, chunk->data};
27652 const UA_ByteString sig = {sigsize, chunk->data + chunk->length - sigsize};
27653 UA_StatusCode retval = cryptoModule->signatureAlgorithm.
27654 verify(channel->channelContext, &content, &sig);
27655 return retval;
27656}
27657
27658/* Sets the payload to a pointer inside the chunk buffer. Returns the requestId
27659 * and the sequenceNumber */
27660UA_StatusCode
27661decryptAndVerifyChunk(const UA_SecureChannel *channel,
27662 const UA_SecurityPolicyCryptoModule *cryptoModule,
27663 UA_MessageType messageType, UA_ByteString *chunk,
27664 size_t offset) {
27665 /* Decrypt the chunk */
27666 UA_StatusCode res = UA_STATUSCODE_GOOD;
27667 if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT ||
27668 messageType == UA_MESSAGETYPE_OPN) {
27669 UA_ByteString cipher = {chunk->length - offset, chunk->data + offset};
27670 res = cryptoModule->encryptionAlgorithm.decrypt(channel->channelContext, &cipher);
27671 UA_CHECK_STATUS(res, return res);
27672 chunk->length = cipher.length + offset;
27673 }
27674
27675 /* Does the message have a signature? */
27676 if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN &&
27677 channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT &&
27678 messageType != UA_MESSAGETYPE_OPN)
27679 return UA_STATUSCODE_GOOD;
27680
27681 /* Verify the chunk signature */
27682 size_t sigsize = cryptoModule->signatureAlgorithm.
27683 getRemoteSignatureSize(channel->channelContext);
27684 res = verifySignature(channel, cryptoModule, chunk, sigsize);
27685 UA_CHECK_STATUS(res,
27686 UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel,
27687 "Could not verify the signature"); return res);
27688
27689 /* Compute the padding if the payload as encrypted */
27690 size_t padSize = 0;
27691 if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT ||
27692 (messageType == UA_MESSAGETYPE_OPN &&
27693 cryptoModule->encryptionAlgorithm.uri.length > 0)) {
27694 padSize = decodePadding(channel, cryptoModule, chunk, sigsize);
27695 UA_LOG_TRACE_CHANNEL(channel->securityPolicy->logger, channel,
27696 "Calculated padding size to be %lu",
27697 (long unsigned)padSize);
27698 }
27699
27700 /* Verify the content length. The encrypted payload has to be at least 9
27701 * bytes long: 8 byte for the SequenceHeader and one byte for the actual
27702 * message */
27703 UA_CHECK(offset + padSize + sigsize + 9 < chunk->length,
27704 UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel,
27705 "Impossible padding value");
27706 return UA_STATUSCODE_BADSECURITYCHECKSFAILED);
27707
27708 /* Hide the signature and padding */
27709 chunk->length -= (sigsize + padSize);
27710 return UA_STATUSCODE_GOOD;
27711}
27712
27713UA_StatusCode
27714checkAsymHeader(UA_SecureChannel *channel,
27715 const UA_AsymmetricAlgorithmSecurityHeader *asymHeader) {
27716 const UA_SecurityPolicy *sp = channel->securityPolicy;
27717 if(!UA_ByteString_equal(p1: &sp->policyUri, p2: &asymHeader->securityPolicyUri))
27718 return UA_STATUSCODE_BADSECURITYPOLICYREJECTED;
27719
27720 return sp->asymmetricModule.
27721 compareCertificateThumbprint(sp, &asymHeader->receiverCertificateThumbprint);
27722
27723 /* The certificate in the header is verified via the configured PKI plugin
27724 * as certificateVerification.verifyCertificate(...). We cannot do it here
27725 * because the client/server context is needed. */
27726}
27727
27728UA_StatusCode
27729checkSymHeader(UA_SecureChannel *channel, const UA_UInt32 tokenId) {
27730 /* If no match, try to revolve to the next token after a
27731 * RenewSecureChannel */
27732 UA_StatusCode retval = UA_STATUSCODE_GOOD;
27733 UA_ChannelSecurityToken *token = &channel->securityToken;
27734 switch(channel->renewState) {
27735 case UA_SECURECHANNELRENEWSTATE_NORMAL:
27736 case UA_SECURECHANNELRENEWSTATE_SENT:
27737 default:
27738 break;
27739
27740 case UA_SECURECHANNELRENEWSTATE_NEWTOKEN_SERVER:
27741 /* Old token still in use */
27742 if(tokenId == channel->securityToken.tokenId)
27743 break;
27744
27745 /* Not the new token */
27746 UA_CHECK(tokenId == channel->altSecurityToken.tokenId,
27747 UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel,
27748 "Unknown SecurityToken");
27749 return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN);
27750
27751 /* Roll over to the new token, generate new local and remote keys */
27752 channel->renewState = UA_SECURECHANNELRENEWSTATE_NORMAL;
27753 channel->securityToken = channel->altSecurityToken;
27754 UA_ChannelSecurityToken_init(p: &channel->altSecurityToken);
27755 retval |= UA_SecureChannel_generateLocalKeys(channel);
27756 retval |= generateRemoteKeys(channel);
27757 UA_CHECK_STATUS(retval, return retval);
27758 break;
27759
27760 case UA_SECURECHANNELRENEWSTATE_NEWTOKEN_CLIENT:
27761 /* The server is still using the old token. That's okay. */
27762 if(tokenId == channel->altSecurityToken.tokenId) {
27763 token = &channel->altSecurityToken;
27764 break;
27765 }
27766
27767 /* Not the new token */
27768 UA_CHECK(tokenId == channel->securityToken.tokenId,
27769 UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel,
27770 "Unknown SecurityToken");
27771 return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN);
27772
27773 /* The remote server uses the new token for the first time. Delete the
27774 * old token and roll the remote key over. The local key already uses
27775 * the nonce pair from the last OPN exchange. */
27776 channel->renewState = UA_SECURECHANNELRENEWSTATE_NORMAL;
27777 UA_ChannelSecurityToken_init(p: &channel->altSecurityToken);
27778 retval = generateRemoteKeys(channel);
27779 UA_CHECK_STATUS(retval, return retval);
27780 }
27781
27782 UA_DateTime timeout = token->createdAt + (token->revisedLifetime * UA_DATETIME_MSEC);
27783 if(channel->state == UA_SECURECHANNELSTATE_OPEN &&
27784 timeout < UA_DateTime_nowMonotonic()) {
27785 UA_LOG_WARNING_CHANNEL(channel->securityPolicy->logger, channel,
27786 "SecurityToken timed out");
27787 UA_SecureChannel_shutdown(channel, shutdownReason: UA_SHUTDOWNREASON_TIMEOUT);
27788 return UA_STATUSCODE_BADSECURECHANNELCLOSED;
27789 }
27790
27791 return UA_STATUSCODE_GOOD;
27792}
27793
27794/**** amalgamated original file "/src/server/ua_session.c" ****/
27795
27796/* This Source Code Form is subject to the terms of the Mozilla Public
27797 * License, v. 2.0. If a copy of the MPL was not distributed with this
27798 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
27799 *
27800 * Copyright 2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
27801 * Copyright 2018 (c) Thomas Stalder, Blue Time Concept SA
27802 * Copyright 2019 (c) HMS Industrial Networks AB (Author: Jonas Green)
27803 */
27804
27805#ifdef UA_ENABLE_SUBSCRIPTIONS
27806#endif
27807
27808#define UA_SESSION_NONCELENTH 32
27809
27810void UA_Session_init(UA_Session *session) {
27811 memset(s: session, c: 0, n: sizeof(UA_Session));
27812 session->availableContinuationPoints = UA_MAXCONTINUATIONPOINTS;
27813#ifdef UA_ENABLE_SUBSCRIPTIONS
27814 SIMPLEQ_INIT(&session->responseQueue);
27815 TAILQ_INIT(&session->subscriptions);
27816#endif
27817}
27818
27819void UA_Session_clear(UA_Session *session, UA_Server* server) {
27820 UA_LOCK_ASSERT(&server->serviceMutex, 1);
27821
27822 /* Remove all Subscriptions. This may send out remaining publish
27823 * responses. */
27824#ifdef UA_ENABLE_SUBSCRIPTIONS
27825 UA_Subscription *sub, *tempsub;
27826 TAILQ_FOREACH_SAFE(sub, &session->subscriptions, sessionListEntry, tempsub) {
27827 UA_Subscription_delete(server, sub);
27828 }
27829#endif
27830
27831#ifdef UA_ENABLE_DIAGNOSTICS
27832 deleteNode(server, nodeId: session->sessionId, true);
27833#endif
27834
27835 UA_Session_detachFromSecureChannel(session);
27836 UA_ApplicationDescription_clear(p: &session->clientDescription);
27837 UA_NodeId_clear(p: &session->header.authenticationToken);
27838 UA_String_clear(p: &session->clientUserIdOfSession);
27839 UA_NodeId_clear(p: &session->sessionId);
27840 UA_String_clear(p: &session->sessionName);
27841 UA_ByteString_clear(p: &session->serverNonce);
27842 struct ContinuationPoint *cp, *next = session->continuationPoints;
27843 while((cp = next)) {
27844 next = ContinuationPoint_clear(cp);
27845 UA_free(ptr: cp);
27846 }
27847 session->continuationPoints = NULL;
27848 session->availableContinuationPoints = UA_MAXCONTINUATIONPOINTS;
27849
27850 UA_KeyValueMap_delete(map: session->attributes);
27851 session->attributes = NULL;
27852
27853 UA_Array_delete(p: session->localeIds, size: session->localeIdsSize,
27854 type: &UA_TYPES[UA_TYPES_STRING]);
27855 session->localeIds = NULL;
27856 session->localeIdsSize = 0;
27857
27858#ifdef UA_ENABLE_DIAGNOSTICS
27859 UA_SessionDiagnosticsDataType_clear(p: &session->diagnostics);
27860 UA_SessionSecurityDiagnosticsDataType_clear(p: &session->securityDiagnostics);
27861#endif
27862}
27863
27864void
27865UA_Session_attachToSecureChannel(UA_Session *session, UA_SecureChannel *channel) {
27866 UA_Session_detachFromSecureChannel(session);
27867 session->header.channel = channel;
27868 session->header.serverSession = true;
27869 SLIST_INSERT_HEAD(&channel->sessions, &session->header, next);
27870}
27871
27872void
27873UA_Session_detachFromSecureChannel(UA_Session *session) {
27874 UA_SecureChannel *channel = session->header.channel;
27875 if(!channel)
27876 return;
27877 session->header.channel = NULL;
27878 UA_SessionHeader *sh;
27879 SLIST_FOREACH(sh, &channel->sessions, next) {
27880 if((UA_Session*)sh != session)
27881 continue;
27882 SLIST_REMOVE(&channel->sessions, sh, UA_SessionHeader, next);
27883 break;
27884 }
27885
27886 /* Clean up the response queue. Their RequestId is bound to the
27887 * SecureChannel so they cannot be reused. */
27888#ifdef UA_ENABLE_SUBSCRIPTIONS
27889 UA_PublishResponseEntry *pre;
27890 while((pre = UA_Session_dequeuePublishReq(session))) {
27891 UA_PublishResponse_clear(p: &pre->response);
27892 UA_free(ptr: pre);
27893 }
27894#endif
27895}
27896
27897UA_StatusCode
27898UA_Session_generateNonce(UA_Session *session) {
27899 UA_SecureChannel *channel = session->header.channel;
27900 if(!channel || !channel->securityPolicy)
27901 return UA_STATUSCODE_BADINTERNALERROR;
27902
27903 /* Is the length of the previous nonce correct? */
27904 if(session->serverNonce.length != UA_SESSION_NONCELENTH) {
27905 UA_ByteString_clear(p: &session->serverNonce);
27906 UA_StatusCode retval =
27907 UA_ByteString_allocBuffer(bs: &session->serverNonce, UA_SESSION_NONCELENTH);
27908 if(retval != UA_STATUSCODE_GOOD)
27909 return retval;
27910 }
27911
27912 return channel->securityPolicy->symmetricModule.
27913 generateNonce(channel->securityPolicy->policyContext, &session->serverNonce);
27914}
27915
27916void UA_Session_updateLifetime(UA_Session *session) {
27917 session->validTill = UA_DateTime_nowMonotonic() +
27918 (UA_DateTime)(session->timeout * UA_DATETIME_MSEC);
27919#ifdef UA_ENABLE_DIAGNOSTICS
27920 session->diagnostics.clientLastContactTime = UA_DateTime_now();
27921#endif
27922}
27923
27924#ifdef UA_ENABLE_SUBSCRIPTIONS
27925
27926void
27927UA_Session_attachSubscription(UA_Session *session, UA_Subscription *sub) {
27928 /* Attach to the session */
27929 sub->session = session;
27930
27931 /* Increase the count */
27932 session->subscriptionsSize++;
27933
27934 /* Increase the number of outstanding retransmissions */
27935 session->totalRetransmissionQueueSize += sub->retransmissionQueueSize;
27936
27937 /* Insert at the end of the subscriptions of the same priority / just before
27938 * the subscriptions with the next lower priority. */
27939 UA_Subscription *after = NULL;
27940 TAILQ_FOREACH(after, &session->subscriptions, sessionListEntry) {
27941 if(after->priority < sub->priority) {
27942 TAILQ_INSERT_BEFORE(after, sub, sessionListEntry);
27943 return;
27944 }
27945 }
27946 TAILQ_INSERT_TAIL(&session->subscriptions, sub, sessionListEntry);
27947}
27948
27949void
27950UA_Session_detachSubscription(UA_Server *server, UA_Session *session,
27951 UA_Subscription *sub, UA_Boolean releasePublishResponses) {
27952 /* Detach from the session */
27953 sub->session = NULL;
27954 TAILQ_REMOVE(&session->subscriptions, sub, sessionListEntry);
27955
27956 /* Reduce the count */
27957 UA_assert(session->subscriptionsSize > 0);
27958 session->subscriptionsSize--;
27959
27960 /* Reduce the number of outstanding retransmissions */
27961 session->totalRetransmissionQueueSize -= sub->retransmissionQueueSize;
27962
27963 /* Send remaining publish responses if the last subscription was removed */
27964 if(!releasePublishResponses || !TAILQ_EMPTY(&session->subscriptions))
27965 return;
27966 UA_PublishResponseEntry *pre;
27967 while((pre = UA_Session_dequeuePublishReq(session))) {
27968 UA_PublishResponse *response = &pre->response;
27969 response->responseHeader.serviceResult = UA_STATUSCODE_BADNOSUBSCRIPTION;
27970 sendResponse(server, session, channel: session->header.channel, requestId: pre->requestId,
27971 response: (UA_Response*)response, responseType: &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]);
27972 UA_PublishResponse_clear(p: response);
27973 UA_free(ptr: pre);
27974 }
27975}
27976
27977UA_Subscription *
27978UA_Session_getSubscriptionById(UA_Session *session, UA_UInt32 subscriptionId) {
27979 UA_Subscription *sub;
27980 TAILQ_FOREACH(sub, &session->subscriptions, sessionListEntry) {
27981 /* Prevent lookup of subscriptions that are to be deleted with a statuschange */
27982 if(sub->statusChange != UA_STATUSCODE_GOOD)
27983 continue;
27984 if(sub->subscriptionId == subscriptionId)
27985 break;
27986 }
27987 return sub;
27988}
27989
27990UA_Subscription *
27991getSubscriptionById(UA_Server *server, UA_UInt32 subscriptionId) {
27992 UA_Subscription *sub;
27993 LIST_FOREACH(sub, &server->subscriptions, serverListEntry) {
27994 /* Prevent lookup of subscriptions that are to be deleted with a statuschange */
27995 if(sub->statusChange != UA_STATUSCODE_GOOD)
27996 continue;
27997 if(sub->subscriptionId == subscriptionId)
27998 break;
27999 }
28000 return sub;
28001}
28002
28003UA_PublishResponseEntry*
28004UA_Session_dequeuePublishReq(UA_Session *session) {
28005 UA_PublishResponseEntry *entry = SIMPLEQ_FIRST(&session->responseQueue);
28006 if(entry) {
28007 SIMPLEQ_REMOVE_HEAD(&session->responseQueue, listEntry);
28008 session->responseQueueSize--;
28009 }
28010 return entry;
28011}
28012
28013void
28014UA_Session_queuePublishReq(UA_Session *session, UA_PublishResponseEntry* entry,
28015 UA_Boolean head) {
28016 if(!head)
28017 SIMPLEQ_INSERT_TAIL(&session->responseQueue, entry, listEntry);
28018 else
28019 SIMPLEQ_INSERT_HEAD(&session->responseQueue, entry, listEntry);
28020 session->responseQueueSize++;
28021}
28022
28023#endif
28024
28025/* Session Handling */
28026
28027UA_StatusCode
28028UA_Server_closeSession(UA_Server *server, const UA_NodeId *sessionId) {
28029 lockServer(server);
28030 session_list_entry *entry;
28031 UA_StatusCode res = UA_STATUSCODE_BADSESSIONIDINVALID;
28032 LIST_FOREACH(entry, &server->sessions, pointers) {
28033 if(UA_NodeId_equal(p1: &entry->session.sessionId, p2: sessionId)) {
28034 UA_Server_removeSession(server, sentry: entry, shutdownReason: UA_SHUTDOWNREASON_CLOSE);
28035 res = UA_STATUSCODE_GOOD;
28036 break;
28037 }
28038 }
28039 unlockServer(server);
28040 return res;
28041}
28042
28043/* Session Attributes */
28044
28045#define UA_PROTECTEDATTRIBUTESSIZE 4
28046static const UA_QualifiedName protectedAttributes[UA_PROTECTEDATTRIBUTESSIZE] = {
28047 {0, UA_STRING_STATIC("localeIds")},
28048 {0, UA_STRING_STATIC("clientDescription")},
28049 {0, UA_STRING_STATIC("sessionName")},
28050 {0, UA_STRING_STATIC("clientUserId")}
28051};
28052
28053static UA_Boolean
28054protectedAttribute(const UA_QualifiedName key) {
28055 for(size_t i = 0; i < UA_PROTECTEDATTRIBUTESSIZE; i++) {
28056 if(UA_QualifiedName_equal(p1: &key, p2: &protectedAttributes[i]))
28057 return true;
28058 }
28059 return false;
28060}
28061
28062UA_StatusCode
28063UA_Server_setSessionAttribute(UA_Server *server, const UA_NodeId *sessionId,
28064 const UA_QualifiedName key, const UA_Variant *value) {
28065 if(protectedAttribute(key))
28066 return UA_STATUSCODE_BADNOTWRITABLE;
28067 lockServer(server);
28068 UA_Session *session = getSessionById(server, sessionId);
28069 UA_StatusCode res = UA_STATUSCODE_BADSESSIONIDINVALID;
28070 if(session)
28071 res = UA_KeyValueMap_set(map: session->attributes,
28072 key, value);
28073 unlockServer(server);
28074 return res;
28075}
28076
28077UA_StatusCode
28078UA_Server_deleteSessionAttribute(UA_Server *server, const UA_NodeId *sessionId,
28079 const UA_QualifiedName key) {
28080 if(protectedAttribute(key))
28081 return UA_STATUSCODE_BADNOTWRITABLE;
28082 lockServer(server);
28083 UA_Session *session = getSessionById(server, sessionId);
28084 if(!session) {
28085 unlockServer(server);
28086 return UA_STATUSCODE_BADSESSIONIDINVALID;
28087 }
28088 UA_StatusCode res =
28089 UA_KeyValueMap_remove(map: session->attributes, key);
28090 unlockServer(server);
28091 return res;
28092}
28093
28094static UA_StatusCode
28095getSessionAttribute(UA_Server *server, const UA_NodeId *sessionId,
28096 const UA_QualifiedName key, UA_Variant *outValue,
28097 UA_Boolean copy) {
28098 if(!outValue)
28099 return UA_STATUSCODE_BADINTERNALERROR;
28100
28101 UA_Session *session = getSessionById(server, sessionId);
28102 if(!session)
28103 return UA_STATUSCODE_BADSESSIONIDINVALID;
28104
28105 const UA_Variant *attr;
28106 UA_Variant localAttr;
28107
28108 if(UA_QualifiedName_equal(p1: &key, p2: &protectedAttributes[0])) {
28109 /* Return LocaleIds */
28110 UA_Variant_setArray(v: &localAttr, array: session->localeIds,
28111 arraySize: session->localeIdsSize, type: &UA_TYPES[UA_TYPES_STRING]);
28112 attr = &localAttr;
28113 } else if(UA_QualifiedName_equal(p1: &key, p2: &protectedAttributes[1])) {
28114 /* Return client description */
28115 UA_Variant_setScalar(v: &localAttr, p: &session->clientDescription,
28116 type: &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]);
28117 attr = &localAttr;
28118 } else if(UA_QualifiedName_equal(p1: &key, p2: &protectedAttributes[2])) {
28119 /* Return session name */
28120 UA_Variant_setScalar(v: &localAttr, p: &session->sessionName,
28121 type: &UA_TYPES[UA_TYPES_STRING]);
28122 attr = &localAttr;
28123 } else if(UA_QualifiedName_equal(p1: &key, p2: &protectedAttributes[3])) {
28124 /* Return client user id */
28125 UA_Variant_setScalar(v: &localAttr, p: &session->clientUserIdOfSession,
28126 type: &UA_TYPES[UA_TYPES_STRING]);
28127 attr = &localAttr;
28128 } else {
28129 /* Get from the actual key-value list */
28130 attr = UA_KeyValueMap_get(map: session->attributes, key);
28131 if(!attr)
28132 return UA_STATUSCODE_BADNOTFOUND;
28133 }
28134
28135 if(copy)
28136 return UA_Variant_copy(src: attr, dst: outValue);
28137
28138 *outValue = *attr;
28139 outValue->storageType = UA_VARIANT_DATA_NODELETE;
28140 return UA_STATUSCODE_GOOD;
28141}
28142
28143UA_StatusCode
28144UA_Server_getSessionAttribute(UA_Server *server, const UA_NodeId *sessionId,
28145 const UA_QualifiedName key, UA_Variant *outValue) {
28146 lockServer(server);
28147 UA_StatusCode res = getSessionAttribute(server, sessionId, key, outValue, false);
28148 unlockServer(server);
28149 return res;
28150}
28151
28152UA_StatusCode
28153UA_Server_getSessionAttributeCopy(UA_Server *server, const UA_NodeId *sessionId,
28154 const UA_QualifiedName key, UA_Variant *outValue) {
28155 lockServer(server);
28156 UA_StatusCode res = getSessionAttribute(server, sessionId, key, outValue, true);
28157 unlockServer(server);
28158 return res;
28159}
28160
28161UA_StatusCode
28162UA_Server_getSessionAttribute_scalar(UA_Server *server,
28163 const UA_NodeId *sessionId,
28164 const UA_QualifiedName key,
28165 const UA_DataType *type,
28166 void *outValue) {
28167 lockServer(server);
28168
28169 UA_Variant attr;
28170 UA_StatusCode res = getSessionAttribute(server, sessionId, key, outValue: &attr, false);
28171 if(res != UA_STATUSCODE_GOOD) {
28172 unlockServer(server);
28173 return res;
28174 }
28175
28176 if(!UA_Variant_hasScalarType(v: &attr, type)) {
28177 unlockServer(server);
28178 return UA_STATUSCODE_BADNOTFOUND;
28179 }
28180
28181 memcpy(dest: outValue, src: attr.data, n: type->memSize);
28182
28183 unlockServer(server);
28184 return UA_STATUSCODE_GOOD;
28185}
28186
28187/**** amalgamated original file "/src/server/ua_nodes.c" ****/
28188
28189/* This Source Code Form is subject to the terms of the Mozilla Public
28190 * License, v. 2.0. If a copy of the MPL was not distributed with this
28191 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
28192 *
28193 * Copyright 2015-2018, 2021 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
28194 * Copyright 2015-2016 (c) Sten Grüner
28195 * Copyright 2015 (c) Chris Iatrou
28196 * Copyright 2015, 2017 (c) Florian Palm
28197 * Copyright 2015 (c) Oleksiy Vasylyev
28198 * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH
28199 * Copyright 2017 (c) Julian Grothoff
28200 */
28201
28202
28203/*********************/
28204/* ReferenceType Set */
28205/*********************/
28206
28207#define UA_REFTYPES_ALL_MASK (~(UA_UInt32)0)
28208#define UA_REFTYPES_ALL_MASK2 UA_REFTYPES_ALL_MASK, UA_REFTYPES_ALL_MASK
28209#define UA_REFTYPES_ALL_MASK4 UA_REFTYPES_ALL_MASK2, UA_REFTYPES_ALL_MASK2
28210#if (UA_REFERENCETYPESET_MAX) / 32 > 8
28211# error Adjust macros to support than 256 reference types
28212#elif (UA_REFERENCETYPESET_MAX) / 32 == 8
28213# define UA_REFTYPES_ALL_ARRAY UA_REFTYPES_ALL_MASK4, UA_REFTYPES_ALL_MASK4
28214#elif (UA_REFERENCETYPESET_MAX) / 32 == 7
28215# define UA_REFTYPES_ALL_ARRAY \
28216 UA_REFTYPES_ALL_MASK4, UA_REFTYPES_ALL_MASK2, UA_REFTYPES_ALL_MASK
28217#elif (UA_REFERENCETYPESET_MAX) / 32 == 6
28218# define UA_REFTYPES_ALL_ARRAY UA_REFTYPES_ALL_MASK4, UA_REFTYPES_ALL_MASK2
28219#elif (UA_REFERENCETYPESET_MAX) / 32 == 5
28220# define UA_REFTYPES_ALL_ARRAY UA_REFTYPES_ALL_MASK4, UA_REFTYPES_ALL_MASK
28221#elif (UA_REFERENCETYPESET_MAX) / 32 == 4
28222# define UA_REFTYPES_ALL_ARRAY UA_REFTYPES_ALL_MASK4
28223#elif (UA_REFERENCETYPESET_MAX) / 32 == 3
28224# define UA_REFTYPES_ALL_ARRAY UA_REFTYPES_ALL_MASK2, UA_REFTYPES_ALL_MASK
28225#elif (UA_REFERENCETYPESET_MAX) / 32 == 2
28226# define UA_REFTYPES_ALL_ARRAY UA_REFTYPES_ALL_MASK2
28227#else
28228# define UA_REFTYPES_ALL_ARRAY UA_REFTYPES_ALL_MASK
28229#endif
28230
28231const UA_ReferenceTypeSet UA_REFERENCETYPESET_NONE = {{0}};
28232const UA_ReferenceTypeSet UA_REFERENCETYPESET_ALL = {{UA_REFTYPES_ALL_ARRAY}};
28233
28234/*****************/
28235/* Node Pointers */
28236/*****************/
28237
28238#define UA_NODEPOINTER_MASK 0x03
28239#define UA_NODEPOINTER_TAG_IMMEDIATE 0x00
28240#define UA_NODEPOINTER_TAG_NODEID 0x01
28241#define UA_NODEPOINTER_TAG_EXPANDEDNODEID 0x02
28242#define UA_NODEPOINTER_TAG_NODE 0x03
28243
28244void
28245UA_NodePointer_clear(UA_NodePointer *np) {
28246 switch(np->immediate & UA_NODEPOINTER_MASK) {
28247 case UA_NODEPOINTER_TAG_NODEID:
28248 np->immediate &= ~(uintptr_t)UA_NODEPOINTER_MASK;
28249 UA_NodeId_delete(p: (UA_NodeId*)(uintptr_t)np->id);
28250 break;
28251 case UA_NODEPOINTER_TAG_EXPANDEDNODEID:
28252 np->immediate &= ~(uintptr_t)UA_NODEPOINTER_MASK;
28253 UA_ExpandedNodeId_delete(p: (UA_ExpandedNodeId*)(uintptr_t)
28254 np->expandedId);
28255 break;
28256 default:
28257 break;
28258 }
28259 UA_NodePointer_init(np);
28260}
28261
28262UA_StatusCode
28263UA_NodePointer_copy(UA_NodePointer in, UA_NodePointer *out) {
28264 UA_StatusCode res = UA_STATUSCODE_GOOD;
28265 UA_Byte tag = in.immediate & UA_NODEPOINTER_MASK;
28266 in.immediate &= ~(uintptr_t)UA_NODEPOINTER_MASK;
28267 switch(tag) {
28268 case UA_NODEPOINTER_TAG_NODE:
28269 in.id = &in.node->nodeId;
28270 goto nodeid; /* fallthrough */
28271 case UA_NODEPOINTER_TAG_NODEID:
28272 nodeid:
28273 out->id = UA_NodeId_new();
28274 if(!out->id)
28275 return UA_STATUSCODE_BADOUTOFMEMORY;
28276 res = UA_NodeId_copy(src: in.id, dst: (UA_NodeId*)(uintptr_t)out->id);
28277 if(res != UA_STATUSCODE_GOOD) {
28278 UA_free(ptr: (void*)out->immediate);
28279 out->immediate = 0;
28280 break;
28281 }
28282 out->immediate |= UA_NODEPOINTER_TAG_NODEID;
28283 break;
28284 case UA_NODEPOINTER_TAG_EXPANDEDNODEID:
28285 out->expandedId = UA_ExpandedNodeId_new();
28286 if(!out->expandedId)
28287 return UA_STATUSCODE_BADOUTOFMEMORY;
28288 res = UA_ExpandedNodeId_copy(src: in.expandedId,
28289 dst: (UA_ExpandedNodeId*)(uintptr_t)
28290 out->expandedId);
28291 if(res != UA_STATUSCODE_GOOD) {
28292 UA_free(ptr: (void*)out->immediate);
28293 out->immediate = 0;
28294 break;
28295 }
28296 out->immediate |= UA_NODEPOINTER_TAG_EXPANDEDNODEID;
28297 break;
28298 default:
28299 case UA_NODEPOINTER_TAG_IMMEDIATE:
28300 *out = in;
28301 break;
28302 }
28303 return res;
28304}
28305
28306UA_Boolean
28307UA_NodePointer_isLocal(UA_NodePointer np) {
28308 UA_Byte tag = np.immediate & UA_NODEPOINTER_MASK;
28309 return (tag != UA_NODEPOINTER_TAG_EXPANDEDNODEID);
28310}
28311
28312UA_Order
28313UA_NodePointer_order(UA_NodePointer p1, UA_NodePointer p2) {
28314 if(p1.immediate == p2.immediate)
28315 return UA_ORDER_EQ;
28316
28317 /* Extract the tag and resolve pointers to nodes */
28318 UA_Byte tag1 = p1.immediate & UA_NODEPOINTER_MASK;
28319 if(tag1 == UA_NODEPOINTER_TAG_NODE) {
28320 p1 = UA_NodePointer_fromNodeId(id: &p1.node->nodeId);
28321 tag1 = p1.immediate & UA_NODEPOINTER_MASK;
28322 }
28323 UA_Byte tag2 = p2.immediate & UA_NODEPOINTER_MASK;
28324 if(tag2 == UA_NODEPOINTER_TAG_NODE) {
28325 p2 = UA_NodePointer_fromNodeId(id: &p2.node->nodeId);
28326 tag2 = p2.immediate & UA_NODEPOINTER_MASK;
28327 }
28328
28329 /* Different tags, cannot be identical */
28330 if(tag1 != tag2)
28331 return (tag1 > tag2) ? UA_ORDER_MORE : UA_ORDER_LESS;
28332
28333 /* Immediate */
28334 if(UA_LIKELY(tag1 == UA_NODEPOINTER_TAG_IMMEDIATE))
28335 return (p1.immediate > p2.immediate) ?
28336 UA_ORDER_MORE : UA_ORDER_LESS;
28337
28338 /* Compare from pointers */
28339 p1.immediate &= ~(uintptr_t)UA_NODEPOINTER_MASK;
28340 p2.immediate &= ~(uintptr_t)UA_NODEPOINTER_MASK;
28341 if(tag1 == UA_NODEPOINTER_TAG_EXPANDEDNODEID)
28342 return UA_ExpandedNodeId_order(n1: p1.expandedId, n2: p2.expandedId);
28343 return UA_NodeId_order(n1: p1.id, n2: p2.id);
28344}
28345
28346UA_NodePointer
28347UA_NodePointer_fromNodeId(const UA_NodeId *id) {
28348 UA_NodePointer np;
28349 if(id->identifierType != UA_NODEIDTYPE_NUMERIC) {
28350 np.id = id;
28351 np.immediate |= UA_NODEPOINTER_TAG_NODEID;
28352 return np;
28353 }
28354
28355#if SIZE_MAX > UA_UINT32_MAX
28356 /* 64bit: 4 Byte for the numeric identifier + 2 Byte for the namespaceIndex
28357 * + 1 Byte for the tagging bit (zero) */
28358 np.immediate = ((uintptr_t)id->identifier.numeric) << 32;
28359 np.immediate |= ((uintptr_t)id->namespaceIndex) << 8;
28360#else
28361 /* 32bit: 3 Byte for the numeric identifier + 6 Bit for the namespaceIndex
28362 * + 2 Bit for the tagging bit (zero) */
28363 if(id->namespaceIndex < (0x01 << 6) &&
28364 id->identifier.numeric < (0x01 << 24)) {
28365 np.immediate = ((uintptr_t)id->identifier.numeric) << 8;
28366 np.immediate |= ((uintptr_t)id->namespaceIndex) << 2;
28367 } else {
28368 np.id = id;
28369 np.immediate |= UA_NODEPOINTER_TAG_NODEID;
28370 }
28371#endif
28372 return np;
28373}
28374
28375UA_NodeId
28376UA_NodePointer_toNodeId(UA_NodePointer np) {
28377 UA_Byte tag = np.immediate & UA_NODEPOINTER_MASK;
28378 np.immediate &= ~(uintptr_t)UA_NODEPOINTER_MASK;
28379 switch(tag) {
28380 case UA_NODEPOINTER_TAG_NODE:
28381 return np.node->nodeId;
28382 case UA_NODEPOINTER_TAG_NODEID:
28383 return *np.id;
28384 case UA_NODEPOINTER_TAG_EXPANDEDNODEID:
28385 return np.expandedId->nodeId;
28386 default:
28387 case UA_NODEPOINTER_TAG_IMMEDIATE:
28388 break;
28389 }
28390
28391 UA_NodeId id;
28392 id.identifierType = UA_NODEIDTYPE_NUMERIC;
28393#if SIZE_MAX > UA_UINT32_MAX /* 64bit */
28394 id.namespaceIndex = (UA_UInt16)(np.immediate >> 8);
28395 id.identifier.numeric = (UA_UInt32)(np.immediate >> 32);
28396#else /* 32bit */
28397 id.namespaceIndex = ((UA_Byte)np.immediate) >> 2;
28398 id.identifier.numeric = np.immediate >> 8;
28399#endif
28400 return id;
28401}
28402
28403UA_NodePointer
28404UA_NodePointer_fromExpandedNodeId(const UA_ExpandedNodeId *id) {
28405 if(!UA_ExpandedNodeId_isLocal(n: id)) {
28406 UA_NodePointer np;
28407 np.expandedId = id;
28408 np.immediate |= UA_NODEPOINTER_TAG_EXPANDEDNODEID;
28409 return np;
28410 }
28411 return UA_NodePointer_fromNodeId(id: &id->nodeId);
28412}
28413
28414UA_ExpandedNodeId
28415UA_NodePointer_toExpandedNodeId(UA_NodePointer np) {
28416 /* Resolve node pointer to get the NodeId */
28417 UA_Byte tag = np.immediate & UA_NODEPOINTER_MASK;
28418 if(tag == UA_NODEPOINTER_TAG_NODE) {
28419 np = UA_NodePointer_fromNodeId(id: &np.node->nodeId);
28420 tag = np.immediate & UA_NODEPOINTER_MASK;
28421 }
28422
28423 /* ExpandedNodeId, make a shallow copy */
28424 if(tag == UA_NODEPOINTER_TAG_EXPANDEDNODEID) {
28425 np.immediate &= ~(uintptr_t)UA_NODEPOINTER_MASK;
28426 return *np.expandedId;
28427 }
28428
28429 /* NodeId, either immediate or via a pointer */
28430 UA_ExpandedNodeId en;
28431 UA_ExpandedNodeId_init(p: &en);
28432 en.nodeId = UA_NodePointer_toNodeId(np);
28433 return en;
28434}
28435
28436/**************/
28437/* References */
28438/**************/
28439
28440static UA_StatusCode
28441addReferenceTarget(UA_NodeReferenceKind *refs, UA_NodePointer target,
28442 UA_UInt32 targetNameHash);
28443
28444static UA_StatusCode
28445addReferenceTargetToTree(UA_NodeReferenceKind *rk, UA_NodePointer targetId,
28446 UA_UInt32 targetIdHash, UA_UInt32 targetNameHash);
28447
28448enum ZIP_CMP
28449cmpRefTargetId(const void *a, const void *b) {
28450 const UA_ReferenceTargetTreeElem *aa = (const UA_ReferenceTargetTreeElem*)a;
28451 const UA_ReferenceTargetTreeElem *bb = (const UA_ReferenceTargetTreeElem*)b;
28452 if(aa->targetIdHash < bb->targetIdHash)
28453 return ZIP_CMP_LESS;
28454 if(aa->targetIdHash > bb->targetIdHash)
28455 return ZIP_CMP_MORE;
28456 return (enum ZIP_CMP)UA_NodePointer_order(p1: aa->target.targetId,
28457 p2: bb->target.targetId);
28458}
28459
28460enum ZIP_CMP
28461cmpRefTargetName(const void *a, const void *b) {
28462 const UA_ReferenceTargetTreeElem *aa = (const UA_ReferenceTargetTreeElem*)a;
28463 const UA_ReferenceTargetTreeElem *bb = (const UA_ReferenceTargetTreeElem*)b;
28464 if(aa->target.targetNameHash == bb->target.targetNameHash)
28465 return ZIP_CMP_EQ;
28466 return (aa->target.targetNameHash < bb->target.targetNameHash) ?
28467 ZIP_CMP_LESS : ZIP_CMP_MORE;
28468}
28469
28470/* Move to the array in-order, also deletes the tree elements */
28471static void
28472moveTreeToArray(UA_ReferenceTarget *array, size_t *pos,
28473 UA_ReferenceTargetTreeElem *elem) {
28474 if(!elem)
28475 return;
28476 moveTreeToArray(array, pos, elem: elem->idTreeEntry.left);
28477 array[*pos] = elem->target;
28478 (*pos)++;
28479 moveTreeToArray(array, pos, elem: elem->idTreeEntry.right);
28480 UA_free(ptr: elem);
28481}
28482
28483static void *
28484removeTreeEntry(void *context, UA_ReferenceTargetTreeElem *elem) {
28485 (void)context;
28486 UA_NodePointer_clear(np: &elem->target.targetId);
28487 UA_free(ptr: elem);
28488 return NULL;
28489}
28490
28491UA_StatusCode
28492UA_NodeReferenceKind_switch(UA_NodeReferenceKind *rk) {
28493 UA_assert(rk->targetsSize > 0);
28494
28495 if(rk->hasRefTree) {
28496 /* From tree to array */
28497 UA_ReferenceTarget *array = (UA_ReferenceTarget*)
28498 UA_malloc(size: sizeof(UA_ReferenceTarget) * rk->targetsSize);
28499 if(!array)
28500 return UA_STATUSCODE_BADOUTOFMEMORY;
28501 size_t pos = 0;
28502 moveTreeToArray(array, pos: &pos, elem: rk->targets.tree.idRoot);
28503 rk->targets.array = array;
28504 rk->hasRefTree = false;
28505 return UA_STATUSCODE_GOOD;
28506 }
28507
28508 /* From array to tree */
28509 UA_NodeReferenceKind newRk = *rk;
28510 newRk.hasRefTree = true;
28511 newRk.targets.tree.idRoot = NULL;
28512 newRk.targets.tree.nameRoot = NULL;
28513 newRk.targetsSize = 0;
28514 for(size_t i = 0; i < rk->targetsSize; i++) {
28515 UA_StatusCode res =
28516 addReferenceTarget(refs: &newRk, target: rk->targets.array[i].targetId,
28517 targetNameHash: rk->targets.array[i].targetNameHash);
28518 if(res != UA_STATUSCODE_GOOD) {
28519 ZIP_ITER(UA_ReferenceIdTree,
28520 (UA_ReferenceIdTree*)&newRk.targets.tree.idRoot,
28521 removeTreeEntry, NULL);
28522 return res;
28523 }
28524 }
28525 for(size_t i = 0; i < rk->targetsSize; i++)
28526 UA_NodePointer_clear(np: &rk->targets.array[i].targetId);
28527 UA_free(ptr: rk->targets.array);
28528 *rk = newRk;
28529 return UA_STATUSCODE_GOOD;
28530}
28531
28532void *
28533UA_NodeReferenceKind_iterate(UA_NodeReferenceKind *rk,
28534 UA_NodeReferenceKind_iterateCallback callback,
28535 void *context) {
28536 if(rk->hasRefTree)
28537 return ZIP_ITER(UA_ReferenceIdTree,
28538 (UA_ReferenceIdTree*)&rk->targets.tree.idRoot,
28539 (UA_ReferenceIdTree_cb)callback, context);
28540 for(size_t i = 0; i < rk->targetsSize; i++) {
28541 void *res = callback(context, &rk->targets.array[i]);
28542 if(res)
28543 return res;
28544 }
28545 return NULL;
28546}
28547
28548const UA_ReferenceTarget *
28549UA_NodeReferenceKind_findTarget(const UA_NodeReferenceKind *rk,
28550 const UA_ExpandedNodeId *targetId) {
28551 UA_NodePointer targetP = UA_NodePointer_fromExpandedNodeId(id: targetId);
28552 if(rk->hasRefTree) {
28553 /* Return from the tree */
28554 UA_ReferenceTargetTreeElem tmpTarget;
28555 tmpTarget.target.targetId = targetP;
28556 tmpTarget.targetIdHash = UA_ExpandedNodeId_hash(n: targetId);
28557 UA_ReferenceTargetTreeElem *result =
28558 ZIP_FIND(UA_ReferenceIdTree, (UA_ReferenceIdTree*)
28559 (uintptr_t)&rk->targets.tree.idRoot, &tmpTarget);
28560 if(result)
28561 return &result->target;
28562 } else {
28563 /* Return from the array */
28564 for(size_t i = 0; i < rk->targetsSize; i++) {
28565 if(UA_NodePointer_equal(p1: targetP, p2: rk->targets.array[i].targetId))
28566 return &rk->targets.array[i];
28567 }
28568 }
28569 return NULL;
28570}
28571
28572/* General node handling methods. There is no UA_Node_new() method here.
28573 * Creating nodes is part of the Nodestore layer */
28574
28575void UA_Node_clear(UA_Node *node) {
28576 /* Delete references */
28577 UA_Node_deleteReferences(node);
28578
28579 /* Delete other head content */
28580 UA_NodeHead *head = &node->head;
28581 UA_NodeId_clear(p: &head->nodeId);
28582 UA_QualifiedName_clear(p: &head->browseName);
28583
28584 UA_LocalizedTextListEntry *lt;
28585
28586 while((lt = head->displayName)) {
28587 head->displayName = lt->next;
28588 UA_LocalizedText_clear(p: &lt->localizedText);
28589 UA_free(ptr: lt);
28590 }
28591
28592 while((lt = head->description)) {
28593 head->description = lt->next;
28594 UA_LocalizedText_clear(p: &lt->localizedText);
28595 UA_free(ptr: lt);
28596 }
28597
28598 /* Delete unique content of the nodeclass */
28599 switch(head->nodeClass) {
28600 case UA_NODECLASS_OBJECT:
28601 break;
28602 case UA_NODECLASS_METHOD:
28603 break;
28604 case UA_NODECLASS_OBJECTTYPE:
28605 break;
28606 case UA_NODECLASS_VARIABLE:
28607 case UA_NODECLASS_VARIABLETYPE: {
28608 UA_VariableNode *p = &node->variableNode;
28609 UA_NodeId_clear(p: &p->dataType);
28610 UA_Array_delete(p: p->arrayDimensions, size: p->arrayDimensionsSize,
28611 type: &UA_TYPES[UA_TYPES_INT32]);
28612 p->arrayDimensions = NULL;
28613 p->arrayDimensionsSize = 0;
28614 if(p->valueSource == UA_VALUESOURCE_DATA)
28615 UA_DataValue_clear(p: &p->value.data.value);
28616 break;
28617 }
28618 case UA_NODECLASS_REFERENCETYPE: {
28619 UA_ReferenceTypeNode *p = &node->referenceTypeNode;
28620 UA_LocalizedText_clear(p: &p->inverseName);
28621 break;
28622 }
28623 case UA_NODECLASS_DATATYPE:
28624 break;
28625 case UA_NODECLASS_VIEW:
28626 break;
28627 default:
28628 break;
28629 }
28630}
28631
28632static UA_StatusCode
28633UA_ObjectNode_copy(const UA_ObjectNode *src, UA_ObjectNode *dst) {
28634 dst->eventNotifier = src->eventNotifier;
28635 return UA_STATUSCODE_GOOD;
28636}
28637
28638static UA_StatusCode
28639UA_CommonVariableNode_copy(const UA_VariableNode *src, UA_VariableNode *dst) {
28640 UA_StatusCode retval =
28641 UA_Array_copy(src: src->arrayDimensions, size: src->arrayDimensionsSize,
28642 dst: (void**)&dst->arrayDimensions, type: &UA_TYPES[UA_TYPES_INT32]);
28643 if(retval != UA_STATUSCODE_GOOD)
28644 return retval;
28645 dst->arrayDimensionsSize = src->arrayDimensionsSize;
28646 retval = UA_NodeId_copy(src: &src->dataType, dst: &dst->dataType);
28647 dst->valueRank = src->valueRank;
28648 dst->valueBackend = src->valueBackend;
28649 dst->valueSource = src->valueSource;
28650 if(src->valueSource == UA_VALUESOURCE_DATA) {
28651 retval |= UA_DataValue_copy(src: &src->value.data.value,
28652 dst: &dst->value.data.value);
28653 dst->value.data.callback = src->value.data.callback;
28654 } else {
28655 dst->value.dataSource = src->value.dataSource;
28656 }
28657 return retval;
28658}
28659
28660static UA_StatusCode
28661UA_VariableNode_copy(const UA_VariableNode *src, UA_VariableNode *dst) {
28662 dst->accessLevel = src->accessLevel;
28663 dst->minimumSamplingInterval = src->minimumSamplingInterval;
28664 dst->historizing = src->historizing;
28665 dst->isDynamic = src->isDynamic;
28666 return UA_CommonVariableNode_copy(src, dst);
28667}
28668
28669static UA_StatusCode
28670UA_VariableTypeNode_copy(const UA_VariableTypeNode *src,
28671 UA_VariableTypeNode *dst) {
28672 dst->isAbstract = src->isAbstract;
28673 return UA_CommonVariableNode_copy(src: (const UA_VariableNode*)src, dst: (UA_VariableNode*)dst);
28674}
28675
28676static UA_StatusCode
28677UA_MethodNode_copy(const UA_MethodNode *src, UA_MethodNode *dst) {
28678 dst->executable = src->executable;
28679 dst->method = src->method;
28680#if UA_MULTITHREADING >= 100
28681 dst->async = src->async;
28682#endif
28683 return UA_STATUSCODE_GOOD;
28684}
28685
28686static UA_StatusCode
28687UA_ObjectTypeNode_copy(const UA_ObjectTypeNode *src, UA_ObjectTypeNode *dst) {
28688 dst->isAbstract = src->isAbstract;
28689 dst->lifecycle = src->lifecycle;
28690 return UA_STATUSCODE_GOOD;
28691}
28692
28693static UA_StatusCode
28694UA_ReferenceTypeNode_copy(const UA_ReferenceTypeNode *src,
28695 UA_ReferenceTypeNode *dst) {
28696 dst->isAbstract = src->isAbstract;
28697 dst->symmetric = src->symmetric;
28698 dst->referenceTypeIndex = src->referenceTypeIndex;
28699 dst->subTypes = src->subTypes;
28700 return UA_LocalizedText_copy(src: &src->inverseName, dst: &dst->inverseName);
28701}
28702
28703static UA_StatusCode
28704UA_DataTypeNode_copy(const UA_DataTypeNode *src, UA_DataTypeNode *dst) {
28705 dst->isAbstract = src->isAbstract;
28706 return UA_STATUSCODE_GOOD;
28707}
28708
28709static UA_StatusCode
28710UA_ViewNode_copy(const UA_ViewNode *src, UA_ViewNode *dst) {
28711 dst->containsNoLoops = src->containsNoLoops;
28712 dst->eventNotifier = src->eventNotifier;
28713 return UA_STATUSCODE_GOOD;
28714}
28715
28716static void *
28717copyTarget(void *context, UA_ReferenceTargetTreeElem *elm) {
28718 UA_NodeReferenceKind *drefs = (UA_NodeReferenceKind*)context;
28719 return (void*)(uintptr_t)
28720 addReferenceTargetToTree(rk: drefs, targetId: elm->target.targetId,
28721 targetIdHash: elm->targetIdHash,
28722 targetNameHash: elm->target.targetNameHash);
28723}
28724
28725UA_StatusCode
28726UA_Node_copy(const UA_Node *src, UA_Node *dst) {
28727 const UA_NodeHead *srchead = &src->head;
28728 UA_NodeHead *dsthead = &dst->head;
28729 if(srchead->nodeClass != dsthead->nodeClass)
28730 return UA_STATUSCODE_BADINTERNALERROR;
28731
28732 /* Copy standard content */
28733 UA_StatusCode retval = UA_NodeId_copy(src: &srchead->nodeId, dst: &dsthead->nodeId);
28734 retval |= UA_QualifiedName_copy(src: &srchead->browseName, dst: &dsthead->browseName);
28735
28736 /* Copy the display name in several languages */
28737 for(UA_LocalizedTextListEntry *lt = srchead->displayName; lt != NULL; lt = lt->next) {
28738 UA_LocalizedTextListEntry *newEntry = (UA_LocalizedTextListEntry *)
28739 UA_calloc(nmemb: 1, size: sizeof(UA_LocalizedTextListEntry));
28740 if(!newEntry) {
28741 retval |= UA_STATUSCODE_BADOUTOFMEMORY;
28742 break;
28743 }
28744 retval |= UA_LocalizedText_copy(src: &lt->localizedText, dst: &newEntry->localizedText);
28745
28746 /* Add to the linked list possibly in reverse order */
28747 newEntry->next = dsthead->displayName;
28748 dsthead->displayName = newEntry;
28749 }
28750
28751 /* Copy the description in several languages */
28752 for(UA_LocalizedTextListEntry *lt = srchead->description; lt != NULL; lt = lt->next) {
28753 UA_LocalizedTextListEntry *newEntry = (UA_LocalizedTextListEntry *)
28754 UA_calloc(nmemb: 1, size: sizeof(UA_LocalizedTextListEntry));
28755 if(!newEntry) {
28756 retval |= UA_STATUSCODE_BADOUTOFMEMORY;
28757 break;
28758 }
28759 retval |= UA_LocalizedText_copy(src: &lt->localizedText, dst: &newEntry->localizedText);
28760
28761 /* Add to the linked list possibly in reverse order */
28762 newEntry->next = dsthead->description;
28763 dsthead->description= newEntry;
28764 }
28765
28766 dsthead->writeMask = srchead->writeMask;
28767 dsthead->context = srchead->context;
28768 dsthead->constructed = srchead->constructed;
28769#ifdef UA_ENABLE_SUBSCRIPTIONS
28770 dsthead->monitoredItems = srchead->monitoredItems;
28771#endif
28772 if(retval != UA_STATUSCODE_GOOD) {
28773 UA_Node_clear(node: dst);
28774 return retval;
28775 }
28776
28777 /* Copy the references */
28778 dsthead->references = NULL;
28779 if(srchead->referencesSize > 0) {
28780 dsthead->references = (UA_NodeReferenceKind*)
28781 UA_calloc(nmemb: srchead->referencesSize, size: sizeof(UA_NodeReferenceKind));
28782 if(!dsthead->references) {
28783 UA_Node_clear(node: dst);
28784 return UA_STATUSCODE_BADOUTOFMEMORY;
28785 }
28786 dsthead->referencesSize = srchead->referencesSize;
28787
28788 for(size_t i = 0; i < srchead->referencesSize; ++i) {
28789 UA_NodeReferenceKind *srefs = &srchead->references[i];
28790 UA_NodeReferenceKind *drefs = &dsthead->references[i];
28791 drefs->referenceTypeIndex = srefs->referenceTypeIndex;
28792 drefs->isInverse = srefs->isInverse;
28793 drefs->hasRefTree = srefs->hasRefTree; /* initially empty */
28794
28795 /* Copy all the targets */
28796 if(!srefs->hasRefTree) {
28797 drefs->targets.array = (UA_ReferenceTarget*)
28798 UA_malloc(size: sizeof(UA_ReferenceTarget) * srefs->targetsSize);
28799 if(!drefs->targets.array) {
28800 UA_Node_clear(node: dst);
28801 return UA_STATUSCODE_BADOUTOFMEMORY;
28802 }
28803 for(size_t j = 0; j < srefs->targetsSize; j++) {
28804 drefs->targets.array[j].targetNameHash =
28805 srefs->targets.array[j].targetNameHash;
28806 retval = UA_NodePointer_copy(in: srefs->targets.array[j].targetId,
28807 out: &drefs->targets.array[j].targetId);
28808 drefs->targetsSize++; /* avoid that targetsSize == 0 in error case */
28809 if(retval != UA_STATUSCODE_GOOD) {
28810 UA_Node_clear(node: dst);
28811 return retval;
28812 }
28813 }
28814 } else {
28815 void *res = ZIP_ITER(UA_ReferenceIdTree,
28816 (UA_ReferenceIdTree*)&srefs->targets.tree.idRoot,
28817 copyTarget, drefs);
28818 if(res != NULL) {
28819 UA_Node_clear(node: dst);
28820 return (UA_StatusCode)(uintptr_t)res;
28821 }
28822 }
28823
28824 UA_assert(srefs->targetsSize > 0);
28825 UA_assert(srefs->targetsSize == drefs->targetsSize);
28826 }
28827 }
28828
28829 /* Copy unique content of the nodeclass */
28830 switch(src->head.nodeClass) {
28831 case UA_NODECLASS_OBJECT:
28832 retval = UA_ObjectNode_copy(src: &src->objectNode, dst: &dst->objectNode);
28833 break;
28834 case UA_NODECLASS_VARIABLE:
28835 retval = UA_VariableNode_copy(src: &src->variableNode, dst: &dst->variableNode);
28836 break;
28837 case UA_NODECLASS_METHOD:
28838 retval = UA_MethodNode_copy(src: &src->methodNode, dst: &dst->methodNode);
28839 break;
28840 case UA_NODECLASS_OBJECTTYPE:
28841 retval = UA_ObjectTypeNode_copy(src: &src->objectTypeNode, dst: &dst->objectTypeNode);
28842 break;
28843 case UA_NODECLASS_VARIABLETYPE:
28844 retval = UA_VariableTypeNode_copy(src: &src->variableTypeNode, dst: &dst->variableTypeNode);
28845 break;
28846 case UA_NODECLASS_REFERENCETYPE:
28847 retval = UA_ReferenceTypeNode_copy(src: &src->referenceTypeNode, dst: &dst->referenceTypeNode);
28848 break;
28849 case UA_NODECLASS_DATATYPE:
28850 retval = UA_DataTypeNode_copy(src: &src->dataTypeNode, dst: &dst->dataTypeNode);
28851 break;
28852 case UA_NODECLASS_VIEW:
28853 retval = UA_ViewNode_copy(src: &src->viewNode, dst: &dst->viewNode);
28854 break;
28855 default:
28856 break;
28857 }
28858
28859 if(retval != UA_STATUSCODE_GOOD)
28860 UA_Node_clear(node: dst);
28861
28862 return retval;
28863}
28864
28865UA_Node *
28866UA_Node_copy_alloc(const UA_Node *src) {
28867 size_t nodesize = 0;
28868 switch(src->head.nodeClass) {
28869 case UA_NODECLASS_OBJECT:
28870 nodesize = sizeof(UA_ObjectNode);
28871 break;
28872 case UA_NODECLASS_VARIABLE:
28873 nodesize = sizeof(UA_VariableNode);
28874 break;
28875 case UA_NODECLASS_METHOD:
28876 nodesize = sizeof(UA_MethodNode);
28877 break;
28878 case UA_NODECLASS_OBJECTTYPE:
28879 nodesize = sizeof(UA_ObjectTypeNode);
28880 break;
28881 case UA_NODECLASS_VARIABLETYPE:
28882 nodesize = sizeof(UA_VariableTypeNode);
28883 break;
28884 case UA_NODECLASS_REFERENCETYPE:
28885 nodesize = sizeof(UA_ReferenceTypeNode);
28886 break;
28887 case UA_NODECLASS_DATATYPE:
28888 nodesize = sizeof(UA_DataTypeNode);
28889 break;
28890 case UA_NODECLASS_VIEW:
28891 nodesize = sizeof(UA_ViewNode);
28892 break;
28893 default:
28894 return NULL;
28895 }
28896
28897 UA_Node *dst = (UA_Node*)UA_calloc(nmemb: 1, size: nodesize);
28898 if(!dst)
28899 return NULL;
28900
28901 dst->head.nodeClass = src->head.nodeClass;
28902
28903 UA_StatusCode retval = UA_Node_copy(src, dst);
28904 if(retval != UA_STATUSCODE_GOOD) {
28905 UA_free(ptr: dst);
28906 return NULL;
28907 }
28908 return dst;
28909}
28910/******************************/
28911/* Copy Attributes into Nodes */
28912/******************************/
28913
28914static UA_StatusCode
28915copyStandardAttributes(UA_NodeHead *head, const UA_NodeAttributes *attr) {
28916 /* UA_NodeId_copy(&item->requestedNewNodeId.nodeId, &node->nodeId); */
28917 /* UA_QualifiedName_copy(&item->browseName, &node->browseName); */
28918
28919 head->writeMask = attr->writeMask;
28920 UA_StatusCode retval = UA_Node_insertOrUpdateDescription(head, value: &attr->description);
28921 /* The new nodeset format has optional display names:
28922 * https://github.com/open62541/open62541/issues/2627. If the display name
28923 * is NULL, take the name part of the browse name */
28924 if(attr->displayName.text.length == 0) {
28925 UA_LocalizedText lt;
28926 UA_LocalizedText_init(p: &lt);
28927 lt.text = head->browseName.name;
28928 retval |= UA_Node_insertOrUpdateDisplayName(head, value: &lt);
28929 } else
28930 retval |= UA_Node_insertOrUpdateDisplayName(head, value: &attr->displayName);
28931 return retval;
28932}
28933
28934static UA_StatusCode
28935copyCommonVariableAttributes(UA_VariableNode *node,
28936 const UA_VariableAttributes *attr) {
28937 /* Copy the array dimensions */
28938 UA_StatusCode retval =
28939 UA_Array_copy(src: attr->arrayDimensions, size: attr->arrayDimensionsSize,
28940 dst: (void**)&node->arrayDimensions, type: &UA_TYPES[UA_TYPES_UINT32]);
28941 if(retval != UA_STATUSCODE_GOOD)
28942 return retval;
28943 node->arrayDimensionsSize = attr->arrayDimensionsSize;
28944
28945 /* Data type and value rank */
28946 retval = UA_NodeId_copy(src: &attr->dataType, dst: &node->dataType);
28947 if(retval != UA_STATUSCODE_GOOD)
28948 return retval;
28949 node->valueRank = attr->valueRank;
28950
28951 /* Copy the value */
28952 retval = UA_Variant_copy(src: &attr->value, dst: &node->value.data.value.value);
28953 node->valueSource = UA_VALUESOURCE_DATA;
28954 node->value.data.value.hasValue = (node->value.data.value.value.type != NULL);
28955
28956 return retval;
28957}
28958
28959static UA_StatusCode
28960copyVariableNodeAttributes(UA_VariableNode *vnode,
28961 const UA_VariableAttributes *attr) {
28962 vnode->accessLevel = attr->accessLevel;
28963 vnode->historizing = attr->historizing;
28964 vnode->minimumSamplingInterval = attr->minimumSamplingInterval;
28965 return copyCommonVariableAttributes(node: vnode, attr);
28966}
28967
28968static UA_StatusCode
28969copyVariableTypeNodeAttributes(UA_VariableTypeNode *vtnode,
28970 const UA_VariableTypeAttributes *attr) {
28971 vtnode->isAbstract = attr->isAbstract;
28972 return copyCommonVariableAttributes(node: (UA_VariableNode*)vtnode,
28973 attr: (const UA_VariableAttributes*)attr);
28974}
28975
28976static UA_StatusCode
28977copyObjectNodeAttributes(UA_ObjectNode *onode, const UA_ObjectAttributes *attr) {
28978 onode->eventNotifier = attr->eventNotifier;
28979 return UA_STATUSCODE_GOOD;
28980}
28981
28982static UA_StatusCode
28983copyReferenceTypeNodeAttributes(UA_ReferenceTypeNode *rtnode,
28984 const UA_ReferenceTypeAttributes *attr) {
28985 rtnode->isAbstract = attr->isAbstract;
28986 rtnode->symmetric = attr->symmetric;
28987 return UA_LocalizedText_copy(src: &attr->inverseName, dst: &rtnode->inverseName);
28988}
28989
28990static UA_StatusCode
28991copyObjectTypeNodeAttributes(UA_ObjectTypeNode *otnode,
28992 const UA_ObjectTypeAttributes *attr) {
28993 otnode->isAbstract = attr->isAbstract;
28994 return UA_STATUSCODE_GOOD;
28995}
28996
28997static UA_StatusCode
28998copyViewNodeAttributes(UA_ViewNode *vnode, const UA_ViewAttributes *attr) {
28999 vnode->containsNoLoops = attr->containsNoLoops;
29000 vnode->eventNotifier = attr->eventNotifier;
29001 return UA_STATUSCODE_GOOD;
29002}
29003
29004static UA_StatusCode
29005copyDataTypeNodeAttributes(UA_DataTypeNode *dtnode,
29006 const UA_DataTypeAttributes *attr) {
29007 dtnode->isAbstract = attr->isAbstract;
29008 return UA_STATUSCODE_GOOD;
29009}
29010
29011static UA_StatusCode
29012copyMethodNodeAttributes(UA_MethodNode *mnode,
29013 const UA_MethodAttributes *attr) {
29014 mnode->executable = attr->executable;
29015 return UA_STATUSCODE_GOOD;
29016}
29017
29018#define CHECK_ATTRIBUTES(TYPE) \
29019 if(attributeType != &UA_TYPES[UA_TYPES_##TYPE]) { \
29020 retval = UA_STATUSCODE_BADNODEATTRIBUTESINVALID; \
29021 break; \
29022 }
29023
29024UA_StatusCode
29025UA_Node_setAttributes(UA_Node *node, const void *attributes, const UA_DataType *attributeType) {
29026 /* Copy the attributes into the node */
29027 UA_StatusCode retval = UA_STATUSCODE_GOOD;
29028 switch(node->head.nodeClass) {
29029 case UA_NODECLASS_OBJECT:
29030 CHECK_ATTRIBUTES(OBJECTATTRIBUTES);
29031 retval = copyObjectNodeAttributes(onode: &node->objectNode,
29032 attr: (const UA_ObjectAttributes*)attributes);
29033 break;
29034 case UA_NODECLASS_VARIABLE:
29035 CHECK_ATTRIBUTES(VARIABLEATTRIBUTES);
29036 retval = copyVariableNodeAttributes(vnode: &node->variableNode,
29037 attr: (const UA_VariableAttributes*)attributes);
29038 break;
29039 case UA_NODECLASS_OBJECTTYPE:
29040 CHECK_ATTRIBUTES(OBJECTTYPEATTRIBUTES);
29041 retval = copyObjectTypeNodeAttributes(otnode: &node->objectTypeNode,
29042 attr: (const UA_ObjectTypeAttributes*)attributes);
29043 break;
29044 case UA_NODECLASS_VARIABLETYPE:
29045 CHECK_ATTRIBUTES(VARIABLETYPEATTRIBUTES);
29046 retval = copyVariableTypeNodeAttributes(vtnode: &node->variableTypeNode,
29047 attr: (const UA_VariableTypeAttributes*)attributes);
29048 break;
29049 case UA_NODECLASS_REFERENCETYPE:
29050 CHECK_ATTRIBUTES(REFERENCETYPEATTRIBUTES);
29051 retval = copyReferenceTypeNodeAttributes(rtnode: &node->referenceTypeNode,
29052 attr: (const UA_ReferenceTypeAttributes*)attributes);
29053 break;
29054 case UA_NODECLASS_DATATYPE:
29055 CHECK_ATTRIBUTES(DATATYPEATTRIBUTES);
29056 retval = copyDataTypeNodeAttributes(dtnode: &node->dataTypeNode,
29057 attr: (const UA_DataTypeAttributes*)attributes);
29058 break;
29059 case UA_NODECLASS_VIEW:
29060 CHECK_ATTRIBUTES(VIEWATTRIBUTES);
29061 retval = copyViewNodeAttributes(vnode: &node->viewNode, attr: (const UA_ViewAttributes*)attributes);
29062 break;
29063 case UA_NODECLASS_METHOD:
29064 CHECK_ATTRIBUTES(METHODATTRIBUTES);
29065 retval = copyMethodNodeAttributes(mnode: &node->methodNode, attr: (const UA_MethodAttributes*)attributes);
29066 break;
29067 case UA_NODECLASS_UNSPECIFIED:
29068 default:
29069 retval = UA_STATUSCODE_BADNODECLASSINVALID;
29070 }
29071
29072 if(retval == UA_STATUSCODE_GOOD)
29073 retval = copyStandardAttributes(head: &node->head, attr: (const UA_NodeAttributes*)attributes);
29074 if(retval != UA_STATUSCODE_GOOD)
29075 UA_Node_clear(node);
29076 return retval;
29077}
29078
29079/*********************/
29080/* Manage References */
29081/*********************/
29082
29083static UA_StatusCode
29084addReferenceTargetToTree(UA_NodeReferenceKind *rk, UA_NodePointer targetId,
29085 UA_UInt32 targetIdHash, UA_UInt32 targetNameHash) {
29086 UA_ReferenceTargetTreeElem *entry = (UA_ReferenceTargetTreeElem*)
29087 UA_malloc(size: sizeof(UA_ReferenceTargetTreeElem));
29088 if(!entry)
29089 return UA_STATUSCODE_BADOUTOFMEMORY;
29090
29091 UA_StatusCode res = UA_NodePointer_copy(in: targetId, out: &entry->target.targetId);
29092 if(res != UA_STATUSCODE_GOOD) {
29093 UA_free(ptr: entry);
29094 return res;
29095 }
29096
29097 entry->targetIdHash = targetIdHash;
29098 entry->target.targetNameHash = targetNameHash;
29099
29100 ZIP_INSERT(UA_ReferenceIdTree,
29101 (UA_ReferenceIdTree*)&rk->targets.tree.idRoot, entry);
29102 ZIP_INSERT(UA_ReferenceNameTree,
29103 (UA_ReferenceNameTree*)&rk->targets.tree.nameRoot, entry);
29104
29105 rk->targetsSize++;
29106 return UA_STATUSCODE_GOOD;
29107}
29108
29109static UA_StatusCode
29110addReferenceTarget(UA_NodeReferenceKind *rk, UA_NodePointer targetId,
29111 UA_UInt32 targetNameHash) {
29112 /* Insert into tree */
29113 if(rk->hasRefTree) {
29114 UA_ExpandedNodeId en = UA_NodePointer_toExpandedNodeId(np: targetId);
29115 return addReferenceTargetToTree(rk, targetId, targetIdHash: UA_ExpandedNodeId_hash(n: &en),
29116 targetNameHash);
29117 }
29118
29119 /* Insert to the array */
29120 UA_ReferenceTarget *newRefs = (UA_ReferenceTarget*)
29121 UA_realloc(ptr: rk->targets.array,
29122 size: sizeof(UA_ReferenceTarget) * (rk->targetsSize + 1));
29123 if(!newRefs)
29124 return UA_STATUSCODE_BADOUTOFMEMORY;
29125 rk->targets.array = newRefs;
29126
29127 UA_StatusCode retval =
29128 UA_NodePointer_copy(in: targetId,
29129 out: &rk->targets.array[rk->targetsSize].targetId);
29130 rk->targets.array[rk->targetsSize].targetNameHash = targetNameHash;
29131 if(retval != UA_STATUSCODE_GOOD) {
29132 if(rk->targetsSize == 0) {
29133 UA_free(ptr: rk->targets.array);
29134 rk->targets.array = NULL;
29135 }
29136 return retval;
29137 }
29138
29139 rk->targetsSize++;
29140 return UA_STATUSCODE_GOOD;
29141}
29142
29143static UA_StatusCode
29144addReferenceKind(UA_NodeHead *head, UA_Byte refTypeIndex, UA_Boolean isForward,
29145 const UA_NodePointer target, UA_UInt32 targetBrowseNameHash) {
29146 UA_NodeReferenceKind *refs = (UA_NodeReferenceKind*)
29147 UA_realloc(ptr: head->references,
29148 size: sizeof(UA_NodeReferenceKind) * (head->referencesSize+1));
29149 if(!refs)
29150 return UA_STATUSCODE_BADOUTOFMEMORY;
29151 head->references = refs;
29152
29153 UA_NodeReferenceKind *newRef = &refs[head->referencesSize];
29154 memset(s: newRef, c: 0, n: sizeof(UA_NodeReferenceKind));
29155 newRef->referenceTypeIndex = refTypeIndex;
29156 newRef->isInverse = !isForward;
29157 UA_StatusCode res = addReferenceTarget(rk: newRef, targetId: target, targetNameHash: targetBrowseNameHash);
29158 if(res != UA_STATUSCODE_GOOD) {
29159 if(head->referencesSize == 0) {
29160 UA_free(ptr: head->references);
29161 head->references = NULL;
29162 }
29163 return res;
29164 }
29165
29166 head->referencesSize++;
29167 return UA_STATUSCODE_GOOD;
29168}
29169
29170UA_StatusCode
29171UA_Node_addReference(UA_Node *node, UA_Byte refTypeIndex, UA_Boolean isForward,
29172 const UA_ExpandedNodeId *targetNodeId,
29173 UA_UInt32 targetBrowseNameHash) {
29174 /* Find the matching reference kind */
29175 for(size_t i = 0; i < node->head.referencesSize; ++i) {
29176 UA_NodeReferenceKind *refs = &node->head.references[i];
29177
29178 /* Reference direction does not match */
29179 if(refs->isInverse == isForward)
29180 continue;
29181
29182 /* Reference type does not match */
29183 if(refs->referenceTypeIndex != refTypeIndex)
29184 continue;
29185
29186 /* Does an identical reference already exist? */
29187 const UA_ReferenceTarget *found =
29188 UA_NodeReferenceKind_findTarget(rk: refs, targetId: targetNodeId);
29189 if(found)
29190 return UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED;
29191
29192 /* Add to existing ReferenceKind */
29193 return addReferenceTarget(rk: refs, targetId: UA_NodePointer_fromExpandedNodeId(id: targetNodeId),
29194 targetNameHash: targetBrowseNameHash);
29195 }
29196
29197 /* Add new ReferenceKind for the target */
29198 return addReferenceKind(head: &node->head, refTypeIndex, isForward,
29199 target: UA_NodePointer_fromExpandedNodeId(id: targetNodeId),
29200 targetBrowseNameHash);
29201
29202}
29203
29204UA_StatusCode
29205UA_Node_deleteReference(UA_Node *node, UA_Byte refTypeIndex, UA_Boolean isForward,
29206 const UA_ExpandedNodeId *targetNodeId) {
29207 UA_NodeHead *head = &node->head;
29208 for(size_t i = 0; i < head->referencesSize; i++) {
29209 UA_NodeReferenceKind *refs = &head->references[i];
29210 if(isForward == refs->isInverse)
29211 continue;
29212 if(refTypeIndex != refs->referenceTypeIndex)
29213 continue;
29214
29215 /* Cast out the const qualifier (hack!) */
29216 UA_ReferenceTarget *target = (UA_ReferenceTarget*)(uintptr_t)
29217 UA_NodeReferenceKind_findTarget(rk: refs, targetId: targetNodeId);
29218 if(!target)
29219 continue;
29220
29221 /* Ok, delete the reference. Cannot fail */
29222 refs->targetsSize--;
29223
29224 if(!refs->hasRefTree) {
29225 /* Remove from array */
29226 UA_NodePointer_clear(np: &target->targetId);
29227
29228 /* Elements remaining. Realloc. */
29229 if(refs->targetsSize > 0) {
29230 if(target != &refs->targets.array[refs->targetsSize])
29231 *target = refs->targets.array[refs->targetsSize];
29232 UA_ReferenceTarget *newRefs = (UA_ReferenceTarget*)
29233 UA_realloc(ptr: refs->targets.array,
29234 size: sizeof(UA_ReferenceTarget) * refs->targetsSize);
29235 if(newRefs)
29236 refs->targets.array = newRefs;
29237 return UA_STATUSCODE_GOOD; /* Realloc allowed to fail */
29238 }
29239
29240 /* Remove the last target. Remove the ReferenceKind below */
29241 UA_free(ptr: refs->targets.array);
29242 } else {
29243 UA_ReferenceTargetTreeElem *elem = (UA_ReferenceTargetTreeElem*)target;
29244 ZIP_REMOVE(UA_ReferenceIdTree,
29245 (UA_ReferenceIdTree*)&refs->targets.tree.idRoot, elem);
29246 ZIP_REMOVE(UA_ReferenceNameTree,
29247 (UA_ReferenceNameTree*)&refs->targets.tree.nameRoot, elem);
29248 UA_NodePointer_clear(np: &target->targetId);
29249 UA_free(ptr: target);
29250 if(refs->targetsSize > 0)
29251 return UA_STATUSCODE_GOOD;
29252 }
29253
29254 /* No targets remaining. Remove the ReferenceKind. */
29255 head->referencesSize--;
29256 if(head->referencesSize > 0) {
29257 /* No target for the ReferenceType remaining. Remove and shrink down
29258 * allocated buffer. Ignore errors in case memory buffer could not
29259 * be shrinked down. */
29260 if(i != head->referencesSize)
29261 head->references[i] = head->references[node->head.referencesSize];
29262 UA_NodeReferenceKind *newRefs = (UA_NodeReferenceKind*)
29263 UA_realloc(ptr: head->references,
29264 size: sizeof(UA_NodeReferenceKind) * head->referencesSize);
29265 if(newRefs)
29266 head->references = newRefs;
29267 } else {
29268 /* No remaining references of any ReferenceType */
29269 UA_free(ptr: head->references);
29270 head->references = NULL;
29271 }
29272 return UA_STATUSCODE_GOOD;
29273 }
29274 return UA_STATUSCODE_UNCERTAINREFERENCENOTDELETED;
29275}
29276
29277void
29278UA_Node_deleteReferencesSubset(UA_Node *node, const UA_ReferenceTypeSet *keepSet) {
29279 UA_NodeHead *head = &node->head;
29280 for(size_t i = 0; i < head->referencesSize; i++) {
29281 /* Keep the references of this type? */
29282 UA_NodeReferenceKind *refs = &head->references[i];
29283 if(UA_ReferenceTypeSet_contains(set: keepSet, index: refs->referenceTypeIndex))
29284 continue;
29285
29286 /* Remove all target entries. Don't remove entries from browseName tree.
29287 * The entire ReferenceKind will be removed anyway. */
29288 if(!refs->hasRefTree) {
29289 for(size_t j = 0; j < refs->targetsSize; j++)
29290 UA_NodePointer_clear(np: &refs->targets.array[j].targetId);
29291 UA_free(ptr: refs->targets.array);
29292 } else {
29293 ZIP_ITER(UA_ReferenceIdTree,
29294 (UA_ReferenceIdTree*)&refs->targets.tree.idRoot,
29295 removeTreeEntry, NULL);
29296 }
29297
29298 /* Move last references-kind entry to this position. Don't memcpy over
29299 * the same position. Decrease i to repeat at this location. */
29300 head->referencesSize--;
29301 if(i != head->referencesSize) {
29302 head->references[i] = head->references[head->referencesSize];
29303 i--;
29304 }
29305 }
29306
29307 if(head->referencesSize > 0) {
29308 /* Realloc to save memory. Ignore if realloc fails. */
29309 UA_NodeReferenceKind *refs = (UA_NodeReferenceKind*)
29310 UA_realloc(ptr: head->references,
29311 size: sizeof(UA_NodeReferenceKind) * head->referencesSize);
29312 if(refs)
29313 head->references = refs;
29314 } else {
29315 /* The array is empty. Remove. */
29316 UA_free(ptr: head->references);
29317 head->references = NULL;
29318 }
29319}
29320
29321void UA_Node_deleteReferences(UA_Node *node) {
29322 UA_ReferenceTypeSet noRefs;
29323 UA_ReferenceTypeSet_init(set: &noRefs);
29324 UA_Node_deleteReferencesSubset(node, keepSet: &noRefs);
29325}
29326
29327static UA_StatusCode
29328UA_Node_insertOrUpdateLocale(UA_LocalizedTextListEntry **root,
29329 const UA_LocalizedText *value) {
29330 UA_StatusCode res;
29331 UA_LocalizedTextListEntry *lt, *prev = NULL;
29332 for(lt = *root; lt != NULL; prev = lt, lt = lt->next) {
29333 if(!UA_String_equal(p1: &value->locale, p2: &lt->localizedText.locale))
29334 continue;
29335
29336 /* No text -> remove the entry for this locale */
29337 if(value->text.length == 0) {
29338 if(prev == NULL)
29339 *root = lt->next;
29340 else
29341 prev->next = lt->next;
29342 UA_LocalizedText_clear(p: &lt->localizedText);
29343 UA_free(ptr: lt);
29344 return UA_STATUSCODE_GOOD;
29345 }
29346
29347 /* First make a copy of the text, if this succeeds replace the old
29348 * version */
29349 UA_String tmp;
29350 res = UA_String_copy(src: &value->text, dst: &tmp);
29351 if(res != UA_STATUSCODE_GOOD)
29352 return res;
29353
29354 UA_String_clear(p: &lt->localizedText.text);
29355 lt->localizedText.text = tmp;
29356 return UA_STATUSCODE_GOOD;
29357 }
29358
29359 /* The locale does not exist so far */
29360
29361 /* Do nothing if a non-existing locale should be removed */
29362 if(value->text.length == 0)
29363 return UA_STATUSCODE_GOOD;
29364
29365 /* Add a new localized text */
29366 lt = (UA_LocalizedTextListEntry *)UA_malloc(size: sizeof(UA_LocalizedTextListEntry));
29367 if(!lt)
29368 return UA_STATUSCODE_BADOUTOFMEMORY;
29369
29370 res = UA_LocalizedText_copy(src: value, dst: &lt->localizedText);
29371 if(res != UA_STATUSCODE_GOOD) {
29372 UA_free(ptr: lt);
29373 return res;
29374 }
29375
29376 lt->next = *root;
29377 *root = lt;
29378 return UA_STATUSCODE_GOOD;
29379}
29380
29381UA_StatusCode
29382UA_Node_insertOrUpdateDisplayName(UA_NodeHead *head,
29383 const UA_LocalizedText *value) {
29384 return UA_Node_insertOrUpdateLocale(root: &head->displayName, value);
29385}
29386
29387UA_StatusCode
29388UA_Node_insertOrUpdateDescription(UA_NodeHead *head,
29389 const UA_LocalizedText *value) {
29390 return UA_Node_insertOrUpdateLocale(root: &head->description, value);
29391}
29392
29393/**** amalgamated original file "/src/server/ua_server.c" ****/
29394
29395/* This Source Code Form is subject to the terms of the Mozilla Public
29396 * License, v. 2.0. If a copy of the MPL was not distributed with this
29397 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
29398 *
29399 * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
29400 * Copyright 2014-2017 (c) Florian Palm
29401 * Copyright 2015-2016 (c) Sten Grüner
29402 * Copyright 2015-2016 (c) Chris Iatrou
29403 * Copyright 2015 (c) LEvertz
29404 * Copyright 2015-2016 (c) Oleksiy Vasylyev
29405 * Copyright 2016 (c) Julian Grothoff
29406 * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH
29407 * Copyright 2016 (c) Lorenz Haas
29408 * Copyright 2017 (c) frax2222
29409 * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB
29410 * Copyright 2018 (c) Hilscher Gesellschaft für Systemautomation mbH (Author: Martin Lang)
29411 * Copyright 2019 (c) Kalycito Infotech Private Limited
29412 * Copyright 2021 (c) Fraunhofer IOSB (Author: Jan Hermes)
29413 * Copyright 2022 (c) Fraunhofer IOSB (Author: Andreas Ebner)
29414 */
29415
29416
29417#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
29418#endif
29419
29420#ifdef UA_ENABLE_SUBSCRIPTIONS
29421#endif
29422
29423#ifdef UA_ENABLE_NODESET_INJECTOR
29424#endif
29425
29426/**********************/
29427/* Namespace Handling */
29428/**********************/
29429
29430/* The NS1 Uri can be changed by the user to some custom string. This method is
29431 * called to initialize the NS1 Uri if it is not set before to the default
29432 * Application URI.
29433 *
29434 * This is done as soon as the Namespace Array is read or written via node value
29435 * read / write services, or UA_Server_addNamespace, or UA_Server_getNamespaceByIndex
29436 * UA_Server_getNamespaceByName or UA_Server_run_startup is called.
29437 *
29438 * Therefore one has to set the custom NS1 URI before one of the previously
29439 * mentioned steps. */
29440
29441void
29442setupNs1Uri(UA_Server *server) {
29443 if(!server->namespaces[1].data) {
29444 UA_String_copy(src: &server->config.applicationDescription.applicationUri,
29445 dst: &server->namespaces[1]);
29446 }
29447}
29448
29449UA_UInt16 addNamespace(UA_Server *server, const UA_String name) {
29450 /* ensure that the uri for ns1 is set up from the app description */
29451 setupNs1Uri(server);
29452
29453 /* Check if the namespace already exists in the server's namespace array */
29454 for(size_t i = 0; i < server->namespacesSize; ++i) {
29455 if(UA_String_equal(p1: &name, p2: &server->namespaces[i]))
29456 return (UA_UInt16) i;
29457 }
29458
29459 /* Make the array bigger */
29460 UA_String *newNS = (UA_String*)UA_realloc(ptr: server->namespaces,
29461 size: sizeof(UA_String) * (server->namespacesSize + 1));
29462 UA_CHECK_MEM(newNS, return 0);
29463
29464 server->namespaces = newNS;
29465
29466 /* Copy the namespace string */
29467 UA_StatusCode retval = UA_String_copy(src: &name, dst: &server->namespaces[server->namespacesSize]);
29468 UA_CHECK_STATUS(retval, return 0);
29469
29470 /* Announce the change (otherwise, the array appears unchanged) */
29471 ++server->namespacesSize;
29472 return (UA_UInt16)(server->namespacesSize - 1);
29473}
29474
29475UA_UInt16 UA_Server_addNamespace(UA_Server *server, const char* name) {
29476 /* Override const attribute to get string (dirty hack) */
29477 UA_String nameString;
29478 nameString.length = strlen(s: name);
29479 nameString.data = (UA_Byte*)(uintptr_t)name;
29480 lockServer(server);
29481 UA_UInt16 retVal = addNamespace(server, name: nameString);
29482 unlockServer(server);
29483 return retVal;
29484}
29485
29486UA_ServerConfig*
29487UA_Server_getConfig(UA_Server *server) {
29488 UA_CHECK_MEM(server, return NULL);
29489 return &server->config;
29490}
29491
29492UA_StatusCode
29493getNamespaceByName(UA_Server *server, const UA_String namespaceUri,
29494 size_t *foundIndex) {
29495 /* ensure that the uri for ns1 is set up from the app description */
29496 setupNs1Uri(server);
29497 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
29498 for(size_t idx = 0; idx < server->namespacesSize; idx++) {
29499 if(UA_String_equal(p1: &server->namespaces[idx], p2: &namespaceUri)) {
29500 (*foundIndex) = idx;
29501 res = UA_STATUSCODE_GOOD;
29502 break;
29503 }
29504 }
29505 return res;
29506}
29507
29508UA_StatusCode
29509getNamespaceByIndex(UA_Server *server, const size_t namespaceIndex,
29510 UA_String *foundUri) {
29511 /* ensure that the uri for ns1 is set up from the app description */
29512 setupNs1Uri(server);
29513 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
29514 if(namespaceIndex >= server->namespacesSize)
29515 return res;
29516 res = UA_String_copy(src: &server->namespaces[namespaceIndex], dst: foundUri);
29517 return res;
29518}
29519
29520UA_StatusCode
29521UA_Server_getNamespaceByName(UA_Server *server, const UA_String namespaceUri,
29522 size_t *foundIndex) {
29523 lockServer(server);
29524 UA_StatusCode res = getNamespaceByName(server, namespaceUri, foundIndex);
29525 unlockServer(server);
29526 return res;
29527}
29528
29529UA_StatusCode
29530UA_Server_getNamespaceByIndex(UA_Server *server, const size_t namespaceIndex,
29531 UA_String *foundUri) {
29532 lockServer(server);
29533 UA_StatusCode res = getNamespaceByIndex(server, namespaceIndex, foundUri);
29534 unlockServer(server);
29535 return res;
29536}
29537
29538UA_StatusCode
29539UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId,
29540 UA_NodeIteratorCallback callback, void *handle) {
29541 UA_BrowseDescription bd;
29542 UA_BrowseDescription_init(p: &bd);
29543 bd.nodeId = parentNodeId;
29544 bd.browseDirection = UA_BROWSEDIRECTION_BOTH;
29545 bd.resultMask = UA_BROWSERESULTMASK_REFERENCETYPEID | UA_BROWSERESULTMASK_ISFORWARD;
29546
29547 UA_BrowseResult br = UA_Server_browse(server, maxReferences: 0, bd: &bd);
29548 UA_StatusCode res = br.statusCode;
29549 UA_CHECK_STATUS(res, goto cleanup);
29550
29551 for(size_t i = 0; i < br.referencesSize; i++) {
29552 if(!UA_ExpandedNodeId_isLocal(n: &br.references[i].nodeId))
29553 continue;
29554 res = callback(br.references[i].nodeId.nodeId, !br.references[i].isForward,
29555 br.references[i].referenceTypeId, handle);
29556 UA_CHECK_STATUS(res, goto cleanup);
29557 }
29558cleanup:
29559 UA_BrowseResult_clear(p: &br);
29560 return res;
29561}
29562
29563/*********************/
29564/* Server Components */
29565/*********************/
29566
29567enum ZIP_CMP
29568cmpServerComponent(const UA_UInt64 *a, const UA_UInt64 *b) {
29569 if(*a == *b)
29570 return ZIP_CMP_EQ;
29571 return (*a < *b) ? ZIP_CMP_LESS : ZIP_CMP_MORE;
29572}
29573
29574void
29575addServerComponent(UA_Server *server, UA_ServerComponent *sc,
29576 UA_UInt64 *identifier) {
29577 if(!sc)
29578 return;
29579
29580 sc->identifier = ++server->serverComponentIds;
29581 ZIP_INSERT(UA_ServerComponentTree, &server->serverComponents, sc);
29582
29583 /* Start the component if the server is started */
29584 if(server->state == UA_LIFECYCLESTATE_STARTED && sc->start)
29585 sc->start(server, sc);
29586
29587 if(identifier)
29588 *identifier = sc->identifier;
29589}
29590
29591static void *
29592findServerComponent(void *context, UA_ServerComponent *sc) {
29593 UA_String *name = (UA_String*)context;
29594 return (UA_String_equal(p1: &sc->name, p2: name)) ? sc : NULL;
29595}
29596
29597UA_ServerComponent *
29598getServerComponentByName(UA_Server *server, UA_String name) {
29599 return (UA_ServerComponent*)
29600 ZIP_ITER(UA_ServerComponentTree, &server->serverComponents,
29601 findServerComponent, &name);
29602}
29603
29604static void *
29605removeServerComponent(void *application, UA_ServerComponent *sc) {
29606 UA_assert(sc->state == UA_LIFECYCLESTATE_STOPPED);
29607 sc->free((UA_Server*)application, sc);
29608 return NULL;
29609}
29610
29611static void *
29612startServerComponent(void *application, UA_ServerComponent *sc) {
29613 sc->start((UA_Server*)application, sc);
29614 return NULL;
29615}
29616
29617static void *
29618stopServerComponent(void *application, UA_ServerComponent *sc) {
29619 sc->stop((UA_Server*)application, sc);
29620 return NULL;
29621}
29622
29623/* ZIP_ITER returns NULL only if all components are stopped */
29624static void *
29625checkServerComponent(void *application, UA_ServerComponent *sc) {
29626 return (sc->state == UA_LIFECYCLESTATE_STOPPED) ? NULL : (void*)0x01;
29627}
29628
29629/********************/
29630/* Server Lifecycle */
29631/********************/
29632
29633/* The server needs to be stopped before it can be deleted */
29634UA_StatusCode
29635UA_Server_delete(UA_Server *server) {
29636 if(server == NULL) {
29637 return UA_STATUSCODE_BADINTERNALERROR;
29638 }
29639
29640 if(server->state != UA_LIFECYCLESTATE_STOPPED) {
29641 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
29642 msg: "The server must be fully stopped before it can be deleted");
29643 return UA_STATUSCODE_BADINTERNALERROR;
29644 }
29645
29646 lockServer(server);
29647
29648 session_list_entry *current, *temp;
29649 LIST_FOREACH_SAFE(current, &server->sessions, pointers, temp) {
29650 UA_Server_removeSession(server, sentry: current, shutdownReason: UA_SHUTDOWNREASON_CLOSE);
29651 }
29652 UA_Array_delete(p: server->namespaces, size: server->namespacesSize, type: &UA_TYPES[UA_TYPES_STRING]);
29653
29654#ifdef UA_ENABLE_SUBSCRIPTIONS
29655 UA_MonitoredItem *mon, *mon_tmp;
29656 LIST_FOREACH_SAFE(mon, &server->localMonitoredItems, listEntry, mon_tmp) {
29657 LIST_REMOVE(mon, listEntry);
29658 UA_MonitoredItem_delete(server, mon);
29659 }
29660
29661 /* Remove subscriptions without a session */
29662 UA_Subscription *sub, *sub_tmp;
29663 LIST_FOREACH_SAFE(sub, &server->subscriptions, serverListEntry, sub_tmp) {
29664 UA_Subscription_delete(server, sub);
29665 }
29666 UA_assert(server->monitoredItemsSize == 0);
29667 UA_assert(server->subscriptionsSize == 0);
29668
29669#ifdef UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS
29670 UA_ConditionList_delete(server);
29671#endif
29672
29673#endif
29674
29675#ifdef UA_ENABLE_PUBSUB
29676 UA_PubSubManager_delete(server, pubSubManager: &server->pubSubManager);
29677#endif
29678
29679#if UA_MULTITHREADING >= 100
29680 UA_AsyncManager_clear(&server->asyncManager, server);
29681#endif
29682
29683 /* Clean up the Admin Session */
29684 UA_Session_clear(session: &server->adminSession, server);
29685
29686 /* Remove all remaining server components (must be all stopped) */
29687 ZIP_ITER(UA_ServerComponentTree, &server->serverComponents,
29688 removeServerComponent, server);
29689
29690 unlockServer(server); /* The timer has its own mutex */
29691
29692 /* Clean up the config */
29693 UA_ServerConfig_clean(config: &server->config);
29694
29695#if UA_MULTITHREADING >= 100
29696 UA_LOCK_DESTROY(&server->serviceMutex);
29697#endif
29698
29699 /* Delete the server itself and return */
29700 UA_free(ptr: server);
29701 return UA_STATUSCODE_GOOD;
29702}
29703
29704/* Regular house-keeping tasks. Removing unused and timed-out channels and
29705 * sessions. */
29706static void
29707serverHouseKeeping(UA_Server *server, void *_) {
29708 lockServer(server);
29709 UA_DateTime nowMonotonic = UA_DateTime_nowMonotonic();
29710 UA_Server_cleanupSessions(server, nowMonotonic);
29711 unlockServer(server);
29712}
29713
29714/********************/
29715/* Server Lifecycle */
29716/********************/
29717
29718static
29719UA_INLINE
29720UA_Boolean UA_Server_NodestoreIsConfigured(UA_Server *server) {
29721 return server->config.nodestore.getNode != NULL;
29722}
29723
29724static UA_Server *
29725UA_Server_init(UA_Server *server) {
29726 UA_StatusCode res = UA_STATUSCODE_GOOD;
29727 UA_CHECK_FATAL(UA_Server_NodestoreIsConfigured(server), goto cleanup,
29728 server->config.logging, UA_LOGCATEGORY_SERVER,
29729 "No Nodestore configured in the server");
29730
29731 /* Init start time to zero, the actual start time will be sampled in
29732 * UA_Server_run_startup() */
29733 server->startTime = 0;
29734
29735 /* Set a seed for non-cyptographic randomness */
29736#ifndef UA_ENABLE_DETERMINISTIC_RNG
29737 UA_random_seed(seed: (UA_UInt64)UA_DateTime_now());
29738#endif
29739
29740 UA_LOCK_INIT(&server->serviceMutex);
29741 lockServer(server);
29742
29743 /* Initialize the adminSession */
29744 UA_Session_init(session: &server->adminSession);
29745 server->adminSession.sessionId.identifierType = UA_NODEIDTYPE_GUID;
29746 server->adminSession.sessionId.identifier.guid.data1 = 1;
29747 server->adminSession.validTill = UA_INT64_MAX;
29748 server->adminSession.sessionName = UA_STRING_ALLOC("Administrator");
29749
29750 /* Create Namespaces 0 and 1
29751 * Ns1 will be filled later with the uri from the app description */
29752 server->namespaces = (UA_String *)UA_Array_new(size: 2, type: &UA_TYPES[UA_TYPES_STRING]);
29753 UA_CHECK_MEM(server->namespaces, goto cleanup);
29754
29755 server->namespaces[0] = UA_STRING_ALLOC("http://opcfoundation.org/UA/");
29756 server->namespaces[1] = UA_STRING_NULL;
29757 server->namespacesSize = 2;
29758
29759 /* Initialize Session Management */
29760 LIST_INIT(&server->sessions);
29761 server->sessionCount = 0;
29762
29763#if UA_MULTITHREADING >= 100
29764 UA_AsyncManager_init(&server->asyncManager, server);
29765#endif
29766
29767 /* Initialize the binay protocol support */
29768 addServerComponent(server, sc: UA_BinaryProtocolManager_new(server), NULL);
29769
29770 /* Initialized discovery */
29771#ifdef UA_ENABLE_DISCOVERY
29772 addServerComponent(server, sc: UA_DiscoveryManager_new(server), NULL);
29773#endif
29774
29775 /* Initialize namespace 0*/
29776 res = initNS0(server);
29777 UA_CHECK_STATUS(res, goto cleanup);
29778
29779#ifdef UA_ENABLE_NODESET_INJECTOR
29780 res = UA_Server_injectNodesets(server);
29781 UA_CHECK_STATUS(res, goto cleanup);
29782#endif
29783
29784#ifdef UA_ENABLE_PUBSUB
29785 /* Initialized PubSubManager */
29786 UA_PubSubManager_init(server, pubSubManager: &server->pubSubManager);
29787
29788#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
29789 /* Build PubSub information model */
29790 initPubSubNS0(server);
29791#endif
29792
29793#ifdef UA_ENABLE_PUBSUB_MONITORING
29794 /* setup default PubSub monitoring callbacks */
29795 res = UA_PubSubManager_setDefaultMonitoringCallbacks(&server->config.pubSubConfig.monitoringInterface);
29796 UA_CHECK_STATUS(res, goto cleanup);
29797#endif /* UA_ENABLE_PUBSUB_MONITORING */
29798#endif /* UA_ENABLE_PUBSUB */
29799
29800 unlockServer(server);
29801 return server;
29802
29803 cleanup:
29804 unlockServer(server);
29805 UA_Server_delete(server);
29806 return NULL;
29807}
29808
29809UA_Server *
29810UA_Server_newWithConfig(UA_ServerConfig *config) {
29811 UA_CHECK_MEM(config, return NULL);
29812
29813 UA_CHECK_LOG(config->eventLoop != NULL, return NULL, ERROR,
29814 config->logging, UA_LOGCATEGORY_SERVER, "No EventLoop configured");
29815
29816 UA_Server *server = (UA_Server *)UA_calloc(nmemb: 1, size: sizeof(UA_Server));
29817 UA_CHECK_MEM(server, UA_ServerConfig_clean(config); return NULL);
29818
29819 server->config = *config;
29820
29821 /* If not defined, set logging to what the server has */
29822 if(!server->config.secureChannelPKI.logging)
29823 server->config.secureChannelPKI.logging = server->config.logging;
29824 if(!server->config.sessionPKI.logging)
29825 server->config.sessionPKI.logging = server->config.logging;
29826
29827 /* Reset the old config */
29828 memset(s: config, c: 0, n: sizeof(UA_ServerConfig));
29829 return UA_Server_init(server);
29830}
29831
29832/* Returns if the server should be shut down immediately */
29833static UA_Boolean
29834setServerShutdown(UA_Server *server) {
29835 if(server->endTime != 0)
29836 return false;
29837 if(server->config.shutdownDelay == 0)
29838 return true;
29839 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
29840 msg: "Shutting down the server with a delay of %i ms", (int)server->config.shutdownDelay);
29841 server->endTime = UA_DateTime_now() + (UA_DateTime)(server->config.shutdownDelay * UA_DATETIME_MSEC);
29842 return false;
29843}
29844
29845/*******************/
29846/* Timed Callbacks */
29847/*******************/
29848
29849UA_StatusCode
29850UA_Server_addTimedCallback(UA_Server *server, UA_ServerCallback callback,
29851 void *data, UA_DateTime date, UA_UInt64 *callbackId) {
29852 lockServer(server);
29853 UA_StatusCode retval = server->config.eventLoop->
29854 addTimedCallback(server->config.eventLoop, (UA_Callback)callback,
29855 server, data, date, callbackId);
29856 unlockServer(server);
29857 return retval;
29858}
29859
29860UA_StatusCode
29861addRepeatedCallback(UA_Server *server, UA_ServerCallback callback,
29862 void *data, UA_Double interval_ms, UA_UInt64 *callbackId) {
29863 UA_LOCK_ASSERT(&server->serviceMutex, 1);
29864 return server->config.eventLoop->
29865 addCyclicCallback(server->config.eventLoop, (UA_Callback) callback,
29866 server, data, interval_ms, NULL,
29867 UA_TIMER_HANDLE_CYCLEMISS_WITH_CURRENTTIME, callbackId);
29868}
29869
29870UA_StatusCode
29871UA_Server_addRepeatedCallback(UA_Server *server, UA_ServerCallback callback,
29872 void *data, UA_Double interval_ms,
29873 UA_UInt64 *callbackId) {
29874 lockServer(server);
29875 UA_StatusCode res = addRepeatedCallback(server, callback, data, interval_ms, callbackId);
29876 unlockServer(server);
29877 return res;
29878}
29879
29880UA_StatusCode
29881changeRepeatedCallbackInterval(UA_Server *server, UA_UInt64 callbackId,
29882 UA_Double interval_ms) {
29883 UA_LOCK_ASSERT(&server->serviceMutex, 1);
29884 return server->config.eventLoop->
29885 modifyCyclicCallback(server->config.eventLoop, callbackId, interval_ms,
29886 NULL, UA_TIMER_HANDLE_CYCLEMISS_WITH_CURRENTTIME);
29887}
29888
29889UA_StatusCode
29890UA_Server_changeRepeatedCallbackInterval(UA_Server *server, UA_UInt64 callbackId,
29891 UA_Double interval_ms) {
29892 lockServer(server);
29893 UA_StatusCode retval =
29894 changeRepeatedCallbackInterval(server, callbackId, interval_ms);
29895 unlockServer(server);
29896 return retval;
29897}
29898
29899void
29900removeCallback(UA_Server *server, UA_UInt64 callbackId) {
29901 UA_LOCK_ASSERT(&server->serviceMutex, 1);
29902 UA_EventLoop *el = server->config.eventLoop;
29903 if(el) {
29904 el->removeCyclicCallback(el, callbackId);
29905 }
29906}
29907
29908void
29909UA_Server_removeCallback(UA_Server *server, UA_UInt64 callbackId) {
29910 lockServer(server);
29911 removeCallback(server, callbackId);
29912 unlockServer(server);
29913}
29914
29915static void
29916notifySecureChannelsStopped(UA_Server *server, struct UA_ServerComponent *sc,
29917 UA_LifecycleState state) {
29918 if(sc->state == UA_LIFECYCLESTATE_STOPPED &&
29919 server->state == UA_LIFECYCLESTATE_STARTED) {
29920 sc->notifyState = NULL; /* remove the callback */
29921 sc->start(server, sc);
29922 }
29923}
29924
29925UA_StatusCode
29926UA_Server_updateCertificate(UA_Server *server,
29927 const UA_ByteString *oldCertificate,
29928 const UA_ByteString *newCertificate,
29929 const UA_ByteString *newPrivateKey,
29930 UA_Boolean closeSessions,
29931 UA_Boolean closeSecureChannels) {
29932 UA_CHECK(server && oldCertificate && newCertificate && newPrivateKey,
29933 return UA_STATUSCODE_BADINTERNALERROR);
29934
29935 lockServer(server);
29936
29937 if(closeSessions) {
29938 session_list_entry *current;
29939 LIST_FOREACH(current, &server->sessions, pointers) {
29940 UA_SessionHeader *header = &current->session.header;
29941 if(UA_ByteString_equal(p1: oldCertificate, p2: &header->channel->securityPolicy->localCertificate))
29942 UA_Server_removeSessionByToken(server, token: &header->authenticationToken,
29943 shutdownReason: UA_SHUTDOWNREASON_CLOSE);
29944 }
29945 }
29946
29947 /* Gracefully close all SecureChannels. And restart the
29948 * BinaryProtocolManager once it has fully stopped. */
29949 if(closeSecureChannels) {
29950 UA_ServerComponent *binaryProtocolManager =
29951 getServerComponentByName(server, name: UA_STRING(chars: "binary"));
29952 if(binaryProtocolManager) {
29953 binaryProtocolManager->notifyState = notifySecureChannelsStopped;
29954 binaryProtocolManager->stop(server, binaryProtocolManager);
29955 }
29956 }
29957
29958 size_t i = 0;
29959 UA_StatusCode res = UA_STATUSCODE_GOOD;
29960 while(i < server->config.endpointsSize) {
29961 UA_EndpointDescription *ed = &server->config.endpoints[i];
29962 if(UA_ByteString_equal(p1: &ed->serverCertificate, p2: oldCertificate)) {
29963 UA_String_clear(p: &ed->serverCertificate);
29964 UA_String_copy(src: newCertificate, dst: &ed->serverCertificate);
29965 UA_SecurityPolicy *sp = getSecurityPolicyByUri(server,
29966 securityPolicyUri: &server->config.endpoints[i].securityPolicyUri);
29967 if(!sp) {
29968 res = UA_STATUSCODE_BADINTERNALERROR;
29969 break;
29970 }
29971 sp->updateCertificateAndPrivateKey(sp, *newCertificate, *newPrivateKey);
29972 }
29973 i++;
29974 }
29975
29976 unlockServer(server);
29977
29978 return res;
29979}
29980
29981/***************************/
29982/* Server lookup functions */
29983/***************************/
29984
29985UA_SecurityPolicy *
29986getSecurityPolicyByUri(const UA_Server *server, const UA_ByteString *securityPolicyUri) {
29987 for(size_t i = 0; i < server->config.securityPoliciesSize; i++) {
29988 UA_SecurityPolicy *securityPolicyCandidate = &server->config.securityPolicies[i];
29989 if(UA_ByteString_equal(p1: securityPolicyUri, p2: &securityPolicyCandidate->policyUri))
29990 return securityPolicyCandidate;
29991 }
29992 return NULL;
29993}
29994
29995#ifdef UA_ENABLE_ENCRYPTION
29996/* The local ApplicationURI has to match the certificates of the
29997 * SecurityPolicies */
29998static UA_StatusCode
29999verifyServerApplicationURI(const UA_Server *server) {
30000 const UA_String securityPolicyNoneUri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#None");
30001 for(size_t i = 0; i < server->config.securityPoliciesSize; i++) {
30002 UA_SecurityPolicy *sp = &server->config.securityPolicies[i];
30003 if(UA_String_equal(p1: &sp->policyUri, p2: &securityPolicyNoneUri) && (sp->localCertificate.length == 0))
30004 continue;
30005 UA_StatusCode retval = server->config.secureChannelPKI.
30006 verifyApplicationURI(&server->config.secureChannelPKI,
30007 &sp->localCertificate,
30008 &server->config.applicationDescription.applicationUri);
30009
30010 UA_CHECK_STATUS_ERROR(retval, return retval, server->config.logging, UA_LOGCATEGORY_SERVER,
30011 "The configured ApplicationURI \"%.*s\"does not match the "
30012 "ApplicationURI specified in the certificate for the "
30013 "SecurityPolicy %.*s",
30014 (int)server->config.applicationDescription.applicationUri.length,
30015 server->config.applicationDescription.applicationUri.data,
30016 (int)sp->policyUri.length, sp->policyUri.data);
30017 }
30018 return UA_STATUSCODE_GOOD;
30019}
30020#endif
30021
30022UA_ServerStatistics
30023UA_Server_getStatistics(UA_Server *server) {
30024 UA_ServerStatistics stat;
30025 lockServer(server);
30026 stat.scs = server->secureChannelStatistics;
30027 UA_ServerDiagnosticsSummaryDataType *sds = &server->serverDiagnosticsSummary;
30028 stat.ss.currentSessionCount = server->activeSessionCount;
30029 stat.ss.cumulatedSessionCount = sds->cumulatedSessionCount;
30030 stat.ss.securityRejectedSessionCount = sds->securityRejectedSessionCount;
30031 stat.ss.rejectedSessionCount = sds->rejectedSessionCount;
30032 stat.ss.sessionTimeoutCount = sds->sessionTimeoutCount;
30033 stat.ss.sessionAbortCount = sds->sessionAbortCount;
30034 unlockServer(server);
30035 return stat;
30036}
30037
30038/********************/
30039/* Main Server Loop */
30040/********************/
30041
30042#define UA_MAXTIMEOUT 500 /* Max timeout in ms between main-loop iterations */
30043
30044void
30045setServerLifecycleState(UA_Server *server, UA_LifecycleState state) {
30046 UA_LOCK_ASSERT(&server->serviceMutex, 1);
30047 if(server->state == state)
30048 return;
30049 server->state = state;
30050 if(server->config.notifyLifecycleState)
30051 server->config.notifyLifecycleState(server, server->state);
30052}
30053
30054UA_LifecycleState
30055UA_Server_getLifecycleState(UA_Server *server) {
30056 return server->state;
30057}
30058
30059/* Start: Spin up the workers and the network layer and sample the server's
30060 * start time.
30061 * Iterate: Process repeated callbacks and events in the network layer. This
30062 * part can be driven from an external main-loop in an event-driven
30063 * single-threaded architecture.
30064 * Stop: Stop workers, finish all callbacks, stop the network layer, clean up */
30065
30066UA_StatusCode
30067UA_Server_run_startup(UA_Server *server) {
30068 if(server == NULL) {
30069 return UA_STATUSCODE_BADINVALIDARGUMENT;
30070 }
30071 UA_ServerConfig *config = &server->config;
30072
30073#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
30074 /* Prominently warn user that fuzzing build is enabled. This will tamper
30075 * with authentication tokens and other important variables E.g. if fuzzing
30076 * is enabled, and two clients are connected, subscriptions do not work
30077 * properly, since the tokens will be overridden to allow easier fuzzing. */
30078 UA_LOG_FATAL(server->config.logging, UA_LOGCATEGORY_SERVER,
30079 "Server was built with unsafe fuzzing mode. "
30080 "This should only be used for specific fuzzing builds.");
30081#endif
30082
30083 if(server->state != UA_LIFECYCLESTATE_STOPPED) {
30084 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
30085 msg: "The server has already been started");
30086 return UA_STATUSCODE_BADINTERNALERROR;
30087 }
30088
30089 /* Check if UserIdentityTokens are defined */
30090 bool hasUserIdentityTokens = false;
30091 for(size_t i = 0; i < config->endpointsSize; i++) {
30092 if(config->endpoints[i].userIdentityTokensSize > 0) {
30093 hasUserIdentityTokens = true;
30094 break;
30095 }
30096 }
30097 if(config->accessControl.userTokenPoliciesSize == 0 && hasUserIdentityTokens == false) {
30098 UA_LOG_ERROR(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
30099 msg: "The server has no userIdentificationPolicies defined.");
30100 return UA_STATUSCODE_BADINTERNALERROR;
30101 }
30102
30103 /* Start the EventLoop if not already started */
30104 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
30105 UA_EventLoop *el = config->eventLoop;
30106 UA_CHECK_MEM_ERROR(el, return UA_STATUSCODE_BADINTERNALERROR,
30107 config->logging, UA_LOGCATEGORY_SERVER,
30108 "An EventLoop must be configured");
30109
30110 if(el->state != UA_EVENTLOOPSTATE_STARTED) {
30111 retVal = el->start(el);
30112 UA_CHECK_STATUS(retVal, return retVal); /* Errors are logged internally */
30113 }
30114
30115 /* Take the server lock */
30116 lockServer(server);
30117
30118 /* Does the ApplicationURI match the local certificates? */
30119#ifdef UA_ENABLE_ENCRYPTION
30120 retVal = verifyServerApplicationURI(server);
30121 UA_CHECK_STATUS(retVal, unlockServer(server); return retVal);
30122#endif
30123
30124 /* Are there enough SecureChannels possible for the max number of sessions? */
30125 if(config->maxSecureChannels != 0 &&
30126 (config->maxSessions == 0 || config->maxSessions > config->maxSecureChannels)) {
30127 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
30128 msg: "Maximum SecureChannels count not enough for the "
30129 "maximum Sessions count");
30130 }
30131
30132 /* Add a regular callback for housekeeping tasks. With a 1s interval. */
30133 retVal = addRepeatedCallback(server, callback: serverHouseKeeping,
30134 NULL, interval_ms: 1000.0, callbackId: &server->houseKeepingCallbackId);
30135 UA_CHECK_STATUS_ERROR(retVal, unlockServer(server); return retVal,
30136 config->logging, UA_LOGCATEGORY_SERVER,
30137 "Could not create the server housekeeping task");
30138
30139 /* Ensure that the uri for ns1 is set up from the app description */
30140 UA_String_clear(p: &server->namespaces[1]);
30141 setupNs1Uri(server);
30142
30143 /* At least one endpoint has to be configured */
30144 if(config->endpointsSize == 0) {
30145 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
30146 msg: "There has to be at least one endpoint.");
30147 }
30148
30149 /* Update Endpoint description */
30150 for(size_t i = 0; i < config->endpointsSize; ++i) {
30151 UA_ApplicationDescription_clear(p: &config->endpoints[i].server);
30152 UA_ApplicationDescription_copy(src: &config->applicationDescription,
30153 dst: &config->endpoints[i].server);
30154 }
30155
30156 /* Write ServerArray with same ApplicationUri value as NamespaceArray */
30157 UA_Variant var;
30158 UA_Variant_init(p: &var);
30159 UA_Variant_setArray(v: &var, array: &config->applicationDescription.applicationUri,
30160 arraySize: 1, type: &UA_TYPES[UA_TYPES_STRING]);
30161 UA_NodeId serverArray = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERARRAY);
30162 writeValueAttribute(server, nodeId: serverArray, value: &var);
30163
30164 /* Sample the start time and set it to the Server object */
30165 server->startTime = UA_DateTime_now();
30166 UA_Variant_init(p: &var);
30167 UA_Variant_setScalar(v: &var, p: &server->startTime, type: &UA_TYPES[UA_TYPES_DATETIME]);
30168 UA_NodeId startTime =
30169 UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS_STARTTIME);
30170 writeValueAttribute(server, nodeId: startTime, value: &var);
30171
30172 /* Start all ServerComponents */
30173 ZIP_ITER(UA_ServerComponentTree, &server->serverComponents,
30174 startServerComponent, server);
30175
30176 /* Check that the binary protocol support component have been started */
30177 UA_ServerComponent *binaryProtocolManager =
30178 getServerComponentByName(server, name: UA_STRING(chars: "binary"));
30179 if(binaryProtocolManager->state != UA_LIFECYCLESTATE_STARTED) {
30180 UA_LOG_ERROR(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
30181 msg: "The binary protocol support component could not been started.");
30182 /* Stop all server components that have already been started */
30183 ZIP_ITER(UA_ServerComponentTree, &server->serverComponents,
30184 stopServerComponent, server);
30185 unlockServer(server);
30186 return UA_STATUSCODE_BADINTERNALERROR;
30187 }
30188
30189 /* Set the server to STARTED. From here on, only use
30190 * UA_Server_run_shutdown(server) to stop the server. */
30191 setServerLifecycleState(server, state: UA_LIFECYCLESTATE_STARTED);
30192
30193 unlockServer(server);
30194 return UA_STATUSCODE_GOOD;
30195}
30196
30197UA_UInt16
30198UA_Server_run_iterate(UA_Server *server, UA_Boolean waitInternal) {
30199 /* Make sure an EventLoop is configured */
30200 UA_EventLoop *el = server->config.eventLoop;
30201 if(!el)
30202 return 0;
30203
30204 /* Process timed and network events in the EventLoop */
30205 UA_UInt32 timeout = (waitInternal) ? UA_MAXTIMEOUT : 0;
30206 el->run(el, timeout);
30207
30208 /* Return the time until the next scheduled callback */
30209 UA_DateTime now = el->dateTime_nowMonotonic(el);
30210 UA_DateTime nextTimeout = (el->nextCyclicTime(el) - now) / UA_DATETIME_MSEC;
30211 if(nextTimeout < 0)
30212 nextTimeout = 0;
30213 if(nextTimeout > UA_UINT16_MAX)
30214 nextTimeout = UA_UINT16_MAX;
30215 return (UA_UInt16)nextTimeout;
30216}
30217
30218static UA_Boolean
30219testShutdownCondition(UA_Server *server) {
30220 /* Was there a wait time until the shutdown configured? */
30221 if(server->endTime == 0)
30222 return false;
30223 return (UA_DateTime_now() > server->endTime);
30224}
30225
30226static UA_Boolean
30227testStoppedCondition(UA_Server *server) {
30228 /* Check if there are remaining server components that did not fully stop */
30229 if(ZIP_ITER(UA_ServerComponentTree, &server->serverComponents,
30230 checkServerComponent, server) != NULL)
30231 return false;
30232 return true;
30233}
30234
30235UA_StatusCode
30236UA_Server_run_shutdown(UA_Server *server) {
30237 if(server == NULL)
30238 return UA_STATUSCODE_BADINVALIDARGUMENT;
30239
30240 lockServer(server);
30241
30242 if(server->state != UA_LIFECYCLESTATE_STARTED) {
30243 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
30244 msg: "The server is not started, cannot be shut down");
30245 unlockServer(server);
30246 return UA_STATUSCODE_BADINTERNALERROR;
30247 }
30248
30249 /* Set to stopping and notify the application */
30250 setServerLifecycleState(server, state: UA_LIFECYCLESTATE_STOPPING);
30251
30252 /* Stop the regular housekeeping tasks */
30253 if(server->houseKeepingCallbackId != 0) {
30254 removeCallback(server, callbackId: server->houseKeepingCallbackId);
30255 server->houseKeepingCallbackId = 0;
30256 }
30257
30258 /* Stop PubSub */
30259#ifdef UA_ENABLE_PUBSUB
30260 UA_PubSubManager_shutdown(server, pubSubManager: &server->pubSubManager);
30261#endif
30262
30263 /* Stop all ServerComponents */
30264 ZIP_ITER(UA_ServerComponentTree, &server->serverComponents,
30265 stopServerComponent, server);
30266
30267 /* Are we already stopped? */
30268 if(testStoppedCondition(server)) {
30269 setServerLifecycleState(server, state: UA_LIFECYCLESTATE_STOPPED);
30270 }
30271
30272 /* Only stop the EventLoop if it is coupled to the server lifecycle */
30273 if(server->config.externalEventLoop) {
30274 unlockServer(server);
30275 return UA_STATUSCODE_GOOD;
30276 }
30277
30278 /* Iterate the EventLoop until the server is stopped */
30279 UA_StatusCode res = UA_STATUSCODE_GOOD;
30280 UA_EventLoop *el = server->config.eventLoop;
30281 while(!testStoppedCondition(server) &&
30282 res == UA_STATUSCODE_GOOD) {
30283 res = el->run(el, 100);
30284 }
30285
30286 /* Stop the EventLoop. Iterate until stopped. */
30287 el->stop(el);
30288 while(el->state != UA_EVENTLOOPSTATE_STOPPED &&
30289 el->state != UA_EVENTLOOPSTATE_FRESH &&
30290 res == UA_STATUSCODE_GOOD) {
30291 res = el->run(el, 100);
30292 }
30293
30294 /* Set server lifecycle state to stopped if not already the case */
30295 setServerLifecycleState(server, state: UA_LIFECYCLESTATE_STOPPED);
30296
30297 unlockServer(server);
30298 return res;
30299}
30300
30301UA_StatusCode
30302UA_Server_run(UA_Server *server, const volatile UA_Boolean *running) {
30303 UA_StatusCode retval = UA_Server_run_startup(server);
30304 UA_CHECK_STATUS(retval, return retval);
30305
30306 while(!testShutdownCondition(server)) {
30307 UA_Server_run_iterate(server, true);
30308 if(!*running) {
30309 if(setServerShutdown(server))
30310 break;
30311 }
30312 }
30313 return UA_Server_run_shutdown(server);
30314}
30315
30316void lockServer(UA_Server *server) {
30317 if(UA_LIKELY(server->config.eventLoop && server->config.eventLoop->lock))
30318 server->config.eventLoop->lock(server->config.eventLoop);
30319 UA_LOCK(&server->serviceMutex);
30320}
30321
30322void unlockServer(UA_Server *server) {
30323 if(UA_LIKELY(server->config.eventLoop && server->config.eventLoop->unlock))
30324 server->config.eventLoop->unlock(server->config.eventLoop);
30325 UA_UNLOCK(&server->serviceMutex);
30326}
30327
30328/**** amalgamated original file "/src/server/ua_server_ns0.c" ****/
30329
30330/* This Source Code Form is subject to the terms of the Mozilla Public
30331 * License, v. 2.0. If a copy of the MPL was not distributed with this
30332 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
30333 *
30334 * Copyright 2017-2022 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
30335 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
30336 * Copyright 2017 (c) Thomas Bender
30337 * Copyright 2017 (c) Julian Grothoff
30338 * Copyright 2017 (c) Henrik Norrman
30339 * Copyright 2018 (c) Fabian Arndt, Root-Core
30340 * Copyright 2019 (c) Kalycito Infotech Private Limited
30341 * Copyright 2021 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati)
30342 * Copyright 2023 (c) Fraunhofer IOSB (Author: Andreas Ebner)
30343 */
30344
30345
30346
30347static UA_StatusCode
30348ns0_addNode_raw(UA_Server *server, UA_NodeClass nodeClass,
30349 UA_UInt32 nodeId, char *name, void *attributes,
30350 const UA_DataType *attributesType) {
30351 UA_AddNodesItem item;
30352 UA_AddNodesItem_init(p: &item);
30353 item.nodeClass = nodeClass;
30354 item.requestedNewNodeId.nodeId = UA_NODEID_NUMERIC(nsIndex: 0, identifier: nodeId);
30355 item.browseName = UA_QUALIFIEDNAME(nsIndex: 0, chars: name);
30356 UA_ExtensionObject_setValueNoDelete(eo: &item.nodeAttributes,
30357 p: attributes, type: attributesType);
30358 return addNode_raw(server, session: &server->adminSession, NULL, item: &item, NULL);
30359}
30360
30361static UA_StatusCode
30362ns0_addNode_finish(UA_Server *server, UA_UInt32 nodeId,
30363 UA_UInt32 parentNodeId, UA_UInt32 referenceTypeId) {
30364 const UA_NodeId sourceId = UA_NODEID_NUMERIC(nsIndex: 0, identifier: nodeId);
30365 const UA_NodeId refTypeId = UA_NODEID_NUMERIC(nsIndex: 0, identifier: referenceTypeId);
30366 const UA_NodeId targetId = UA_NODEID_NUMERIC(nsIndex: 0, identifier: parentNodeId);
30367 UA_StatusCode retval = addRef(server, sourceId, referenceTypeId: refTypeId, targetId, false);
30368 if(retval != UA_STATUSCODE_GOOD)
30369 return retval;
30370 return addNode_finish(server, session: &server->adminSession, nodeId: &sourceId);
30371}
30372
30373static UA_StatusCode
30374addObjectNode(UA_Server *server, char* name, UA_UInt32 objectid,
30375 UA_UInt32 parentid, UA_UInt32 referenceid, UA_UInt32 type_id) {
30376 UA_ObjectAttributes object_attr = UA_ObjectAttributes_default;
30377 object_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: name);
30378 return addNode(server, nodeClass: UA_NODECLASS_OBJECT, requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 0, identifier: objectid),
30379 parentNodeId: UA_NODEID_NUMERIC(nsIndex: 0, identifier: parentid), referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, identifier: referenceid),
30380 browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: name), typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, identifier: type_id),
30381 attr: &object_attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
30382 NULL, NULL);
30383}
30384
30385static UA_StatusCode
30386addReferenceTypeNode(UA_Server *server, char* name, char *inverseName, UA_UInt32 referencetypeid,
30387 UA_Boolean isabstract, UA_Boolean symmetric, UA_UInt32 parentid) {
30388 UA_ReferenceTypeAttributes reference_attr = UA_ReferenceTypeAttributes_default;
30389 reference_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: name);
30390 reference_attr.isAbstract = isabstract;
30391 reference_attr.symmetric = symmetric;
30392 if(inverseName)
30393 reference_attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: inverseName);
30394 return addNode(server, nodeClass: UA_NODECLASS_REFERENCETYPE, requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 0, identifier: referencetypeid),
30395 parentNodeId: UA_NODEID_NUMERIC(nsIndex: 0, identifier: parentid), referenceTypeId: UA_NODEID_NULL, browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: name),
30396 typeDefinition: UA_NODEID_NULL, attr: &reference_attr,
30397 attributeType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES], NULL, NULL);
30398}
30399
30400/***************************/
30401/* Bootstrap NS0 hierarchy */
30402/***************************/
30403
30404/* Creates the basic nodes which are expected by the nodeset compiler to be
30405 * already created. This is necessary to reduce the dependencies for the nodeset
30406 * compiler. */
30407static UA_StatusCode
30408createNS0_base(UA_Server *server) {
30409 /* Bootstrap ReferenceTypes. The order of these is important for the
30410 * ReferenceTypeIndex. The ReferenceTypeIndex is created with the raw node.
30411 * The ReferenceTypeSet of subtypes for every ReferenceType is created
30412 * during the call to AddNode_finish. */
30413 UA_StatusCode ret = UA_STATUSCODE_GOOD;
30414 UA_ReferenceTypeAttributes references_attr = UA_ReferenceTypeAttributes_default;
30415 references_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "References");
30416 references_attr.isAbstract = true;
30417 references_attr.symmetric = true;
30418 references_attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "References");
30419 ret |= ns0_addNode_raw(server, nodeClass: UA_NODECLASS_REFERENCETYPE, UA_NS0ID_REFERENCES, name: "References",
30420 attributes: &references_attr, attributesType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]);
30421
30422 UA_ReferenceTypeAttributes hassubtype_attr = UA_ReferenceTypeAttributes_default;
30423 hassubtype_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HasSubtype");
30424 hassubtype_attr.isAbstract = false;
30425 hassubtype_attr.symmetric = false;
30426 hassubtype_attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "SubtypeOf");
30427 ret |= ns0_addNode_raw(server, nodeClass: UA_NODECLASS_REFERENCETYPE, UA_NS0ID_HASSUBTYPE, name: "HasSubtype",
30428 attributes: &hassubtype_attr, attributesType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]);
30429
30430 UA_ReferenceTypeAttributes aggregates_attr = UA_ReferenceTypeAttributes_default;
30431 aggregates_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Aggregates");
30432 aggregates_attr.isAbstract = true;
30433 aggregates_attr.symmetric = false;
30434 aggregates_attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "AggregatedBy");
30435 ret |= ns0_addNode_raw(server, nodeClass: UA_NODECLASS_REFERENCETYPE, UA_NS0ID_AGGREGATES, name: "Aggregates",
30436 attributes: &aggregates_attr, attributesType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]);
30437
30438 ret |= addReferenceTypeNode(server, name: "HierarchicalReferences", NULL,
30439 UA_NS0ID_HIERARCHICALREFERENCES, true, false, UA_NS0ID_REFERENCES);
30440
30441 ret |= addReferenceTypeNode(server, name: "NonHierarchicalReferences", NULL,
30442 UA_NS0ID_NONHIERARCHICALREFERENCES, true, true, UA_NS0ID_REFERENCES);
30443
30444 ret |= addReferenceTypeNode(server, name: "HasChild", NULL, UA_NS0ID_HASCHILD,
30445 true, false, UA_NS0ID_HIERARCHICALREFERENCES);
30446
30447 ret |= addReferenceTypeNode(server, name: "Organizes", inverseName: "OrganizedBy", UA_NS0ID_ORGANIZES,
30448 false, false, UA_NS0ID_HIERARCHICALREFERENCES);
30449
30450 ret |= addReferenceTypeNode(server, name: "HasEventSource", inverseName: "EventSourceOf", UA_NS0ID_HASEVENTSOURCE,
30451 false, false, UA_NS0ID_HIERARCHICALREFERENCES);
30452
30453 ret |= addReferenceTypeNode(server, name: "HasModellingRule", inverseName: "ModellingRuleOf", UA_NS0ID_HASMODELLINGRULE,
30454 false, false, UA_NS0ID_NONHIERARCHICALREFERENCES);
30455
30456 ret |= addReferenceTypeNode(server, name: "HasEncoding", inverseName: "EncodingOf", UA_NS0ID_HASENCODING,
30457 false, false, UA_NS0ID_NONHIERARCHICALREFERENCES);
30458
30459 ret |= addReferenceTypeNode(server, name: "HasDescription", inverseName: "DescriptionOf", UA_NS0ID_HASDESCRIPTION,
30460 false, false, UA_NS0ID_NONHIERARCHICALREFERENCES);
30461
30462 ret |= addReferenceTypeNode(server, name: "HasTypeDefinition", inverseName: "TypeDefinitionOf", UA_NS0ID_HASTYPEDEFINITION,
30463 false, false, UA_NS0ID_NONHIERARCHICALREFERENCES);
30464
30465 ret |= addReferenceTypeNode(server, name: "GeneratesEvent", inverseName: "GeneratedBy", UA_NS0ID_GENERATESEVENT,
30466 false, false, UA_NS0ID_NONHIERARCHICALREFERENCES);
30467
30468 /* Complete bootstrap of Aggregates */
30469 ret |= ns0_addNode_finish(server, UA_NS0ID_AGGREGATES, UA_NS0ID_HASCHILD, UA_NS0ID_HASSUBTYPE);
30470
30471 /* Complete bootstrap of HasSubtype */
30472 ret |= ns0_addNode_finish(server, UA_NS0ID_HASSUBTYPE, UA_NS0ID_HASCHILD, UA_NS0ID_HASSUBTYPE);
30473
30474 ret |= addReferenceTypeNode(server, name: "HasProperty", inverseName: "PropertyOf", UA_NS0ID_HASPROPERTY,
30475 false, false, UA_NS0ID_AGGREGATES);
30476
30477 ret |= addReferenceTypeNode(server, name: "HasComponent", inverseName: "ComponentOf", UA_NS0ID_HASCOMPONENT,
30478 false, false, UA_NS0ID_AGGREGATES);
30479
30480 ret |= addReferenceTypeNode(server, name: "HasNotifier", inverseName: "NotifierOf", UA_NS0ID_HASNOTIFIER,
30481 false, false, UA_NS0ID_HASEVENTSOURCE);
30482
30483 ret |= addReferenceTypeNode(server, name: "HasOrderedComponent", inverseName: "OrderedComponentOf",
30484 UA_NS0ID_HASORDEREDCOMPONENT, false, false, UA_NS0ID_HASCOMPONENT);
30485
30486 ret |= addReferenceTypeNode(server, name: "HasInterface", inverseName: "InterfaceOf",
30487 UA_NS0ID_HASINTERFACE, false, false, UA_NS0ID_NONHIERARCHICALREFERENCES);
30488
30489 /**************/
30490 /* Data Types */
30491 /**************/
30492
30493 /* Bootstrap BaseDataType */
30494 UA_DataTypeAttributes basedatatype_attr = UA_DataTypeAttributes_default;
30495 basedatatype_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BaseDataType");
30496 basedatatype_attr.isAbstract = true;
30497 ret |= ns0_addNode_raw(server, nodeClass: UA_NODECLASS_DATATYPE, UA_NS0ID_BASEDATATYPE, name: "BaseDataType",
30498 attributes: &basedatatype_attr, attributesType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES]);
30499
30500 /*****************/
30501 /* VariableTypes */
30502 /*****************/
30503
30504 UA_VariableTypeAttributes basevar_attr = UA_VariableTypeAttributes_default;
30505 basevar_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BaseVariableType");
30506 basevar_attr.isAbstract = true;
30507 basevar_attr.valueRank = UA_VALUERANK_ANY;
30508 basevar_attr.dataType = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEDATATYPE);
30509 ret |= ns0_addNode_raw(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
30510 UA_NS0ID_BASEVARIABLETYPE, name: "BaseVariableType",
30511 attributes: &basevar_attr, attributesType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES]);
30512
30513 UA_VariableTypeAttributes bdv_attr = UA_VariableTypeAttributes_default;
30514 bdv_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BaseDataVariableType");
30515 bdv_attr.dataType = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEDATATYPE);
30516 bdv_attr.valueRank = UA_VALUERANK_ANY;
30517 ret |= addNode(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
30518 requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEDATAVARIABLETYPE),
30519 parentNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEVARIABLETYPE),
30520 referenceTypeId: UA_NODEID_NULL, browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "BaseDataVariableType"),
30521 typeDefinition: UA_NODEID_NULL, attr: &bdv_attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],
30522 NULL, NULL);
30523
30524 UA_VariableTypeAttributes prop_attr = UA_VariableTypeAttributes_default;
30525 prop_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PropertyType");
30526 prop_attr.dataType = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEDATATYPE);
30527 prop_attr.valueRank = UA_VALUERANK_ANY;
30528 ret |= addNode(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
30529 requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PROPERTYTYPE),
30530 parentNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEVARIABLETYPE),
30531 referenceTypeId: UA_NODEID_NULL, browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "PropertyType"),
30532 typeDefinition: UA_NODEID_NULL, attr: &prop_attr,
30533 attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES], NULL, NULL);
30534
30535 /***************/
30536 /* ObjectTypes */
30537 /***************/
30538
30539 UA_ObjectTypeAttributes baseobj_attr = UA_ObjectTypeAttributes_default;
30540 baseobj_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BaseObjectType");
30541 ret |= ns0_addNode_raw(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
30542 UA_NS0ID_BASEOBJECTTYPE, name: "BaseObjectType",
30543 attributes: &baseobj_attr, attributesType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES]);
30544
30545 UA_ObjectTypeAttributes folder_attr = UA_ObjectTypeAttributes_default;
30546 folder_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "FolderType");
30547 ret |= addNode(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
30548 requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_FOLDERTYPE),
30549 parentNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEOBJECTTYPE),
30550 referenceTypeId: UA_NODEID_NULL, browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "FolderType"),
30551 typeDefinition: UA_NODEID_NULL,
30552 attr: &folder_attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES], NULL, NULL);
30553
30554 /******************/
30555 /* Root and below */
30556 /******************/
30557
30558 ret |= addObjectNode(server, name: "Root", UA_NS0ID_ROOTFOLDER, parentid: 0, referenceid: 0, UA_NS0ID_FOLDERTYPE);
30559
30560 ret |= addObjectNode(server, name: "Objects", UA_NS0ID_OBJECTSFOLDER, UA_NS0ID_ROOTFOLDER,
30561 UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
30562
30563 ret |= addObjectNode(server, name: "Types", UA_NS0ID_TYPESFOLDER, UA_NS0ID_ROOTFOLDER,
30564 UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
30565
30566 ret |= addObjectNode(server, name: "ReferenceTypes", UA_NS0ID_REFERENCETYPESFOLDER, UA_NS0ID_TYPESFOLDER,
30567 UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
30568 ret |= ns0_addNode_finish(server, UA_NS0ID_REFERENCES,
30569 UA_NS0ID_REFERENCETYPESFOLDER, UA_NS0ID_ORGANIZES);
30570
30571 ret |= addObjectNode(server, name: "DataTypes", UA_NS0ID_DATATYPESFOLDER, UA_NS0ID_TYPESFOLDER,
30572 UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
30573 ret |= ns0_addNode_finish(server, UA_NS0ID_BASEDATATYPE,
30574 UA_NS0ID_DATATYPESFOLDER, UA_NS0ID_ORGANIZES);
30575
30576 ret |= addObjectNode(server, name: "VariableTypes", UA_NS0ID_VARIABLETYPESFOLDER, UA_NS0ID_TYPESFOLDER,
30577 UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
30578 ret |= ns0_addNode_finish(server, UA_NS0ID_BASEVARIABLETYPE,
30579 UA_NS0ID_VARIABLETYPESFOLDER, UA_NS0ID_ORGANIZES);
30580
30581 ret |= addObjectNode(server, name: "ObjectTypes", UA_NS0ID_OBJECTTYPESFOLDER, UA_NS0ID_TYPESFOLDER,
30582 UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
30583 ret |= ns0_addNode_finish(server, UA_NS0ID_BASEOBJECTTYPE,
30584 UA_NS0ID_OBJECTTYPESFOLDER, UA_NS0ID_ORGANIZES);
30585
30586 ret |= addObjectNode(server, name: "EventTypes", UA_NS0ID_EVENTTYPESFOLDER, UA_NS0ID_TYPESFOLDER,
30587 UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
30588
30589 ret |= addObjectNode(server, name: "Views", UA_NS0ID_VIEWSFOLDER, UA_NS0ID_ROOTFOLDER,
30590 UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE);
30591
30592 /* Add BaseEventType */
30593 UA_ObjectTypeAttributes eventtype_attr = UA_ObjectTypeAttributes_default;
30594 eventtype_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BaseEventType");
30595 ret |= addNode(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
30596 requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEEVENTTYPE),
30597 parentNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEOBJECTTYPE),
30598 referenceTypeId: UA_NODEID_NULL, browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "BaseEventType"),
30599 typeDefinition: UA_NODEID_NULL,
30600 attr: &eventtype_attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES], NULL, NULL);
30601 ret |= addRef(server,
30602 sourceId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_EVENTTYPESFOLDER),
30603 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_ORGANIZES),
30604 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEEVENTTYPE), true);
30605
30606 if(ret != UA_STATUSCODE_GOOD)
30607 ret = UA_STATUSCODE_BADINTERNALERROR;
30608
30609 return ret;
30610}
30611
30612/****************/
30613/* Data Sources */
30614/****************/
30615
30616static UA_StatusCode
30617writeStatus(UA_Server *server, const UA_NodeId *sessionId,
30618 void *sessionContext, const UA_NodeId *nodeId,
30619 void *nodeContext, const UA_NumericRange *range,
30620 const UA_DataValue *value) {
30621 if(range)
30622 return UA_STATUSCODE_BADINDEXRANGEINVALID;
30623
30624 if(nodeId->identifier.numeric != UA_NS0ID_SERVER_SERVERSTATUS_SECONDSTILLSHUTDOWN)
30625 return UA_STATUSCODE_BADINTERNALERROR;
30626
30627 /* Only the local user can write into this variable */
30628 if(sessionId != &server->adminSession.sessionId)
30629 return UA_STATUSCODE_BADUSERACCESSDENIED;
30630
30631 if(!UA_Variant_hasScalarType(v: &value->value, type: &UA_TYPES[UA_TYPES_UINT32]))
30632 return UA_STATUSCODE_BADTYPEMISMATCH;
30633
30634 UA_UInt32 *endTime = (UA_UInt32*)value->value.data;
30635 server->endTime = UA_DateTime_now() + (UA_DateTime)(*endTime * UA_DATETIME_SEC);
30636 return UA_STATUSCODE_GOOD;
30637}
30638
30639static UA_StatusCode
30640readStatus(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
30641 const UA_NodeId *nodeId, void *nodeContext, UA_Boolean sourceTimestamp,
30642 const UA_NumericRange *range, UA_DataValue *value) {
30643 if(range) {
30644 value->hasStatus = true;
30645 value->status = UA_STATUSCODE_BADINDEXRANGEINVALID;
30646 return UA_STATUSCODE_GOOD;
30647 }
30648
30649 if(sourceTimestamp) {
30650 value->hasSourceTimestamp = true;
30651 value->sourceTimestamp = UA_DateTime_now();
30652 }
30653
30654 void *data = NULL;
30655
30656 UA_assert(nodeId->identifierType == UA_NODEIDTYPE_NUMERIC);
30657
30658 switch(nodeId->identifier.numeric) {
30659 case UA_NS0ID_SERVER_SERVERSTATUS_SECONDSTILLSHUTDOWN: {
30660 UA_UInt32 *shutdown = UA_UInt32_new();
30661 if(!shutdown)
30662 return UA_STATUSCODE_BADOUTOFMEMORY;
30663 if(server->endTime != 0)
30664 *shutdown = (UA_UInt32)((server->endTime - UA_DateTime_now()) / UA_DATETIME_SEC);
30665 value->value.data = shutdown;
30666 value->value.type = &UA_TYPES[UA_TYPES_UINT32];
30667 value->hasValue = true;
30668 return UA_STATUSCODE_GOOD;
30669 }
30670
30671 case UA_NS0ID_SERVER_SERVERSTATUS_STATE: {
30672 UA_ServerState *state = UA_ServerState_new();
30673 if(!state)
30674 return UA_STATUSCODE_BADOUTOFMEMORY;
30675 if(server->endTime != 0)
30676 *state = UA_SERVERSTATE_SHUTDOWN;
30677 value->value.data = state;
30678 value->value.type = &UA_TYPES[UA_TYPES_SERVERSTATE];
30679 value->hasValue = true;
30680 return UA_STATUSCODE_GOOD;
30681 }
30682
30683 case UA_NS0ID_SERVER_SERVERSTATUS: {
30684 UA_ServerStatusDataType *statustype = UA_ServerStatusDataType_new();
30685 if(!statustype)
30686 return UA_STATUSCODE_BADOUTOFMEMORY;
30687 statustype->startTime = server->startTime;
30688 statustype->currentTime = UA_DateTime_now();
30689
30690 statustype->state = UA_SERVERSTATE_RUNNING;
30691 statustype->secondsTillShutdown = 0;
30692 if(server->endTime != 0) {
30693 statustype->state = UA_SERVERSTATE_SHUTDOWN;
30694 statustype->secondsTillShutdown = (UA_UInt32)
30695 ((server->endTime - UA_DateTime_now()) / UA_DATETIME_SEC);
30696 }
30697
30698 value->value.data = statustype;
30699 value->value.type = &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE];
30700 value->hasValue = true;
30701 return UA_BuildInfo_copy(src: &server->config.buildInfo, dst: &statustype->buildInfo);
30702 }
30703
30704 case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO:
30705 value->value.type = &UA_TYPES[UA_TYPES_BUILDINFO];
30706 data = &server->config.buildInfo;
30707 break;
30708
30709 case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTURI:
30710 value->value.type = &UA_TYPES[UA_TYPES_STRING];
30711 data = &server->config.buildInfo.productUri;
30712 break;
30713
30714 case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_MANUFACTURERNAME:
30715 value->value.type = &UA_TYPES[UA_TYPES_STRING];
30716 data = &server->config.buildInfo.manufacturerName;
30717 break;
30718
30719 case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME:
30720 value->value.type = &UA_TYPES[UA_TYPES_STRING];
30721 data = &server->config.buildInfo.productName;
30722 break;
30723
30724 case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_SOFTWAREVERSION:
30725 value->value.type = &UA_TYPES[UA_TYPES_STRING];
30726 data = &server->config.buildInfo.softwareVersion;
30727 break;
30728
30729 case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDNUMBER:
30730 value->value.type = &UA_TYPES[UA_TYPES_STRING];
30731 data = &server->config.buildInfo.buildNumber;
30732 break;
30733
30734 case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDDATE:
30735 value->value.type = &UA_TYPES[UA_TYPES_DATETIME];
30736 data = &server->config.buildInfo.buildDate;
30737 break;
30738
30739 default:
30740 value->hasStatus = true;
30741 value->status = UA_STATUSCODE_BADINTERNALERROR;
30742 return UA_STATUSCODE_GOOD;
30743 }
30744
30745 value->value.data = UA_new(type: value->value.type);
30746 if(!value->value.data) {
30747 value->value.type = NULL;
30748 return UA_STATUSCODE_BADOUTOFMEMORY;
30749 }
30750
30751 value->hasValue = true;
30752 return UA_copy(src: data, dst: value->value.data, type: value->value.type);
30753}
30754
30755#ifdef UA_GENERATED_NAMESPACE_ZERO
30756static UA_StatusCode
30757readServiceLevel(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
30758 const UA_NodeId *nodeId, void *nodeContext, UA_Boolean includeSourceTimeStamp,
30759 const UA_NumericRange *range, UA_DataValue *value) {
30760 if(range) {
30761 value->hasStatus = true;
30762 value->status = UA_STATUSCODE_BADINDEXRANGEINVALID;
30763 return UA_STATUSCODE_GOOD;
30764 }
30765
30766 value->value.type = &UA_TYPES[UA_TYPES_BYTE];
30767 value->value.arrayLength = 0;
30768 UA_Byte *byte = UA_Byte_new();
30769 *byte = 255;
30770 value->value.data = byte;
30771 value->value.arrayDimensionsSize = 0;
30772 value->value.arrayDimensions = NULL;
30773 value->hasValue = true;
30774 if(includeSourceTimeStamp) {
30775 value->hasSourceTimestamp = true;
30776 value->sourceTimestamp = UA_DateTime_now();
30777 }
30778 return UA_STATUSCODE_GOOD;
30779}
30780
30781static UA_StatusCode
30782readAuditing(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
30783 const UA_NodeId *nodeId, void *nodeContext, UA_Boolean includeSourceTimeStamp,
30784 const UA_NumericRange *range, UA_DataValue *value) {
30785 if(range) {
30786 value->hasStatus = true;
30787 value->status = UA_STATUSCODE_BADINDEXRANGEINVALID;
30788 return UA_STATUSCODE_GOOD;
30789 }
30790
30791 value->value.type = &UA_TYPES[UA_TYPES_BOOLEAN];
30792 value->value.arrayLength = 0;
30793 UA_Boolean *boolean = UA_Boolean_new();
30794 *boolean = false;
30795 value->value.data = boolean;
30796 value->value.arrayDimensionsSize = 0;
30797 value->value.arrayDimensions = NULL;
30798 value->hasValue = true;
30799 if(includeSourceTimeStamp) {
30800 value->hasSourceTimestamp = true;
30801 value->sourceTimestamp = UA_DateTime_now();
30802 }
30803 return UA_STATUSCODE_GOOD;
30804}
30805#endif
30806
30807static UA_StatusCode
30808readNamespaces(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
30809 const UA_NodeId *nodeid, void *nodeContext, UA_Boolean includeSourceTimeStamp,
30810 const UA_NumericRange *range,
30811 UA_DataValue *value) {
30812 /* ensure that the uri for ns1 is set up from the app description */
30813 setupNs1Uri(server);
30814
30815 if(range) {
30816 value->hasStatus = true;
30817 value->status = UA_STATUSCODE_BADINDEXRANGEINVALID;
30818 return UA_STATUSCODE_GOOD;
30819 }
30820 UA_StatusCode retval;
30821 retval = UA_Variant_setArrayCopy(v: &value->value, array: server->namespaces,
30822 arraySize: server->namespacesSize, type: &UA_TYPES[UA_TYPES_STRING]);
30823 if(retval != UA_STATUSCODE_GOOD)
30824 return retval;
30825 value->hasValue = true;
30826 if(includeSourceTimeStamp) {
30827 value->hasSourceTimestamp = true;
30828 value->sourceTimestamp = UA_DateTime_now();
30829 }
30830 return UA_STATUSCODE_GOOD;
30831}
30832
30833static UA_StatusCode
30834writeNamespaces(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
30835 const UA_NodeId *nodeid, void *nodeContext, const UA_NumericRange *range,
30836 const UA_DataValue *value) {
30837 /* Check the data type */
30838 if(!value->hasValue ||
30839 value->value.type != &UA_TYPES[UA_TYPES_STRING])
30840 return UA_STATUSCODE_BADTYPEMISMATCH;
30841
30842 /* Check that the variant is not empty */
30843 if(!value->value.data)
30844 return UA_STATUSCODE_BADTYPEMISMATCH;
30845
30846 /* TODO: Writing with a range is not implemented */
30847 if(range)
30848 return UA_STATUSCODE_BADINTERNALERROR;
30849
30850 UA_String *newNamespaces = (UA_String*)value->value.data;
30851 size_t newNamespacesSize = value->value.arrayLength;
30852
30853 /* Test if we append to the existing namespaces */
30854 if(newNamespacesSize <= server->namespacesSize)
30855 return UA_STATUSCODE_BADTYPEMISMATCH;
30856
30857 /* ensure that the uri for ns1 is set up from the app description */
30858 setupNs1Uri(server);
30859
30860 /* Test if the existing namespaces are unchanged */
30861 for(size_t i = 0; i < server->namespacesSize; ++i) {
30862 if(!UA_String_equal(p1: &server->namespaces[i], p2: &newNamespaces[i]))
30863 return UA_STATUSCODE_BADINTERNALERROR;
30864 }
30865
30866 /* Add namespaces */
30867 for(size_t i = server->namespacesSize; i < newNamespacesSize; ++i)
30868 addNamespace(server, name: newNamespaces[i]);
30869 return UA_STATUSCODE_GOOD;
30870}
30871
30872static UA_StatusCode
30873readCurrentTime(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
30874 const UA_NodeId *nodeid, void *nodeContext, UA_Boolean sourceTimeStamp,
30875 const UA_NumericRange *range, UA_DataValue *value) {
30876 if(range) {
30877 value->hasStatus = true;
30878 value->status = UA_STATUSCODE_BADINDEXRANGEINVALID;
30879 return UA_STATUSCODE_GOOD;
30880 }
30881 UA_DateTime currentTime = UA_DateTime_now();
30882 UA_StatusCode retval = UA_Variant_setScalarCopy(v: &value->value, p: &currentTime,
30883 type: &UA_TYPES[UA_TYPES_DATETIME]);
30884 if(retval != UA_STATUSCODE_GOOD)
30885 return retval;
30886 value->hasValue = true;
30887 if(sourceTimeStamp) {
30888 value->hasSourceTimestamp = true;
30889 value->sourceTimestamp = currentTime;
30890 }
30891 return UA_STATUSCODE_GOOD;
30892}
30893
30894#ifdef UA_GENERATED_NAMESPACE_ZERO
30895static UA_StatusCode
30896readOperationLimits(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
30897 const UA_NodeId *nodeid, void *nodeContext, UA_Boolean includeSourceTimeStamp,
30898 const UA_NumericRange *range,
30899 UA_DataValue *value) {
30900 UA_StatusCode retval = UA_STATUSCODE_GOOD;
30901 if(nodeid->identifierType != UA_NODEIDTYPE_NUMERIC)
30902 return UA_STATUSCODE_BADNOTSUPPORTED;
30903 switch(nodeid->identifier.numeric) {
30904 case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREAD:
30905 retval = UA_Variant_setScalarCopy(v: &value->value, p: &server->config.maxNodesPerRead, type: &UA_TYPES[UA_TYPES_UINT32]);
30906 break;
30907 case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERWRITE:
30908 retval = UA_Variant_setScalarCopy(v: &value->value, p: &server->config.maxNodesPerWrite, type: &UA_TYPES[UA_TYPES_UINT32]);
30909 break;
30910 case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERMETHODCALL:
30911 retval = UA_Variant_setScalarCopy(v: &value->value, p: &server->config.maxNodesPerMethodCall, type: &UA_TYPES[UA_TYPES_UINT32]);
30912 break;
30913 case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERBROWSE:
30914 retval = UA_Variant_setScalarCopy(v: &value->value, p: &server->config.maxNodesPerBrowse, type: &UA_TYPES[UA_TYPES_UINT32]);
30915 break;
30916 case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREGISTERNODES:
30917 retval = UA_Variant_setScalarCopy(v: &value->value, p: &server->config.maxNodesPerRegisterNodes, type: &UA_TYPES[UA_TYPES_UINT32]);
30918 break;
30919 case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERTRANSLATEBROWSEPATHSTONODEIDS:
30920 retval = UA_Variant_setScalarCopy(v: &value->value, p: &server->config.maxNodesPerTranslateBrowsePathsToNodeIds, type: &UA_TYPES[UA_TYPES_UINT32]);
30921 break;
30922 case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERNODEMANAGEMENT:
30923 retval = UA_Variant_setScalarCopy(v: &value->value, p: &server->config.maxNodesPerNodeManagement, type: &UA_TYPES[UA_TYPES_UINT32]);
30924 break;
30925 case UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXMONITOREDITEMSPERCALL:
30926 retval = UA_Variant_setScalarCopy(v: &value->value, p: &server->config.maxMonitoredItemsPerCall, type: &UA_TYPES[UA_TYPES_UINT32]);
30927 break;
30928 default:
30929 retval = UA_STATUSCODE_BADNOTSUPPORTED;
30930 }
30931 return retval;
30932}
30933
30934static UA_StatusCode
30935readMinSamplingInterval(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
30936 const UA_NodeId *nodeid, void *nodeContext, UA_Boolean includeSourceTimeStamp,
30937 const UA_NumericRange *range,
30938 UA_DataValue *value) {
30939 if(range) {
30940 value->hasStatus = true;
30941 value->status = UA_STATUSCODE_BADINDEXRANGEINVALID;
30942 return UA_STATUSCODE_GOOD;
30943 }
30944
30945 UA_StatusCode retval;
30946 UA_Duration minInterval;
30947#ifdef UA_ENABLE_SUBSCRIPTIONS
30948 minInterval = server->config.samplingIntervalLimits.min;
30949#else
30950 minInterval = 0.0;
30951#endif
30952 retval = UA_Variant_setScalarCopy(v: &value->value, p: &minInterval, type: &UA_TYPES[UA_TYPES_DURATION]);
30953 if(retval != UA_STATUSCODE_GOOD)
30954 return retval;
30955 value->hasValue = true;
30956 if(includeSourceTimeStamp) {
30957 value->hasSourceTimestamp = true;
30958 value->sourceTimestamp = UA_DateTime_now();
30959 }
30960 return UA_STATUSCODE_GOOD;
30961}
30962#endif
30963
30964#if defined(UA_GENERATED_NAMESPACE_ZERO) && defined(UA_ENABLE_METHODCALLS) && defined(UA_ENABLE_SUBSCRIPTIONS)
30965static UA_StatusCode
30966resendData(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
30967 const UA_NodeId *methodId, void *methodContext, const UA_NodeId *objectId,
30968 void *objectContext, size_t inputSize, const UA_Variant *input,
30969 size_t outputSize, UA_Variant *output) {
30970 /* Get the input argument */
30971 if(inputSize != 1 ||
30972 !UA_Variant_hasScalarType(v: input, type: &UA_TYPES[UA_TYPES_UINT32]))
30973 return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
30974 UA_UInt32 subscriptionId = *((UA_UInt32*)(input[0].data));
30975
30976 /* Get the Session */
30977 lockServer(server);
30978 UA_Session *session = getSessionById(server, sessionId);
30979 if(!session) {
30980 unlockServer(server);
30981 return UA_STATUSCODE_BADINTERNALERROR;
30982 }
30983
30984 /* Get the Subscription */
30985 UA_Subscription *subscription = getSubscriptionById(server, subscriptionId);
30986 if(!subscription) {
30987 unlockServer(server);
30988 return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
30989 }
30990
30991 /* The Subscription is not attached to this Session */
30992 if(subscription->session != session) {
30993 unlockServer(server);
30994 return UA_STATUSCODE_BADUSERACCESSDENIED;
30995 }
30996
30997 UA_Subscription_resendData(server, sub: subscription);
30998
30999 unlockServer(server);
31000 return UA_STATUSCODE_GOOD;
31001}
31002static UA_StatusCode
31003readMonitoredItems(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
31004 const UA_NodeId *methodId, void *methodContext, const UA_NodeId *objectId,
31005 void *objectContext, size_t inputSize, const UA_Variant *input,
31006 size_t outputSize, UA_Variant *output) {
31007 /* Return two empty arrays by default */
31008 UA_Variant_setArray(v: &output[0], array: UA_Array_new(size: 0, type: &UA_TYPES[UA_TYPES_UINT32]),
31009 arraySize: 0, type: &UA_TYPES[UA_TYPES_UINT32]);
31010 UA_Variant_setArray(v: &output[1], array: UA_Array_new(size: 0, type: &UA_TYPES[UA_TYPES_UINT32]),
31011 arraySize: 0, type: &UA_TYPES[UA_TYPES_UINT32]);
31012
31013 lockServer(server);
31014
31015 /* Get the Session */
31016 UA_Session *session = getSessionById(server, sessionId);
31017 if(!session) {
31018 unlockServer(server);
31019 return UA_STATUSCODE_BADINTERNALERROR;
31020 }
31021 if(inputSize == 0 || !input[0].data) {
31022 unlockServer(server);
31023 return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
31024 }
31025
31026 /* Get the Subscription */
31027 UA_UInt32 subscriptionId = *((UA_UInt32*)(input[0].data));
31028 UA_Subscription *subscription = getSubscriptionById(server, subscriptionId);
31029 if(!subscription) {
31030 unlockServer(server);
31031 return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
31032 }
31033
31034 /* The Subscription is not attached to this Session */
31035 if(subscription->session != session) {
31036 unlockServer(server);
31037 return UA_STATUSCODE_BADUSERACCESSDENIED;
31038 }
31039
31040 /* Count the MonitoredItems */
31041 UA_UInt32 sizeOfOutput = 0;
31042 UA_MonitoredItem* monitoredItem;
31043 LIST_FOREACH(monitoredItem, &subscription->monitoredItems, listEntry) {
31044 ++sizeOfOutput;
31045 }
31046 if(sizeOfOutput == 0) {
31047 unlockServer(server);
31048 return UA_STATUSCODE_GOOD;
31049 }
31050
31051 /* Allocate the output arrays */
31052 UA_UInt32 *clientHandles = (UA_UInt32*)
31053 UA_Array_new(size: sizeOfOutput, type: &UA_TYPES[UA_TYPES_UINT32]);
31054 if(!clientHandles) {
31055 unlockServer(server);
31056 return UA_STATUSCODE_BADOUTOFMEMORY;
31057 }
31058 UA_UInt32 *serverHandles = (UA_UInt32*)
31059 UA_Array_new(size: sizeOfOutput, type: &UA_TYPES[UA_TYPES_UINT32]);
31060 if(!serverHandles) {
31061 unlockServer(server);
31062 UA_free(ptr: clientHandles);
31063 return UA_STATUSCODE_BADOUTOFMEMORY;
31064 }
31065
31066 /* Fill the array */
31067 UA_UInt32 i = 0;
31068 LIST_FOREACH(monitoredItem, &subscription->monitoredItems, listEntry) {
31069 clientHandles[i] = monitoredItem->parameters.clientHandle;
31070 serverHandles[i] = monitoredItem->monitoredItemId;
31071 ++i;
31072 }
31073 UA_Variant_setArray(v: &output[0], array: serverHandles, arraySize: sizeOfOutput, type: &UA_TYPES[UA_TYPES_UINT32]);
31074 UA_Variant_setArray(v: &output[1], array: clientHandles, arraySize: sizeOfOutput, type: &UA_TYPES[UA_TYPES_UINT32]);
31075
31076 unlockServer(server);
31077 return UA_STATUSCODE_GOOD;
31078}
31079#endif /* defined(UA_ENABLE_METHODCALLS) && defined(UA_ENABLE_SUBSCRIPTIONS) */
31080
31081static UA_StatusCode
31082writeNs0VariableArray(UA_Server *server, UA_UInt32 id, void *v,
31083 size_t length, const UA_DataType *type) {
31084 UA_Variant var;
31085 UA_Variant_init(p: &var);
31086 UA_Variant_setArray(v: &var, array: v, arraySize: length, type);
31087 return writeValueAttribute(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, identifier: id), value: &var);
31088}
31089
31090#ifdef UA_GENERATED_NAMESPACE_ZERO
31091static UA_StatusCode
31092writeNs0Variable(UA_Server *server, UA_UInt32 id, void *v, const UA_DataType *type) {
31093 UA_Variant var;
31094 UA_Variant_init(p: &var);
31095 UA_Variant_setScalar(v: &var, p: v, type);
31096 return writeValueAttribute(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, identifier: id), value: &var);
31097}
31098#endif
31099
31100#ifndef UA_GENERATED_NAMESPACE_ZERO
31101static UA_StatusCode
31102addVariableNode(UA_Server *server, char* name, UA_UInt32 variableid,
31103 UA_UInt32 parentid, UA_UInt32 referenceid,
31104 UA_Int32 valueRank, UA_UInt32 dataType) {
31105 UA_VariableAttributes attr = UA_VariableAttributes_default;
31106 attr.displayName = UA_LOCALIZEDTEXT("", name);
31107 attr.dataType = UA_NODEID_NUMERIC(0, dataType);
31108 attr.valueRank = valueRank;
31109 attr.accessLevel = UA_ACCESSLEVELMASK_READ;
31110 return addNode(server, UA_NODECLASS_VARIABLE, UA_NODEID_NUMERIC(0, variableid),
31111 UA_NODEID_NUMERIC(0, parentid), UA_NODEID_NUMERIC(0, referenceid),
31112 UA_QUALIFIEDNAME(0, name),
31113 UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
31114 &attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES], NULL, NULL);
31115}
31116
31117/* A minimal server object that is not complete and does not use the mandated
31118 * references to a server type. To be used on very constrained devices. */
31119static UA_StatusCode
31120minimalServerObject(UA_Server *server) {
31121 /* Server */
31122 UA_StatusCode retval = addObjectNode(server, "Server", UA_NS0ID_SERVER, UA_NS0ID_OBJECTSFOLDER,
31123 UA_NS0ID_ORGANIZES, UA_NS0ID_BASEOBJECTTYPE);
31124
31125 /* Use a valuerank of -2 for now. The array is added later on and the valuerank set to 1. */
31126 retval |= addVariableNode(server, "ServerArray", UA_NS0ID_SERVER_SERVERARRAY,
31127 UA_NS0ID_SERVER, UA_NS0ID_HASPROPERTY,
31128 UA_VALUERANK_ANY, UA_NS0ID_BASEDATATYPE);
31129
31130 retval |= addVariableNode(server, "NamespaceArray", UA_NS0ID_SERVER_NAMESPACEARRAY,
31131 UA_NS0ID_SERVER, UA_NS0ID_HASPROPERTY,
31132 UA_VALUERANK_ANY, UA_NS0ID_BASEDATATYPE);
31133
31134 retval |= addVariableNode(server, "ServerStatus", UA_NS0ID_SERVER_SERVERSTATUS,
31135 UA_NS0ID_SERVER, UA_NS0ID_HASCOMPONENT,
31136 UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
31137
31138 retval |= addVariableNode(server, "StartTime", UA_NS0ID_SERVER_SERVERSTATUS_STARTTIME,
31139 UA_NS0ID_SERVER_SERVERSTATUS, UA_NS0ID_HASCOMPONENT,
31140 UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
31141
31142 retval |= addVariableNode(server, "CurrentTime", UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME,
31143 UA_NS0ID_SERVER_SERVERSTATUS, UA_NS0ID_HASCOMPONENT,
31144 UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
31145
31146 retval |= addVariableNode(server, "State", UA_NS0ID_SERVER_SERVERSTATUS_STATE,
31147 UA_NS0ID_SERVER_SERVERSTATUS, UA_NS0ID_HASCOMPONENT,
31148 UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
31149
31150 retval |= addVariableNode(server, "BuildInfo", UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO,
31151 UA_NS0ID_SERVER_SERVERSTATUS, UA_NS0ID_HASCOMPONENT,
31152 UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
31153
31154 retval |= addVariableNode(server, "ProductUri", UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTURI,
31155 UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT,
31156 UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
31157
31158 retval |= addVariableNode(server, "ManufacturerName",
31159 UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_MANUFACTURERNAME,
31160 UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT,
31161 UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
31162
31163 retval |= addVariableNode(server, "ProductName",
31164 UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME,
31165 UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT,
31166 UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
31167
31168 retval |= addVariableNode(server, "SoftwareVersion",
31169 UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_SOFTWAREVERSION,
31170 UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT,
31171 UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
31172
31173 retval |= addVariableNode(server, "BuildNumber",
31174 UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDNUMBER,
31175 UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT,
31176 UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
31177
31178 retval |= addVariableNode(server, "BuildDate",
31179 UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDDATE,
31180 UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT,
31181 UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE);
31182
31183 return retval;
31184}
31185
31186#else
31187
31188static void
31189addModellingRules(UA_Server *server) {
31190 /* Test if the ModellingRules folder was added. (Only for the full ns0.) */
31191 UA_NodeId mrNodeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MODELLINGRULES);
31192 const UA_Node *mrnode = UA_NODESTORE_GET(server, nodeId: &mrNodeId);
31193 if(!mrnode)
31194 return;
31195 UA_NODESTORE_RELEASE(server, mrnode);
31196
31197 /* Add ExposesItsArray */
31198 addRef(server,
31199 sourceId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MODELLINGRULES),
31200 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
31201 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_MODELLINGRULE_EXPOSESITSARRAY), true);
31202
31203 /* Add Mandatory */
31204 addRef(server,
31205 sourceId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MODELLINGRULES),
31206 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
31207 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_MODELLINGRULE_MANDATORY), true);
31208
31209
31210 /* Add MandatoryPlaceholder */
31211 addRef(server,
31212 sourceId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MODELLINGRULES),
31213 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
31214 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_MODELLINGRULE_MANDATORYPLACEHOLDER), true);
31215
31216 /* Add Optional */
31217 addRef(server,
31218 sourceId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MODELLINGRULES),
31219 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
31220 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_MODELLINGRULE_OPTIONAL), true);
31221
31222 /* Add OptionalPlaceholder */
31223 addRef(server,
31224 sourceId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MODELLINGRULES),
31225 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
31226 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_MODELLINGRULE_OPTIONALPLACEHOLDER), true);
31227}
31228
31229#endif
31230
31231/* Initialize the nodeset 0 by using the generated code of the nodeset compiler.
31232 * This also initialized the data sources for various variables, such as for
31233 * example server time. */
31234UA_StatusCode
31235initNS0(UA_Server *server) {
31236 UA_LOCK_ASSERT(&server->serviceMutex, 1);
31237
31238 /* Initialize base nodes which are always required an cannot be created
31239 * through the NS compiler */
31240 server->bootstrapNS0 = true;
31241 UA_StatusCode retVal = createNS0_base(server);
31242
31243#ifdef UA_GENERATED_NAMESPACE_ZERO
31244 /* Load nodes and references generated from the XML ns0 definition */
31245 retVal |= namespace0_generated(server);
31246#else
31247 /* Create a minimal server object */
31248 retVal |= minimalServerObject(server);
31249#endif
31250
31251 server->bootstrapNS0 = false;
31252
31253 if(retVal != UA_STATUSCODE_GOOD) {
31254 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
31255 msg: "Initialization of Namespace 0 failed with %s. "
31256 "See previous outputs for any error messages.",
31257 UA_StatusCode_name(code: retVal));
31258 return UA_STATUSCODE_BADINTERNALERROR;
31259 }
31260
31261 /* NamespaceArray */
31262 UA_DataSource namespaceDataSource = {readNamespaces, writeNamespaces};
31263 retVal |= setVariableNode_dataSource(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_NAMESPACEARRAY),
31264 dataSource: namespaceDataSource);
31265 retVal |= writeValueRankAttribute(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_NAMESPACEARRAY), value: 1);
31266
31267 /* ServerArray */
31268 retVal |= writeNs0VariableArray(server, UA_NS0ID_SERVER_SERVERARRAY,
31269 v: &server->config.applicationDescription.applicationUri,
31270 length: 1, type: &UA_TYPES[UA_TYPES_STRING]);
31271 retVal |= writeValueRankAttribute(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERARRAY), value: 1);
31272
31273 /* ServerStatus */
31274 UA_DataSource serverStatus = {readStatus, writeStatus};
31275 retVal |= setVariableNode_dataSource(server,
31276 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS), dataSource: serverStatus);
31277
31278 /* StartTime will be sampled in UA_Server_run_startup()*/
31279
31280 /* CurrentTime */
31281 UA_DataSource currentTime = {readCurrentTime, NULL};
31282 UA_NodeId currTime = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);
31283 retVal |= setVariableNode_dataSource(server, nodeId: currTime, dataSource: currentTime);
31284 retVal |= writeMinimumSamplingIntervalAttribute(server, nodeId: currTime, value: 100.0);
31285
31286 /* State */
31287 retVal |= setVariableNode_dataSource(server,
31288 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS_STATE), dataSource: serverStatus);
31289
31290 /* BuildInfo */
31291 retVal |= setVariableNode_dataSource(server,
31292 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO), dataSource: serverStatus);
31293
31294 /* BuildInfo - ProductUri */
31295 retVal |= setVariableNode_dataSource(server,
31296 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTURI),
31297 dataSource: serverStatus);
31298
31299 /* BuildInfo - ManufacturerName */
31300 retVal |= setVariableNode_dataSource(server,
31301 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_MANUFACTURERNAME),
31302 dataSource: serverStatus);
31303
31304 /* BuildInfo - ProductName */
31305 retVal |= setVariableNode_dataSource(server,
31306 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME),
31307 dataSource: serverStatus);
31308
31309 /* BuildInfo - SoftwareVersion */
31310 retVal |= setVariableNode_dataSource(server,
31311 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_SOFTWAREVERSION),
31312 dataSource: serverStatus);
31313
31314 /* BuildInfo - BuildNumber */
31315 retVal |= setVariableNode_dataSource(server,
31316 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDNUMBER),
31317 dataSource: serverStatus);
31318
31319 /* BuildInfo - BuildDate */
31320 retVal |= setVariableNode_dataSource(server,
31321 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDDATE),
31322 dataSource: serverStatus);
31323
31324#ifdef UA_GENERATED_NAMESPACE_ZERO
31325
31326 /* SecondsTillShutdown */
31327 retVal |= setVariableNode_dataSource(server,
31328 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS_SECONDSTILLSHUTDOWN),
31329 dataSource: serverStatus);
31330
31331 /* ShutDownReason */
31332 UA_LocalizedText shutdownReason;
31333 UA_LocalizedText_init(p: &shutdownReason);
31334 retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERSTATUS_SHUTDOWNREASON,
31335 v: &shutdownReason, type: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
31336
31337 /* ServiceLevel */
31338 UA_DataSource serviceLevel = {readServiceLevel, NULL};
31339 retVal |= setVariableNode_dataSource(server,
31340 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVICELEVEL), dataSource: serviceLevel);
31341
31342 /* ServerDiagnostics - EnabledFlag */
31343#ifdef UA_ENABLE_DIAGNOSTICS
31344 UA_Boolean enabledFlag = true;
31345#else
31346 UA_Boolean enabledFlag = false;
31347#endif
31348 retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_ENABLEDFLAG,
31349 v: &enabledFlag, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
31350
31351 /* According to Specification part-5 - pg.no-11(PDF pg.no-29), when the ServerDiagnostics is disabled the client
31352 * may modify the value of enabledFlag=true in the server. By default, this node have CurrentRead/Write access.
31353 * In CTT, Subscription_Minimum_1/002.js test will modify the above flag. This will not be a problem when build
31354 * configuration is set at UA_NAMESPACE_ZERO="REDUCED" as NodeIds will not be present. When UA_NAMESPACE_ZERO="FULL",
31355 * the test will fail. Hence made the NodeId as read only */
31356 retVal |= writeAccessLevelAttribute(server,
31357 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_ENABLEDFLAG),
31358 UA_ACCESSLEVELMASK_READ);
31359
31360 /* Auditing */
31361 UA_DataSource auditing = {readAuditing, NULL};
31362 retVal |= setVariableNode_dataSource(server,
31363 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_AUDITING), dataSource: auditing);
31364
31365 /* Redundancy Support */
31366 UA_RedundancySupport redundancySupport = UA_REDUNDANCYSUPPORT_NONE;
31367 retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERREDUNDANCY_REDUNDANCYSUPPORT,
31368 v: &redundancySupport, type: &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT]);
31369 /* Remove unused subtypes of ServerRedundancy */
31370 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERREDUNDANCY_CURRENTSERVERID), true);
31371 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERREDUNDANCY_REDUNDANTSERVERARRAY), true);
31372 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERREDUNDANCY_SERVERURIARRAY), true);
31373 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERREDUNDANCY_SERVERNETWORKGROUPS), true);
31374 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_CONFORMANCEUNITS), true);
31375 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_URISVERSION), true);
31376 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_CONFORMANCEUNITS), true);
31377 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXMONITOREDITEMS), true);
31378 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXMONITOREDITEMSPERSUBSCRIPTION), true);
31379 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXMONITOREDITEMSQUEUESIZE), true);
31380 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXSELECTCLAUSEPARAMETERS), true);
31381 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXSESSIONS), true);
31382 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXSUBSCRIPTIONS), true);
31383 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXSUBSCRIPTIONSPERSESSION), true);
31384 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXWHERECLAUSEPARAMETERS), true);
31385
31386 /* ServerCapabilities - LocaleIdArray */
31387 UA_LocaleId locale_en = UA_STRING(chars: "en");
31388 retVal |= writeNs0VariableArray(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_LOCALEIDARRAY,
31389 v: &locale_en, length: 1, type: &UA_TYPES[UA_TYPES_LOCALEID]);
31390
31391 /* ServerCapabilities - MaxBrowseContinuationPoints */
31392 UA_UInt16 maxBrowseContinuationPoints = UA_MAXCONTINUATIONPOINTS;
31393 retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXBROWSECONTINUATIONPOINTS,
31394 v: &maxBrowseContinuationPoints, type: &UA_TYPES[UA_TYPES_UINT16]);
31395
31396 /* ServerProfileArray */
31397 UA_String profileArray[3];
31398 UA_UInt16 profileArraySize = 0;
31399#define ADDPROFILEARRAY(x) profileArray[profileArraySize++] = UA_STRING(x)
31400 ADDPROFILEARRAY("http://opcfoundation.org/UA-Profile/Server/StandardUA2017");
31401#ifdef UA_ENABLE_NODEMANAGEMENT
31402 ADDPROFILEARRAY("http://opcfoundation.org/UA-Profile/Server/NodeManagement");
31403#endif
31404#ifdef UA_ENABLE_METHODCALLS
31405 ADDPROFILEARRAY("http://opcfoundation.org/UA-Profile/Server/Methods");
31406#endif
31407 retVal |= writeNs0VariableArray(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_SERVERPROFILEARRAY,
31408 v: profileArray, length: profileArraySize, type: &UA_TYPES[UA_TYPES_STRING]);
31409
31410 /* ServerCapabilities - MaxQueryContinuationPoints */
31411 UA_UInt16 maxQueryContinuationPoints = 0;
31412 retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXQUERYCONTINUATIONPOINTS,
31413 v: &maxQueryContinuationPoints, type: &UA_TYPES[UA_TYPES_UINT16]);
31414
31415 /* ServerCapabilities - MaxHistoryContinuationPoints */
31416 UA_UInt16 maxHistoryContinuationPoints = 0;
31417 retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXHISTORYCONTINUATIONPOINTS,
31418 v: &maxHistoryContinuationPoints, type: &UA_TYPES[UA_TYPES_UINT16]);
31419
31420 /* ServerCapabilities - MinSupportedSampleRate */
31421 UA_DataSource samplingInterval = {readMinSamplingInterval, NULL};
31422 retVal |= setVariableNode_dataSource(server,
31423 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MINSUPPORTEDSAMPLERATE),
31424 dataSource: samplingInterval);
31425
31426 /* ServerCapabilities - OperationLimits - MaxNodesPerRead */
31427 UA_DataSource operationLimitRead = {readOperationLimits, NULL};
31428 retVal |= setVariableNode_dataSource(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREAD),
31429 dataSource: operationLimitRead);
31430
31431 /* ServerCapabilities - OperationLimits - maxNodesPerWrite */
31432 retVal |= setVariableNode_dataSource(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERWRITE),
31433 dataSource: operationLimitRead);
31434
31435 /* ServerCapabilities - OperationLimits - MaxNodesPerMethodCall */
31436 retVal |= setVariableNode_dataSource(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERMETHODCALL),
31437 dataSource: operationLimitRead);
31438
31439 /* ServerCapabilities - OperationLimits - MaxNodesPerBrowse */
31440 retVal |= setVariableNode_dataSource(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERBROWSE),
31441 dataSource: operationLimitRead);
31442
31443 /* ServerCapabilities - OperationLimits - MaxNodesPerRegisterNodes */
31444 retVal |= setVariableNode_dataSource(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREGISTERNODES),
31445 dataSource: operationLimitRead);
31446
31447 /* ServerCapabilities - OperationLimits - MaxNodesPerTranslateBrowsePathsToNodeIds */
31448 retVal |= setVariableNode_dataSource(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERTRANSLATEBROWSEPATHSTONODEIDS),
31449 dataSource: operationLimitRead);
31450
31451 /* ServerCapabilities - OperationLimits - MaxNodesPerNodeManagement */
31452 retVal |= setVariableNode_dataSource(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERNODEMANAGEMENT),
31453 dataSource: operationLimitRead);
31454
31455 /* ServerCapabilities - OperationLimits - MaxMonitoredItemsPerCall */
31456 retVal |= setVariableNode_dataSource(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXMONITOREDITEMSPERCALL),
31457 dataSource: operationLimitRead);
31458
31459 /* Remove unused operation limit components */
31460 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYREADDATA), true);
31461 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYREADEVENTS), true);
31462 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYUPDATEDATA), true);
31463 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYUPDATEEVENTS), true);
31464 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_ROLESET), true);
31465 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXSTRINGLENGTH), true);
31466 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXARRAYLENGTH), true);
31467 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXBYTESTRINGLENGTH), true);
31468
31469 /* Remove not supported server configurations */
31470 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_ESTIMATEDRETURNTIME), true);
31471 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_LOCALTIME), true);
31472 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_REQUESTSERVERSTATECHANGE), true);
31473 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVERCONFIGURATION), true);
31474 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SETSUBSCRIPTIONDURABLE), true);
31475
31476#ifdef UA_ENABLE_DIAGNOSTICS
31477 /* ServerDiagnostics - ServerDiagnosticsSummary */
31478 UA_DataSource serverDiagSummary = {readDiagnostics, NULL};
31479 retVal |= setVariableNode_dataSource(server,
31480 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY), dataSource: serverDiagSummary);
31481
31482 /* ServerDiagnostics - ServerDiagnosticsSummary - ServerViewCount */
31483 retVal |= setVariableNode_dataSource(server,
31484 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SERVERVIEWCOUNT), dataSource: serverDiagSummary);
31485
31486 /* ServerDiagnostics - ServerDiagnosticsSummary - CurrentSessionCount */
31487 retVal |= setVariableNode_dataSource(server,
31488 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CURRENTSESSIONCOUNT), dataSource: serverDiagSummary);
31489
31490 /* ServerDiagnostics - ServerDiagnosticsSummary - CumulatedSessionCount */
31491 retVal |= setVariableNode_dataSource(server,
31492 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CUMULATEDSESSIONCOUNT), dataSource: serverDiagSummary);
31493
31494 /* ServerDiagnostics - ServerDiagnosticsSummary - SecurityRejectedSessionCount */
31495 retVal |= setVariableNode_dataSource(server,
31496 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SECURITYREJECTEDSESSIONCOUNT), dataSource: serverDiagSummary);
31497
31498 /* ServerDiagnostics - ServerDiagnosticsSummary - RejectedSessionCount */
31499 retVal |= setVariableNode_dataSource(server,
31500 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_REJECTEDSESSIONCOUNT), dataSource: serverDiagSummary);
31501
31502 /* ServerDiagnostics - ServerDiagnosticsSummary - SessionTimeoutCount */
31503 retVal |= setVariableNode_dataSource(server,
31504 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SESSIONTIMEOUTCOUNT), dataSource: serverDiagSummary);
31505
31506 /* ServerDiagnostics - ServerDiagnosticsSummary - SessionAbortCount */
31507 retVal |= setVariableNode_dataSource(server,
31508 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SESSIONABORTCOUNT), dataSource: serverDiagSummary);
31509
31510 /* ServerDiagnostics - ServerDiagnosticsSummary - CurrentSubscriptionCount */
31511 retVal |= setVariableNode_dataSource(server,
31512 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CURRENTSUBSCRIPTIONCOUNT), dataSource: serverDiagSummary);
31513
31514 /* ServerDiagnostics - ServerDiagnosticsSummary - CumulatedSubscriptionCount */
31515 retVal |= setVariableNode_dataSource(server,
31516 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CUMULATEDSUBSCRIPTIONCOUNT), dataSource: serverDiagSummary);
31517
31518 /* ServerDiagnostics - ServerDiagnosticsSummary - PublishingIntervalCount */
31519 retVal |= setVariableNode_dataSource(server,
31520 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_PUBLISHINGINTERVALCOUNT), dataSource: serverDiagSummary);
31521
31522 /* ServerDiagnostics - ServerDiagnosticsSummary - SecurityRejectedRequestsCount */
31523 retVal |= setVariableNode_dataSource(server,
31524 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SECURITYREJECTEDREQUESTSCOUNT), dataSource: serverDiagSummary);
31525
31526 /* ServerDiagnostics - ServerDiagnosticsSummary - RejectedRequestsCount */
31527 retVal |= setVariableNode_dataSource(server,
31528 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_REJECTEDREQUESTSCOUNT), dataSource: serverDiagSummary);
31529
31530 /* ServerDiagnostics - SubscriptionDiagnosticsArray */
31531#ifdef UA_ENABLE_SUBSCRIPTIONS
31532 UA_DataSource serverSubDiagSummary = {readSubscriptionDiagnosticsArray, NULL};
31533 retVal |= setVariableNode_dataSource(server,
31534 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SUBSCRIPTIONDIAGNOSTICSARRAY), dataSource: serverSubDiagSummary);
31535#endif
31536
31537 /* ServerDiagnostics - SessionDiagnosticsSummary - SessionDiagnosticsArray */
31538 UA_DataSource sessionDiagSummary = {readSessionDiagnosticsArray, NULL};
31539 retVal |= setVariableNode_dataSource(server,
31540 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY_SESSIONDIAGNOSTICSARRAY), dataSource: sessionDiagSummary);
31541
31542 /* ServerDiagnostics - SessionDiagnosticsSummary - SessionSecurityDiagnosticsArray */
31543 UA_DataSource sessionSecDiagSummary = {readSessionSecurityDiagnostics, NULL};
31544 retVal |= setVariableNode_dataSource(server,
31545 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY_SESSIONSECURITYDIAGNOSTICSARRAY), dataSource: sessionSecDiagSummary);
31546
31547#else
31548 /* Removing these NodeIds make Server Object to be non-complaint with UA
31549 * 1.03 in CTT (Base Inforamtion/Base Info Core Structure/ 001.js) In the
31550 * 1.04 specification this has been resolved by allowing to remove these
31551 * static nodes as well */
31552 deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY), true);
31553 deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY), true);
31554 deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SUBSCRIPTIONDIAGNOSTICSARRAY), true);
31555#endif
31556
31557 /* The sampling diagnostics array is optional
31558 * TODO: Add support for this diagnostics */
31559 deleteNode(server, nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SAMPLINGINTERVALDIAGNOSTICSARRAY), true);
31560
31561#ifndef UA_ENABLE_PUBSUB
31562 deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE), true);
31563#endif
31564
31565#ifndef UA_ENABLE_HISTORIZING
31566 deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_HISTORYSERVERCAPABILITIES), true);
31567#else
31568 /* ServerCapabilities - HistoryServerCapabilities - AccessHistoryDataCapability */
31569 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_ACCESSHISTORYDATACAPABILITY,
31570 v: &server->config.accessHistoryDataCapability, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
31571
31572 /* ServerCapabilities - HistoryServerCapabilities - MaxReturnDataValues */
31573 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_MAXRETURNDATAVALUES,
31574 v: &server->config.maxReturnDataValues, type: &UA_TYPES[UA_TYPES_UINT32]);
31575
31576 /* ServerCapabilities - HistoryServerCapabilities - AccessHistoryEventsCapability */
31577 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_ACCESSHISTORYEVENTSCAPABILITY,
31578 v: &server->config.accessHistoryEventsCapability, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
31579
31580 /* ServerCapabilities - HistoryServerCapabilities - MaxReturnEventValues */
31581 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_MAXRETURNEVENTVALUES,
31582 v: &server->config.maxReturnEventValues, type: &UA_TYPES[UA_TYPES_UINT32]);
31583
31584 /* ServerCapabilities - HistoryServerCapabilities - InsertDataCapability */
31585 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_INSERTDATACAPABILITY,
31586 v: &server->config.insertDataCapability, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
31587
31588 /* ServerCapabilities - HistoryServerCapabilities - InsertEventCapability */
31589 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_INSERTEVENTCAPABILITY,
31590 v: &server->config.insertEventCapability, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
31591
31592 /* ServerCapabilities - HistoryServerCapabilities - InsertAnnotationsCapability */
31593 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_INSERTANNOTATIONCAPABILITY,
31594 v: &server->config.insertAnnotationsCapability, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
31595
31596 /* ServerCapabilities - HistoryServerCapabilities - ReplaceDataCapability */
31597 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_REPLACEDATACAPABILITY,
31598 v: &server->config.replaceDataCapability, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
31599
31600 /* ServerCapabilities - HistoryServerCapabilities - ReplaceEventCapability */
31601 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_REPLACEEVENTCAPABILITY,
31602 v: &server->config.replaceEventCapability, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
31603
31604 /* ServerCapabilities - HistoryServerCapabilities - UpdateDataCapability */
31605 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_UPDATEDATACAPABILITY,
31606 v: &server->config.updateDataCapability, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
31607
31608 /* ServerCapabilities - HistoryServerCapabilities - UpdateEventCapability */
31609 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_UPDATEEVENTCAPABILITY,
31610 v: &server->config.updateEventCapability, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
31611
31612 /* ServerCapabilities - HistoryServerCapabilities - DeleteRawCapability */
31613 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_DELETERAWCAPABILITY,
31614 v: &server->config.deleteRawCapability, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
31615
31616 /* ServerCapabilities - HistoryServerCapabilities - DeleteEventCapability */
31617 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_DELETEEVENTCAPABILITY,
31618 v: &server->config.deleteEventCapability, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
31619
31620 /* ServerCapabilities - HistoryServerCapabilities - DeleteAtTimeDataCapability */
31621 retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_DELETEATTIMECAPABILITY,
31622 v: &server->config.deleteAtTimeDataCapability, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
31623#endif
31624
31625#if defined(UA_ENABLE_METHODCALLS) && defined(UA_ENABLE_SUBSCRIPTIONS)
31626 retVal |= setMethodNode_callback(server,
31627 methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_GETMONITOREDITEMS),
31628 methodCallback: readMonitoredItems);
31629
31630 retVal |= setMethodNode_callback(server,
31631 methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_RESENDDATA),
31632 methodCallback: resendData);
31633#endif
31634
31635 /* The HasComponent references to the ModellingRules are not part of the
31636 * Nodeset2.xml. So we add the references manually. */
31637 addModellingRules(server);
31638
31639#endif /* UA_GENERATED_NAMESPACE_ZERO */
31640
31641 if(retVal != UA_STATUSCODE_GOOD) {
31642 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
31643 msg: "Initialization of Namespace 0 (after bootstrapping) "
31644 "failed with %s. See previous outputs for any error messages.",
31645 UA_StatusCode_name(code: retVal));
31646 return UA_STATUSCODE_BADINTERNALERROR;
31647 }
31648 return UA_STATUSCODE_GOOD;
31649}
31650
31651/**** amalgamated original file "/src/server/ua_server_ns0_diagnostics.c" ****/
31652
31653/* This Source Code Form is subject to the terms of the Mozilla Public
31654 * License, v. 2.0. If a copy of the MPL was not distributed with this
31655 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
31656 *
31657 * Copyright 2022 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
31658 */
31659
31660
31661#ifdef UA_ENABLE_DIAGNOSTICS
31662
31663static UA_Boolean
31664equalBrowseName(UA_String *bn, char *n) {
31665 UA_String name = UA_STRING(chars: n);
31666 return UA_String_equal(p1: bn, p2: &name);
31667}
31668
31669#ifdef UA_ENABLE_SUBSCRIPTIONS
31670
31671/****************************/
31672/* Subscription Diagnostics */
31673/****************************/
31674
31675static void
31676fillSubscriptionDiagnostics(UA_Subscription *sub,
31677 UA_SubscriptionDiagnosticsDataType *diag) {
31678 UA_NodeId_copy(src: &sub->session->sessionId, dst: &diag->sessionId); /* ignore status */
31679 diag->subscriptionId = sub->subscriptionId;
31680 diag->priority = sub->priority;
31681 diag->publishingInterval = sub->publishingInterval;
31682 diag->maxKeepAliveCount = sub->maxKeepAliveCount;
31683 diag->maxLifetimeCount = sub->lifeTimeCount;
31684 diag->maxNotificationsPerPublish = sub->notificationsPerPublish;
31685 diag->publishingEnabled = (sub->state > UA_SUBSCRIPTIONSTATE_ENABLED_NOPUBLISH);
31686 diag->modifyCount = sub->modifyCount;
31687 diag->enableCount = sub->enableCount;
31688 diag->disableCount = sub->disableCount;
31689 diag->republishRequestCount = sub->republishRequestCount;
31690 diag->republishMessageRequestCount =
31691 sub->republishRequestCount; /* Always equal to the previous republishRequestCount */
31692 diag->republishMessageCount = sub->republishMessageCount;
31693 diag->transferRequestCount = sub->transferRequestCount;
31694 diag->transferredToAltClientCount = sub->transferredToAltClientCount;
31695 diag->transferredToSameClientCount = sub->transferredToSameClientCount;
31696 diag->publishRequestCount = sub->publishRequestCount;
31697 diag->dataChangeNotificationsCount = sub->dataChangeNotificationsCount;
31698 diag->eventNotificationsCount = sub->eventNotificationsCount;
31699 diag->notificationsCount = sub->notificationsCount;
31700 diag->latePublishRequestCount = sub->latePublishRequestCount;
31701 diag->currentKeepAliveCount = sub->currentKeepAliveCount;
31702 diag->currentLifetimeCount = sub->currentLifetimeCount;
31703 diag->unacknowledgedMessageCount = (UA_UInt32)sub->retransmissionQueueSize;
31704 diag->discardedMessageCount = sub->discardedMessageCount;
31705 diag->monitoredItemCount = sub->monitoredItemsSize;
31706 diag->monitoringQueueOverflowCount = sub->monitoringQueueOverflowCount;
31707 diag->nextSequenceNumber = sub->nextSequenceNumber;
31708 diag->eventQueueOverFlowCount = sub->eventQueueOverFlowCount;
31709
31710 /* Count the disabled MonitoredItems */
31711 UA_MonitoredItem *mon;
31712 LIST_FOREACH(mon, &sub->monitoredItems, listEntry) {
31713 if(mon->monitoringMode == UA_MONITORINGMODE_DISABLED)
31714 diag->disabledMonitoredItemCount++;
31715 }
31716}
31717
31718/* The node context points to the subscription */
31719static UA_StatusCode
31720readSubscriptionDiagnostics(UA_Server *server,
31721 const UA_NodeId *sessionId, void *sessionContext,
31722 const UA_NodeId *nodeId, void *nodeContext,
31723 UA_Boolean sourceTimestamp,
31724 const UA_NumericRange *range, UA_DataValue *value) {
31725 /* Check the Subscription pointer */
31726 UA_Subscription *sub = (UA_Subscription*)nodeContext;
31727 if(!sub)
31728 return UA_STATUSCODE_BADINTERNALERROR;
31729
31730 /* Read the BrowseName */
31731 UA_QualifiedName bn;
31732 UA_StatusCode res = UA_Server_readBrowseName(server, nodeId: *nodeId, outBrowseName: &bn);
31733 if(res != UA_STATUSCODE_GOOD)
31734 return res;
31735
31736 /* Set the value */
31737 UA_SubscriptionDiagnosticsDataType sddt;
31738 UA_SubscriptionDiagnosticsDataType_init(p: &sddt);
31739 fillSubscriptionDiagnostics(sub, diag: &sddt);
31740
31741 char memberName[128];
31742 memcpy(dest: memberName, src: bn.name.data, n: bn.name.length);
31743 memberName[bn.name.length] = 0;
31744
31745 size_t memberOffset;
31746 const UA_DataType *memberType;
31747 UA_Boolean isArray;
31748 UA_Boolean found =
31749 UA_DataType_getStructMember(type: &UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE],
31750 memberName, outOffset: &memberOffset, outMemberType: &memberType, outIsArray: &isArray);
31751 if(!found) {
31752 /* Not the member, but the main subscription diagnostics variable... */
31753 memberOffset = 0;
31754 memberType = &UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE];
31755 }
31756
31757 void *content = (void*)(((uintptr_t)&sddt) + memberOffset);
31758 res = UA_Variant_setScalarCopy(v: &value->value, p: content, type: memberType);
31759 if(UA_LIKELY(res == UA_STATUSCODE_GOOD))
31760 value->hasValue = true;
31761
31762 UA_SubscriptionDiagnosticsDataType_clear(p: &sddt);
31763 UA_QualifiedName_clear(p: &bn);
31764 return res;
31765}
31766
31767/* Return all subscriptions in the server. */
31768UA_StatusCode
31769readSubscriptionDiagnosticsArray(UA_Server *server,
31770 const UA_NodeId *sessionId, void *sessionContext,
31771 const UA_NodeId *nodeId, void *nodeContext,
31772 UA_Boolean sourceTimestamp,
31773 const UA_NumericRange *range, UA_DataValue *value) {
31774 lockServer(server);
31775
31776 /* Get the current session */
31777 size_t sdSize = 0;
31778 session_list_entry *sentry;
31779 LIST_FOREACH(sentry, &server->sessions, pointers) {
31780 sdSize += sentry->session.subscriptionsSize;
31781 }
31782
31783 /* Allocate the output array */
31784 UA_SubscriptionDiagnosticsDataType *sd = (UA_SubscriptionDiagnosticsDataType*)
31785 UA_Array_new(size: sdSize, type: &UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE]);
31786 if(!sd) {
31787 unlockServer(server);
31788 return UA_STATUSCODE_BADOUTOFMEMORY;
31789 }
31790
31791 /* Collect the statistics */
31792 size_t i = 0;
31793 UA_Subscription *sub;
31794 LIST_FOREACH(sentry, &server->sessions, pointers) {
31795 TAILQ_FOREACH(sub, &sentry->session.subscriptions, sessionListEntry) {
31796 fillSubscriptionDiagnostics(sub, diag: &sd[i]);
31797 i++;
31798 }
31799 }
31800
31801 /* Set the output */
31802 value->hasValue = true;
31803 UA_Variant_setArray(v: &value->value, array: sd, arraySize: sdSize,
31804 type: &UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE]);
31805
31806 unlockServer(server);
31807 return UA_STATUSCODE_GOOD;
31808}
31809
31810void
31811createSubscriptionObject(UA_Server *server, UA_Session *session,
31812 UA_Subscription *sub) {
31813 UA_ExpandedNodeId *children = NULL;
31814 size_t childrenSize = 0;
31815 UA_ReferenceTypeSet refTypes;
31816 UA_NodeId hasComponent = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT);
31817
31818 char subIdStr[32];
31819 itoaUnsigned(value: sub->subscriptionId, buffer: subIdStr, base: 10);
31820
31821 /* Find the NodeId of the SubscriptionDiagnosticsArray */
31822 UA_BrowsePath bp;
31823 UA_BrowsePath_init(p: &bp);
31824 bp.startingNode = sub->session->sessionId;
31825 UA_RelativePathElement rpe[1];
31826 memset(s: rpe, c: 0, n: sizeof(UA_RelativePathElement) * 1);
31827 rpe[0].targetName = UA_QUALIFIEDNAME(nsIndex: 0, chars: "SubscriptionDiagnosticsArray");
31828 bp.relativePath.elements = rpe;
31829 bp.relativePath.elementsSize = 1;
31830 UA_BrowsePathResult bpr = translateBrowsePathToNodeIds(server, browsePath: &bp);
31831 if(bpr.targetsSize < 1)
31832 return;
31833
31834 /* Create an object for the subscription. Instantiates all the mandatory
31835 * children. */
31836 UA_VariableAttributes var_attr = UA_VariableAttributes_default;
31837 var_attr.displayName.text = UA_STRING(chars: subIdStr);
31838 var_attr.dataType = UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE].typeId;
31839 UA_NodeId refId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT);
31840 UA_QualifiedName browseName = UA_QUALIFIEDNAME(nsIndex: 0, chars: subIdStr);
31841 UA_NodeId typeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE);
31842 /* Assign a random free NodeId */
31843 UA_StatusCode res = addNode(server, nodeClass: UA_NODECLASS_VARIABLE, requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 1, identifier: 0),
31844 parentNodeId: bpr.targets[0].targetId.nodeId,
31845 referenceTypeId: refId, browseName, typeDefinition: typeId, attr: &var_attr,
31846 attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES], NULL,
31847 outNewNodeId: &sub->ns0Id);
31848 UA_CHECK_STATUS(res, goto cleanup);
31849
31850 /* Add a second reference from the overall SubscriptionDiagnosticsArray variable */
31851 const UA_NodeId subDiagArray =
31852 UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SUBSCRIPTIONDIAGNOSTICSARRAY);
31853 res = addRefWithSession(server, session, sourceId: &subDiagArray, referenceTypeId: &refId, targetId: &sub->ns0Id, true);
31854 if(res != UA_STATUSCODE_GOOD)
31855 goto cleanup;
31856
31857 /* Get all children (including the variable itself) and set the contenxt + callback */
31858 res = referenceTypeIndices(server, refType: &hasComponent, indices: &refTypes, false);
31859 if(UA_LIKELY(res == UA_STATUSCODE_GOOD)) {
31860 res = browseRecursive(server, startNodesSize: 1, startNodes: &sub->ns0Id,
31861 browseDirection: UA_BROWSEDIRECTION_FORWARD, refTypes: &refTypes,
31862 nodeClassMask: UA_NODECLASS_VARIABLE, true, resultsSize: &childrenSize, results: &children);
31863 }
31864 if(res != UA_STATUSCODE_GOOD)
31865 goto cleanup;
31866
31867 /* Add the callback to all variables */
31868 UA_DataSource subDiagSource = {readSubscriptionDiagnostics, NULL};
31869 for(size_t i = 0; i < childrenSize; i++) {
31870 setVariableNode_dataSource(server, nodeId: children[i].nodeId, dataSource: subDiagSource);
31871 setNodeContext(server, nodeId: children[i].nodeId, nodeContext: sub);
31872 }
31873
31874 UA_Array_delete(p: children, size: childrenSize, type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
31875
31876 cleanup:
31877 UA_BrowsePathResult_clear(p: &bpr);
31878 if(res != UA_STATUSCODE_GOOD) {
31879 UA_LOG_WARNING_SESSION(server->config.logging, session,
31880 "Creating the subscription diagnostics object failed "
31881 "with StatusCode %s", UA_StatusCode_name(res));
31882 }
31883}
31884
31885/***********************/
31886/* Session Diagnostics */
31887/***********************/
31888
31889static UA_StatusCode
31890setSessionSubscriptionDiagnostics(UA_Server *server, UA_Session *session,
31891 UA_DataValue *value) {
31892 UA_LOCK_ASSERT(&server->serviceMutex, 1);
31893
31894 /* Get the current session */
31895 size_t sdSize = session->subscriptionsSize;
31896
31897 /* Allocate the output array */
31898 UA_SubscriptionDiagnosticsDataType *sd = (UA_SubscriptionDiagnosticsDataType*)
31899 UA_Array_new(size: sdSize, type: &UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE]);
31900 if(!sd)
31901 return UA_STATUSCODE_BADOUTOFMEMORY;
31902
31903 /* Collect the statistics */
31904 size_t i = 0;
31905 UA_Subscription *sub;
31906 TAILQ_FOREACH(sub, &session->subscriptions, sessionListEntry) {
31907 fillSubscriptionDiagnostics(sub, diag: &sd[i]);
31908 i++;
31909 }
31910
31911 /* Set the output */
31912 value->hasValue = true;
31913 UA_Variant_setArray(v: &value->value, array: sd, arraySize: sdSize,
31914 type: &UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE]);
31915 return UA_STATUSCODE_GOOD;
31916}
31917
31918#endif /* UA_ENABLE_SUBSCRIPTIONS */
31919
31920static void
31921setSessionDiagnostics(UA_Session *session, UA_SessionDiagnosticsDataType *sd) {
31922 UA_SessionDiagnosticsDataType_copy(src: &session->diagnostics, dst: sd);
31923 UA_NodeId_copy(src: &session->sessionId, dst: &sd->sessionId);
31924 UA_String_copy(src: &session->sessionName, dst: &sd->sessionName);
31925 UA_ApplicationDescription_copy(src: &session->clientDescription,
31926 dst: &sd->clientDescription);
31927 sd->maxResponseMessageSize = session->maxResponseMessageSize;
31928#ifdef UA_ENABLE_SUBSCRIPTIONS
31929 sd->currentPublishRequestsInQueue = (UA_UInt32)session->responseQueueSize;
31930#endif
31931 sd->actualSessionTimeout = session->timeout;
31932
31933 /* Set LocaleIds */
31934 UA_StatusCode res =
31935 UA_Array_copy(src: session->localeIds, size: session->localeIdsSize,
31936 dst: (void **)&sd->localeIds, type: &UA_TYPES[UA_TYPES_STRING]);
31937 if(UA_LIKELY(res == UA_STATUSCODE_GOOD))
31938 sd->localeIdsSize = session->localeIdsSize;
31939
31940 /* Set Subscription diagnostics */
31941#ifdef UA_ENABLE_SUBSCRIPTIONS
31942 sd->currentSubscriptionsCount = (UA_UInt32)session->subscriptionsSize;
31943
31944 UA_Subscription *sub;
31945 TAILQ_FOREACH(sub, &session->subscriptions, sessionListEntry) {
31946 sd->currentMonitoredItemsCount += (UA_UInt32)sub->monitoredItemsSize;
31947 }
31948#endif
31949}
31950
31951UA_StatusCode
31952readSessionDiagnosticsArray(UA_Server *server,
31953 const UA_NodeId *sessionId, void *sessionContext,
31954 const UA_NodeId *nodeId, void *nodeContext,
31955 UA_Boolean sourceTimestamp,
31956 const UA_NumericRange *range, UA_DataValue *value) {
31957 /* Allocate the output array */
31958 UA_SessionDiagnosticsDataType *sd = (UA_SessionDiagnosticsDataType*)
31959 UA_Array_new(size: server->sessionCount,
31960 type: &UA_TYPES[UA_TYPES_SESSIONDIAGNOSTICSDATATYPE]);
31961 if(!sd)
31962 return UA_STATUSCODE_BADOUTOFMEMORY;
31963
31964 lockServer(server);
31965
31966 /* Collect the statistics */
31967 size_t i = 0;
31968 session_list_entry *session;
31969 LIST_FOREACH(session, &server->sessions, pointers) {
31970 setSessionDiagnostics(session: &session->session, sd: &sd[i]);
31971 i++;
31972 }
31973
31974 /* Set the output */
31975 value->hasValue = true;
31976 UA_Variant_setArray(v: &value->value, array: sd, arraySize: server->sessionCount,
31977 type: &UA_TYPES[UA_TYPES_SESSIONDIAGNOSTICSDATATYPE]);
31978
31979 unlockServer(server);
31980 return UA_STATUSCODE_GOOD;
31981}
31982
31983static void
31984setSessionSecurityDiagnostics(UA_Session *session,
31985 UA_SessionSecurityDiagnosticsDataType *sd) {
31986 UA_SessionSecurityDiagnosticsDataType_copy(src: &session->securityDiagnostics, dst: sd);
31987 UA_NodeId_copy(src: &session->sessionId, dst: &sd->sessionId);
31988 UA_String_copy(src: &session->clientUserIdOfSession, dst: &sd->clientUserIdOfSession);
31989 UA_SecureChannel *channel = session->header.channel;
31990 if(channel) {
31991 UA_ByteString_copy(src: &channel->remoteCertificate, dst: &sd->clientCertificate);
31992 UA_String_copy(src: &channel->securityPolicy->policyUri, dst: &sd->securityPolicyUri);
31993 sd->securityMode = channel->securityMode;
31994 sd->encoding = UA_STRING_ALLOC("UA Binary"); /* The only one atm */
31995 sd->transportProtocol = UA_STRING_ALLOC("opc.tcp"); /* The only one atm */
31996 }
31997}
31998
31999static UA_StatusCode
32000readSessionDiagnostics(UA_Server *server,
32001 const UA_NodeId *sessionId, void *sessionContext,
32002 const UA_NodeId *nodeId, void *nodeContext,
32003 UA_Boolean sourceTimestamp,
32004 const UA_NumericRange *range, UA_DataValue *value) {
32005 lockServer(server);
32006
32007 /* Get the Session */
32008 UA_Session *session = getSessionById(server, sessionId);
32009 if(!session) {
32010 unlockServer(server);
32011 return UA_STATUSCODE_BADINTERNALERROR;
32012 }
32013
32014 /* Read the BrowseName */
32015 UA_QualifiedName bn;
32016 UA_StatusCode res = readWithReadValue(server, nodeId, attributeId: UA_ATTRIBUTEID_BROWSENAME, v: &bn);
32017 if(res != UA_STATUSCODE_GOOD) {
32018 unlockServer(server);
32019 return res;
32020 }
32021
32022 union {
32023 UA_SessionDiagnosticsDataType sddt;
32024 UA_SessionSecurityDiagnosticsDataType ssddt;
32025 } data;
32026 void *content;
32027 UA_Boolean isArray = false;
32028 const UA_DataType *type = NULL;
32029 UA_Boolean securityDiagnostics = false;
32030
32031 char memberName[128];
32032 size_t memberOffset;
32033 UA_Boolean found;
32034
32035#ifdef UA_ENABLE_SUBSCRIPTIONS
32036 if(equalBrowseName(bn: &bn.name, n: "SubscriptionDiagnosticsArray")) {
32037 res = setSessionSubscriptionDiagnostics(server, session, value);
32038 goto cleanup;
32039 }
32040#endif
32041
32042 if(equalBrowseName(bn: &bn.name, n: "SessionDiagnostics")) {
32043 setSessionDiagnostics(session, sd: &data.sddt);
32044 content = &data.sddt;
32045 type = &UA_TYPES[UA_TYPES_SESSIONDIAGNOSTICSDATATYPE];
32046 } else if(equalBrowseName(bn: &bn.name, n: "SessionSecurityDiagnostics")) {
32047 setSessionSecurityDiagnostics(session, sd: &data.ssddt);
32048 securityDiagnostics = true;
32049 content = &data.ssddt;
32050 type = &UA_TYPES[UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE];
32051 } else {
32052 /* Try to find the member in SessionDiagnosticsDataType and
32053 * SessionSecurityDiagnosticsDataType */
32054 memcpy(dest: memberName, src: bn.name.data, n: bn.name.length);
32055 memberName[bn.name.length] = 0;
32056 found = UA_DataType_getStructMember(type: &UA_TYPES[UA_TYPES_SESSIONDIAGNOSTICSDATATYPE],
32057 memberName, outOffset: &memberOffset, outMemberType: &type, outIsArray: &isArray);
32058 if(found) {
32059 setSessionDiagnostics(session, sd: &data.sddt);
32060 content = (void*)(((uintptr_t)&data.sddt) + memberOffset);
32061 } else {
32062 const UA_DataType *dt = &UA_TYPES[UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE];
32063 found = UA_DataType_getStructMember(type: dt, memberName, outOffset: &memberOffset,
32064 outMemberType: &type, outIsArray: &isArray);
32065 if(!found) {
32066 res = UA_STATUSCODE_BADNOTIMPLEMENTED;
32067 goto cleanup;
32068 }
32069 setSessionSecurityDiagnostics(session, sd: &data.ssddt);
32070 securityDiagnostics = true;
32071 content = (void*)(((uintptr_t)&data.ssddt) + memberOffset);
32072 }
32073 }
32074
32075 if(!isArray) {
32076 res = UA_Variant_setScalarCopy(v: &value->value, p: content, type);
32077 } else {
32078 size_t len = *(size_t*)content;
32079 content = *(void**)((uintptr_t)content + sizeof(size_t));
32080 res = UA_Variant_setArrayCopy(v: &value->value, array: content, arraySize: len, type);
32081 }
32082 if(UA_LIKELY(res == UA_STATUSCODE_GOOD))
32083 value->hasValue = true;
32084
32085 if(securityDiagnostics)
32086 UA_SessionSecurityDiagnosticsDataType_clear(p: &data.ssddt);
32087 else
32088 UA_SessionDiagnosticsDataType_clear(p: &data.sddt);
32089
32090 cleanup:
32091 UA_QualifiedName_clear(p: &bn);
32092 unlockServer(server);
32093 return res;
32094}
32095
32096UA_StatusCode
32097readSessionSecurityDiagnostics(UA_Server *server,
32098 const UA_NodeId *sessionId, void *sessionContext,
32099 const UA_NodeId *nodeId, void *nodeContext,
32100 UA_Boolean sourceTimestamp,
32101 const UA_NumericRange *range, UA_DataValue *value) {
32102 /* Allocate the output array */
32103 UA_SessionSecurityDiagnosticsDataType *sd = (UA_SessionSecurityDiagnosticsDataType*)
32104 UA_Array_new(size: server->sessionCount,
32105 type: &UA_TYPES[UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE]);
32106 if(!sd)
32107 return UA_STATUSCODE_BADOUTOFMEMORY;
32108
32109 lockServer(server);
32110
32111 /* Collect the statistics */
32112 size_t i = 0;
32113 session_list_entry *session;
32114 LIST_FOREACH(session, &server->sessions, pointers) {
32115 setSessionSecurityDiagnostics(session: &session->session, sd: &sd[i]);
32116 i++;
32117 }
32118
32119 /* Set the output */
32120 value->hasValue = true;
32121 UA_Variant_setArray(v: &value->value, array: sd, arraySize: server->sessionCount,
32122 type: &UA_TYPES[UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE]);
32123
32124 unlockServer(server);
32125 return UA_STATUSCODE_GOOD;
32126}
32127
32128void
32129createSessionObject(UA_Server *server, UA_Session *session) {
32130 UA_ExpandedNodeId *children = NULL;
32131 size_t childrenSize = 0;
32132 UA_ReferenceTypeSet refTypes;
32133 UA_NodeId hasComponent = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT);
32134
32135 /* Create an object for the session. Instantiates all the mandatory children. */
32136 UA_ObjectAttributes object_attr = UA_ObjectAttributes_default;
32137 object_attr.displayName.text = session->sessionName;
32138 UA_NodeId parentId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY);
32139 UA_NodeId refId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT);
32140 UA_QualifiedName browseName = UA_QUALIFIEDNAME(nsIndex: 0, chars: "");
32141 browseName.name = session->sessionName; /* shallow copy */
32142 UA_NodeId typeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE);
32143 UA_StatusCode res = addNode(server, nodeClass: UA_NODECLASS_OBJECT, requestedNewNodeId: session->sessionId,
32144 parentNodeId: parentId, referenceTypeId: refId, browseName, typeDefinition: typeId, attr: &object_attr,
32145 attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], NULL, NULL);
32146 if(res != UA_STATUSCODE_GOOD)
32147 goto cleanup;
32148
32149 /* Recursively browse all children */
32150 res = referenceTypeIndices(server, refType: &hasComponent, indices: &refTypes, false);
32151 if(res != UA_STATUSCODE_GOOD)
32152 goto cleanup;
32153 res = browseRecursive(server, startNodesSize: 1, startNodes: &session->sessionId,
32154 browseDirection: UA_BROWSEDIRECTION_FORWARD, refTypes: &refTypes,
32155 nodeClassMask: UA_NODECLASS_VARIABLE, false, resultsSize: &childrenSize, results: &children);
32156 if(res != UA_STATUSCODE_GOOD)
32157 goto cleanup;
32158
32159 /* Add the callback to all variables */
32160 UA_DataSource sessionDiagSource = {readSessionDiagnostics, NULL};
32161 for(size_t i = 0; i < childrenSize; i++) {
32162 setVariableNode_dataSource(server, nodeId: children[i].nodeId, dataSource: sessionDiagSource);
32163 }
32164
32165 cleanup:
32166 if(res != UA_STATUSCODE_GOOD) {
32167 UA_LOG_WARNING_SESSION(server->config.logging, session,
32168 "Creating the session diagnostics object failed "
32169 "with StatusCode %s", UA_StatusCode_name(res));
32170 }
32171 UA_Array_delete(p: children, size: childrenSize, type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
32172}
32173
32174/***************************/
32175/* Server-Wide Diagnostics */
32176/***************************/
32177
32178UA_StatusCode
32179readDiagnostics(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
32180 const UA_NodeId *nodeId, void *nodeContext, UA_Boolean sourceTimestamp,
32181 const UA_NumericRange *range, UA_DataValue *value) {
32182 if(range) {
32183 value->hasStatus = true;
32184 value->status = UA_STATUSCODE_BADINDEXRANGEINVALID;
32185 return UA_STATUSCODE_GOOD;
32186 }
32187
32188 if(sourceTimestamp) {
32189 value->hasSourceTimestamp = true;
32190 value->sourceTimestamp = UA_DateTime_now();
32191 }
32192
32193 UA_assert(nodeId->identifierType == UA_NODEIDTYPE_NUMERIC);
32194
32195 void *data = NULL;
32196 const UA_DataType *type = &UA_TYPES[UA_TYPES_UINT32]; /* Default */
32197
32198 lockServer(server);
32199
32200 switch(nodeId->identifier.numeric) {
32201 case UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY:
32202 server->serverDiagnosticsSummary.currentSessionCount =
32203 server->activeSessionCount;
32204 data = &server->serverDiagnosticsSummary;
32205 type = &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE];
32206 break;
32207 case UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SERVERVIEWCOUNT:
32208 data = &server->serverDiagnosticsSummary.serverViewCount;
32209 break;
32210 case UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CURRENTSESSIONCOUNT:
32211 data = &server->activeSessionCount;
32212 break;
32213 case UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CUMULATEDSESSIONCOUNT:
32214 data = &server->serverDiagnosticsSummary.cumulatedSessionCount;
32215 break;
32216 case UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SECURITYREJECTEDSESSIONCOUNT:
32217 data = &server->serverDiagnosticsSummary.securityRejectedSessionCount;
32218 break;
32219 case UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_REJECTEDSESSIONCOUNT:
32220 data = &server->serverDiagnosticsSummary.rejectedSessionCount;
32221 break;
32222 case UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SESSIONTIMEOUTCOUNT:
32223 data = &server->serverDiagnosticsSummary.sessionTimeoutCount;
32224 break;
32225 case UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SESSIONABORTCOUNT:
32226 data = &server->serverDiagnosticsSummary.sessionAbortCount;
32227 break;
32228 case UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CURRENTSUBSCRIPTIONCOUNT:
32229 data = &server->serverDiagnosticsSummary.currentSubscriptionCount;
32230 break;
32231 case UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CUMULATEDSUBSCRIPTIONCOUNT:
32232 data = &server->serverDiagnosticsSummary.cumulatedSubscriptionCount;
32233 break;
32234 case UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_PUBLISHINGINTERVALCOUNT:
32235 data = &server->serverDiagnosticsSummary.publishingIntervalCount;
32236 break;
32237 case UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SECURITYREJECTEDREQUESTSCOUNT:
32238 data = &server->serverDiagnosticsSummary.securityRejectedRequestsCount;
32239 break;
32240 case UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_REJECTEDREQUESTSCOUNT:
32241 data = &server->serverDiagnosticsSummary.rejectedRequestsCount;
32242 break;
32243 default:
32244 unlockServer(server);
32245 return UA_STATUSCODE_BADINTERNALERROR;
32246 }
32247
32248 UA_StatusCode res = UA_Variant_setScalarCopy(v: &value->value, p: data, type);
32249 if(res == UA_STATUSCODE_GOOD)
32250 value->hasValue = true;
32251
32252 unlockServer(server);
32253 return res;
32254}
32255
32256#endif /* UA_ENABLE_DIAGNOSTICS */
32257
32258/**** amalgamated original file "/src/server/ua_server_config.c" ****/
32259
32260/* This Source Code Form is subject to the terms of the Mozilla Public
32261 * License, v. 2.0. If a copy of the MPL was not distributed with this
32262 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
32263 *
32264 * Copyright 2019 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
32265 * Copyright 2019 (c) HMS Industrial Networks AB (Author: Jonas Green)
32266 */
32267
32268
32269
32270void
32271UA_ServerConfig_clean(UA_ServerConfig *config) {
32272 if(!config)
32273 return;
32274
32275 /* Server Description */
32276 UA_BuildInfo_clear(p: &config->buildInfo);
32277 UA_ApplicationDescription_clear(p: &config->applicationDescription);
32278#ifdef UA_ENABLE_DISCOVERY_MULTICAST
32279 UA_MdnsDiscoveryConfiguration_clear(&config->mdnsConfig);
32280 UA_String_clear(&config->mdnsInterfaceIP);
32281# if !defined(UA_HAS_GETIFADDR)
32282 if (config->mdnsIpAddressListSize) {
32283 UA_free(config->mdnsIpAddressList);
32284 }
32285# endif
32286#endif
32287
32288 /* Stop and delete the EventLoop */
32289 UA_EventLoop *el = config->eventLoop;
32290 if(el && !config->externalEventLoop) {
32291 if(el->state != UA_EVENTLOOPSTATE_FRESH &&
32292 el->state != UA_EVENTLOOPSTATE_STOPPED) {
32293 el->stop(el);
32294 while(el->state != UA_EVENTLOOPSTATE_STOPPED) {
32295 el->run(el, 100);
32296 }
32297 }
32298 el->free(el);
32299 config->eventLoop = NULL;
32300 }
32301
32302 /* Networking */
32303 UA_Array_delete(p: config->serverUrls, size: config->serverUrlsSize,
32304 type: &UA_TYPES[UA_TYPES_STRING]);
32305 config->serverUrls = NULL;
32306 config->serverUrlsSize = 0;
32307
32308 /* Security Policies */
32309 for(size_t i = 0; i < config->securityPoliciesSize; ++i) {
32310 UA_SecurityPolicy *policy = &config->securityPolicies[i];
32311 policy->clear(policy);
32312 }
32313 UA_free(ptr: config->securityPolicies);
32314 config->securityPolicies = NULL;
32315 config->securityPoliciesSize = 0;
32316
32317 for(size_t i = 0; i < config->endpointsSize; ++i)
32318 UA_EndpointDescription_clear(p: &config->endpoints[i]);
32319
32320 UA_free(ptr: config->endpoints);
32321 config->endpoints = NULL;
32322 config->endpointsSize = 0;
32323
32324 /* Nodestore */
32325 if(config->nodestore.context && config->nodestore.clear) {
32326 config->nodestore.clear(config->nodestore.context);
32327 config->nodestore.context = NULL;
32328 }
32329
32330 /* Certificate Validation */
32331 if(config->secureChannelPKI.clear)
32332 config->secureChannelPKI.clear(&config->secureChannelPKI);
32333 if(config->sessionPKI.clear)
32334 config->sessionPKI.clear(&config->sessionPKI);
32335
32336 /* Access Control */
32337 if(config->accessControl.clear)
32338 config->accessControl.clear(&config->accessControl);
32339
32340 /* Historical data */
32341#ifdef UA_ENABLE_HISTORIZING
32342 if(config->historyDatabase.clear)
32343 config->historyDatabase.clear(&config->historyDatabase);
32344#endif
32345
32346#ifdef UA_ENABLE_PUBSUB
32347#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
32348 if(config->pubSubConfig.securityPolicies != NULL) {
32349 for(size_t i = 0; i < config->pubSubConfig.securityPoliciesSize; i++) {
32350 config->pubSubConfig.securityPolicies[i].clear(&config->pubSubConfig.securityPolicies[i]);
32351 }
32352 UA_free(config->pubSubConfig.securityPolicies);
32353 config->pubSubConfig.securityPolicies = NULL;
32354 config->pubSubConfig.securityPoliciesSize = 0;
32355 }
32356#endif
32357#endif /* UA_ENABLE_PUBSUB */
32358
32359 /* Logger */
32360 if(config->logging != NULL && config->logging->clear != NULL)
32361 config->logging->clear(config->logging);
32362 config->logging = NULL;
32363
32364 /* Custom Data Types */
32365 UA_cleanupDataTypeWithCustom(customTypes: config->customDataTypes);
32366 config->customDataTypes = NULL;
32367}
32368
32369/**** amalgamated original file "/src/server/ua_server_binary.c" ****/
32370
32371/* This Source Code Form is subject to the terms of the Mozilla Public
32372 * License, v. 2.0. If a copy of the MPL was not distributed with this
32373 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
32374 *
32375 * Copyright 2014-2022 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
32376 * Copyright 2014-2016 (c) Sten Grüner
32377 * Copyright 2014-2015, 2017 (c) Florian Palm
32378 * Copyright 2015-2016 (c) Chris Iatrou
32379 * Copyright 2015-2016 (c) Oleksiy Vasylyev
32380 * Copyright 2016 (c) Joakim L. Gilje
32381 * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH
32382 * Copyright 2016 (c) TorbenD
32383 * Copyright 2017 (c) frax2222
32384 * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB
32385 * Copyright 2019 (c) Kalycito Infotech Private Limited
32386 * Copyright 2023 (c) Hilscher Gesellschaft für Systemautomation mbH (Author: Phuong Nguyen)
32387 */
32388
32389
32390
32391#define STARTCHANNELID 1
32392#define STARTTOKENID 1
32393
32394#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
32395// store the authentication token and session ID so we can help fuzzing by setting
32396// these values in the next request automatically
32397UA_NodeId unsafe_fuzz_authenticationToken = {0, UA_NODEIDTYPE_NUMERIC, {0}};
32398#endif
32399
32400#ifdef UA_DEBUG_DUMP_PKGS_FILE
32401void UA_debug_dumpCompleteChunk(UA_Server *const server, UA_Connection *const connection,
32402 UA_ByteString *messageBuffer);
32403#endif
32404
32405/************************************/
32406/* Binary Protocol Server Component */
32407/************************************/
32408
32409/* Maximum numbers of sockets to listen on */
32410#define UA_MAXSERVERCONNECTIONS 16
32411
32412/* SecureChannel Linked List */
32413typedef struct channel_entry {
32414 UA_SecureChannel channel;
32415 TAILQ_ENTRY(channel_entry) pointers;
32416} channel_entry;
32417
32418typedef struct {
32419 UA_ConnectionState state;
32420 uintptr_t connectionId;
32421 UA_ConnectionManager *connectionManager;
32422} UA_ServerConnection;
32423
32424/* Reverse connect */
32425typedef struct reverse_connect_context {
32426 UA_String hostname;
32427 UA_UInt16 port;
32428 UA_UInt64 handle;
32429
32430 UA_SecureChannelState state;
32431 UA_Server_ReverseConnectStateCallback stateCallback;
32432 void *callbackContext;
32433
32434 /* If this is set to true, the reverse connection is removed/freed when the
32435 * connection closes. Otherwise we try to reconnect when the connection
32436 * closes. */
32437 UA_Boolean destruction;
32438
32439 UA_ServerConnection currentConnection;
32440 UA_SecureChannel *channel;
32441 LIST_ENTRY(reverse_connect_context) next;
32442} reverse_connect_context;
32443
32444/* Binary Protocol Manager */
32445typedef struct {
32446 UA_ServerComponent sc;
32447 UA_Server *server; /* remember the pointer so we don't need an additional
32448 context pointer for connections */
32449 const UA_Logger *logging; /* shortcut */
32450 UA_UInt64 houseKeepingCallbackId;
32451
32452 UA_ServerConnection serverConnections[UA_MAXSERVERCONNECTIONS];
32453 size_t serverConnectionsSize;
32454
32455 UA_ConnectionConfig tcpConnectionConfig; /* Extracted from the server config
32456 * parameters */
32457
32458 /* SecureChannels */
32459 TAILQ_HEAD(, channel_entry) channels;
32460 UA_UInt32 lastChannelId;
32461 UA_UInt32 lastTokenId;
32462
32463 /* Reverse Connections */
32464 LIST_HEAD(, reverse_connect_context) reverseConnects;
32465 UA_UInt64 reverseConnectsCheckHandle;
32466 UA_UInt64 lastReverseConnectHandle;
32467} UA_BinaryProtocolManager;
32468
32469void setReverseConnectState(UA_Server *server, reverse_connect_context *context,
32470 UA_SecureChannelState newState);
32471UA_StatusCode attemptReverseConnect(UA_BinaryProtocolManager *bpm,
32472 reverse_connect_context *context);
32473UA_StatusCode setReverseConnectRetryCallback(UA_BinaryProtocolManager *bpm,
32474 UA_Boolean enabled);
32475
32476/********************/
32477/* Helper Functions */
32478/********************/
32479
32480UA_UInt32
32481generateSecureChannelTokenId(UA_Server *server) {
32482 UA_ServerComponent *sc =
32483 getServerComponentByName(server, name: UA_STRING(chars: "binary"));
32484 if(!sc) {
32485 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
32486 msg: "Cannot generate a SecureChannel Token Id. "
32487 "No BinaryProtocolManager configured.");
32488 return 0;
32489 }
32490 UA_BinaryProtocolManager *bpm = (UA_BinaryProtocolManager*)sc;
32491 return bpm->lastTokenId++;
32492}
32493
32494static void
32495setBinaryProtocolManagerState(UA_Server *server,
32496 UA_BinaryProtocolManager *bpm,
32497 UA_LifecycleState state) {
32498 if(state == bpm->sc.state)
32499 return;
32500 bpm->sc.state = state;
32501 if(bpm->sc.notifyState)
32502 bpm->sc.notifyState(server, &bpm->sc, state);
32503}
32504
32505static void
32506deleteServerSecureChannel(UA_BinaryProtocolManager *bpm,
32507 UA_SecureChannel *channel) {
32508 UA_LOCK_ASSERT(&bpm->server->serviceMutex, 1);
32509
32510 /* Detach the channel from the server list */
32511 TAILQ_REMOVE(&bpm->channels, (channel_entry*)channel, pointers);
32512
32513 /* Update the statistics */
32514 UA_SecureChannelStatistics *scs = &bpm->server->secureChannelStatistics;
32515 scs->currentChannelCount--;
32516 switch(channel->shutdownReason) {
32517 case UA_SHUTDOWNREASON_CLOSE:
32518 UA_LOG_INFO_CHANNEL(bpm->logging, channel, "SecureChannel closed");
32519 break;
32520 case UA_SHUTDOWNREASON_TIMEOUT:
32521 UA_LOG_INFO_CHANNEL(bpm->logging, channel, "SecureChannel closed due to timeout");
32522 scs->channelTimeoutCount++;
32523 break;
32524 case UA_SHUTDOWNREASON_PURGE:
32525 UA_LOG_INFO_CHANNEL(bpm->logging, channel, "SecureChannel was purged");
32526 scs->channelPurgeCount++;
32527 break;
32528 case UA_SHUTDOWNREASON_REJECT:
32529 case UA_SHUTDOWNREASON_SECURITYREJECT:
32530 UA_LOG_INFO_CHANNEL(bpm->logging, channel, "SecureChannel was rejected");
32531 scs->rejectedChannelCount++;
32532 break;
32533 case UA_SHUTDOWNREASON_ABORT:
32534 UA_LOG_INFO_CHANNEL(bpm->logging, channel, "SecureChannel was aborted");
32535 scs->channelAbortCount++;
32536 break;
32537 default:
32538 UA_assert(false);
32539 break;
32540 }
32541
32542 /* Clean up the SecureChannel. This is the only place where
32543 * UA_SecureChannel_clear must be called within the server code-base. */
32544 UA_SecureChannel_clear(channel);
32545 UA_free(ptr: channel);
32546}
32547
32548UA_StatusCode
32549sendServiceFault(UA_SecureChannel *channel, UA_UInt32 requestId,
32550 UA_UInt32 requestHandle, UA_StatusCode statusCode) {
32551 UA_ServiceFault response;
32552 UA_ServiceFault_init(p: &response);
32553 UA_ResponseHeader *responseHeader = &response.responseHeader;
32554 responseHeader->requestHandle = requestHandle;
32555 responseHeader->timestamp = UA_DateTime_now();
32556 responseHeader->serviceResult = statusCode;
32557
32558 UA_LOG_DEBUG(logger: channel->securityPolicy->logger, category: UA_LOGCATEGORY_SERVER,
32559 msg: "Sending response for RequestId %u with ServiceResult %s",
32560 (unsigned)requestId, UA_StatusCode_name(code: statusCode));
32561
32562 /* Send error message. Message type is MSG and not ERR, since we are on a
32563 * SecureChannel! */
32564 return UA_SecureChannel_sendSymmetricMessage(channel, requestId,
32565 messageType: UA_MESSAGETYPE_MSG, payload: &response,
32566 payloadType: &UA_TYPES[UA_TYPES_SERVICEFAULT]);
32567}
32568
32569/* This is not an ERR message, the connection is not closed afterwards */
32570static UA_StatusCode
32571decodeHeaderSendServiceFault(UA_SecureChannel *channel, const UA_ByteString *msg,
32572 size_t offset, const UA_DataType *responseType,
32573 UA_UInt32 requestId, UA_StatusCode error) {
32574 UA_RequestHeader requestHeader;
32575 UA_StatusCode retval =
32576 UA_decodeBinaryInternal(src: msg, offset: &offset, dst: &requestHeader,
32577 type: &UA_TYPES[UA_TYPES_REQUESTHEADER], NULL);
32578 if(retval != UA_STATUSCODE_GOOD)
32579 return retval;
32580 retval = sendServiceFault(channel, requestId, requestHandle: requestHeader.requestHandle, statusCode: error);
32581 UA_RequestHeader_clear(p: &requestHeader);
32582 return retval;
32583}
32584
32585/* The counterOffset is the offset of the UA_ServiceCounterDataType for the
32586 * service in the UA_ SessionDiagnosticsDataType. */
32587#ifdef UA_ENABLE_DIAGNOSTICS
32588#define UA_SERVICECOUNTER_OFFSET(X) \
32589 *counterOffset = offsetof(UA_SessionDiagnosticsDataType, X)
32590#else
32591#define UA_SERVICECOUNTER_OFFSET(X)
32592#endif
32593
32594static void
32595getServicePointers(UA_UInt32 requestTypeId, const UA_DataType **requestType,
32596 const UA_DataType **responseType, UA_Service *service,
32597 UA_Boolean *requiresSession, size_t *counterOffset) {
32598 switch(requestTypeId) {
32599 case UA_NS0ID_GETENDPOINTSREQUEST_ENCODING_DEFAULTBINARY:
32600 *service = (UA_Service)Service_GetEndpoints;
32601 *requestType = &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST];
32602 *responseType = &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE];
32603 *requiresSession = false;
32604 break;
32605 case UA_NS0ID_FINDSERVERSREQUEST_ENCODING_DEFAULTBINARY:
32606 *service = (UA_Service)Service_FindServers;
32607 *requestType = &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST];
32608 *responseType = &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE];
32609 *requiresSession = false;
32610 break;
32611#ifdef UA_ENABLE_DISCOVERY
32612# ifdef UA_ENABLE_DISCOVERY_MULTICAST
32613 case UA_NS0ID_FINDSERVERSONNETWORKREQUEST_ENCODING_DEFAULTBINARY:
32614 *service = (UA_Service)Service_FindServersOnNetwork;
32615 *requestType = &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST];
32616 *responseType = &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE];
32617 *requiresSession = false;
32618 break;
32619# endif
32620 case UA_NS0ID_REGISTERSERVERREQUEST_ENCODING_DEFAULTBINARY:
32621 *service = (UA_Service)Service_RegisterServer;
32622 *requestType = &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST];
32623 *responseType = &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE];
32624 *requiresSession = false;
32625 break;
32626 case UA_NS0ID_REGISTERSERVER2REQUEST_ENCODING_DEFAULTBINARY:
32627 *service = (UA_Service)Service_RegisterServer2;
32628 *requestType = &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST];
32629 *responseType = &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE];
32630 *requiresSession = false;
32631 break;
32632#endif
32633 case UA_NS0ID_CREATESESSIONREQUEST_ENCODING_DEFAULTBINARY:
32634 *service = (UA_Service)Service_CreateSession;
32635 *requestType = &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST];
32636 *responseType = &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE];
32637 *requiresSession = false;
32638 break;
32639 case UA_NS0ID_ACTIVATESESSIONREQUEST_ENCODING_DEFAULTBINARY:
32640 *service = (UA_Service)Service_ActivateSession;
32641 *requestType = &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST];
32642 *responseType = &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE];
32643 break;
32644 case UA_NS0ID_CLOSESESSIONREQUEST_ENCODING_DEFAULTBINARY:
32645 *service = (UA_Service)Service_CloseSession;
32646 *requestType = &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST];
32647 *responseType = &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE];
32648 break;
32649 case UA_NS0ID_CANCELREQUEST_ENCODING_DEFAULTBINARY:
32650 *service = (UA_Service)Service_Cancel;
32651 *requestType = &UA_TYPES[UA_TYPES_CANCELREQUEST];
32652 *responseType = &UA_TYPES[UA_TYPES_CANCELRESPONSE];
32653 break;
32654 case UA_NS0ID_READREQUEST_ENCODING_DEFAULTBINARY:
32655 *service = (UA_Service)Service_Read;
32656 *requestType = &UA_TYPES[UA_TYPES_READREQUEST];
32657 *responseType = &UA_TYPES[UA_TYPES_READRESPONSE];
32658 UA_SERVICECOUNTER_OFFSET(readCount);
32659 break;
32660 case UA_NS0ID_WRITEREQUEST_ENCODING_DEFAULTBINARY:
32661 *service = (UA_Service)Service_Write;
32662 *requestType = &UA_TYPES[UA_TYPES_WRITEREQUEST];
32663 *responseType = &UA_TYPES[UA_TYPES_WRITERESPONSE];
32664 UA_SERVICECOUNTER_OFFSET(writeCount);
32665 break;
32666 case UA_NS0ID_BROWSEREQUEST_ENCODING_DEFAULTBINARY:
32667 *service = (UA_Service)Service_Browse;
32668 *requestType = &UA_TYPES[UA_TYPES_BROWSEREQUEST];
32669 *responseType = &UA_TYPES[UA_TYPES_BROWSERESPONSE];
32670 UA_SERVICECOUNTER_OFFSET(browseCount);
32671 break;
32672 case UA_NS0ID_BROWSENEXTREQUEST_ENCODING_DEFAULTBINARY:
32673 *service = (UA_Service)Service_BrowseNext;
32674 *requestType = &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST];
32675 *responseType = &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE];
32676 UA_SERVICECOUNTER_OFFSET(browseNextCount);
32677 break;
32678 case UA_NS0ID_REGISTERNODESREQUEST_ENCODING_DEFAULTBINARY:
32679 *service = (UA_Service)Service_RegisterNodes;
32680 *requestType = &UA_TYPES[UA_TYPES_REGISTERNODESREQUEST];
32681 *responseType = &UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE];
32682 UA_SERVICECOUNTER_OFFSET(registerNodesCount);
32683 break;
32684 case UA_NS0ID_UNREGISTERNODESREQUEST_ENCODING_DEFAULTBINARY:
32685 *service = (UA_Service)Service_UnregisterNodes;
32686 *requestType = &UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST];
32687 *responseType = &UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE];
32688 UA_SERVICECOUNTER_OFFSET(unregisterNodesCount);
32689 break;
32690 case UA_NS0ID_TRANSLATEBROWSEPATHSTONODEIDSREQUEST_ENCODING_DEFAULTBINARY:
32691 *service = (UA_Service)Service_TranslateBrowsePathsToNodeIds;
32692 *requestType = &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST];
32693 *responseType = &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE];
32694 UA_SERVICECOUNTER_OFFSET(translateBrowsePathsToNodeIdsCount);
32695 break;
32696
32697#ifdef UA_ENABLE_SUBSCRIPTIONS
32698 case UA_NS0ID_CREATESUBSCRIPTIONREQUEST_ENCODING_DEFAULTBINARY:
32699 *service = (UA_Service)Service_CreateSubscription;
32700 *requestType = &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST];
32701 *responseType = &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE];
32702 UA_SERVICECOUNTER_OFFSET(createSubscriptionCount);
32703 break;
32704 case UA_NS0ID_PUBLISHREQUEST_ENCODING_DEFAULTBINARY:
32705 *requestType = &UA_TYPES[UA_TYPES_PUBLISHREQUEST];
32706 *responseType = &UA_TYPES[UA_TYPES_PUBLISHRESPONSE];
32707 UA_SERVICECOUNTER_OFFSET(publishCount);
32708 break;
32709 case UA_NS0ID_REPUBLISHREQUEST_ENCODING_DEFAULTBINARY:
32710 *service = (UA_Service)Service_Republish;
32711 *requestType = &UA_TYPES[UA_TYPES_REPUBLISHREQUEST];
32712 *responseType = &UA_TYPES[UA_TYPES_REPUBLISHRESPONSE];
32713 UA_SERVICECOUNTER_OFFSET(republishCount);
32714 break;
32715 case UA_NS0ID_MODIFYSUBSCRIPTIONREQUEST_ENCODING_DEFAULTBINARY:
32716 *service = (UA_Service)Service_ModifySubscription;
32717 *requestType = &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST];
32718 *responseType = &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE];
32719 UA_SERVICECOUNTER_OFFSET(modifySubscriptionCount);
32720 break;
32721 case UA_NS0ID_SETPUBLISHINGMODEREQUEST_ENCODING_DEFAULTBINARY:
32722 *service = (UA_Service)Service_SetPublishingMode;
32723 *requestType = &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST];
32724 *responseType = &UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE];
32725 UA_SERVICECOUNTER_OFFSET(setPublishingModeCount);
32726 break;
32727 case UA_NS0ID_DELETESUBSCRIPTIONSREQUEST_ENCODING_DEFAULTBINARY:
32728 *service = (UA_Service)Service_DeleteSubscriptions;
32729 *requestType = &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST];
32730 *responseType = &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE];
32731 UA_SERVICECOUNTER_OFFSET(deleteSubscriptionsCount);
32732 break;
32733 case UA_NS0ID_TRANSFERSUBSCRIPTIONSREQUEST_ENCODING_DEFAULTBINARY:
32734 *service = (UA_Service)Service_TransferSubscriptions;
32735 *requestType = &UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSREQUEST];
32736 *responseType = &UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSRESPONSE];
32737 UA_SERVICECOUNTER_OFFSET(transferSubscriptionsCount);
32738 break;
32739 case UA_NS0ID_CREATEMONITOREDITEMSREQUEST_ENCODING_DEFAULTBINARY:
32740 *service = (UA_Service)Service_CreateMonitoredItems;
32741 *requestType = &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST];
32742 *responseType = &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE];
32743 UA_SERVICECOUNTER_OFFSET(createMonitoredItemsCount);
32744 break;
32745 case UA_NS0ID_DELETEMONITOREDITEMSREQUEST_ENCODING_DEFAULTBINARY:
32746 *service = (UA_Service)Service_DeleteMonitoredItems;
32747 *requestType = &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST];
32748 *responseType = &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE];
32749 UA_SERVICECOUNTER_OFFSET(deleteMonitoredItemsCount);
32750 break;
32751 case UA_NS0ID_MODIFYMONITOREDITEMSREQUEST_ENCODING_DEFAULTBINARY:
32752 *service = (UA_Service)Service_ModifyMonitoredItems;
32753 *requestType = &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST];
32754 *responseType = &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE];
32755 UA_SERVICECOUNTER_OFFSET(modifyMonitoredItemsCount);
32756 break;
32757 case UA_NS0ID_SETMONITORINGMODEREQUEST_ENCODING_DEFAULTBINARY:
32758 *service = (UA_Service)Service_SetMonitoringMode;
32759 *requestType = &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST];
32760 *responseType = &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE];
32761 UA_SERVICECOUNTER_OFFSET(setMonitoringModeCount);
32762 break;
32763 case UA_NS0ID_SETTRIGGERINGREQUEST_ENCODING_DEFAULTBINARY:
32764 *service = (UA_Service)Service_SetTriggering;
32765 *requestType = &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST];
32766 *responseType = &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE];
32767 UA_SERVICECOUNTER_OFFSET(setTriggeringCount);
32768 break;
32769#endif
32770#ifdef UA_ENABLE_HISTORIZING
32771 /* For History read */
32772 case UA_NS0ID_HISTORYREADREQUEST_ENCODING_DEFAULTBINARY:
32773 *service = (UA_Service)Service_HistoryRead;
32774 *requestType = &UA_TYPES[UA_TYPES_HISTORYREADREQUEST];
32775 *responseType = &UA_TYPES[UA_TYPES_HISTORYREADRESPONSE];
32776 UA_SERVICECOUNTER_OFFSET(historyReadCount);
32777 break;
32778 /* For History update */
32779 case UA_NS0ID_HISTORYUPDATEREQUEST_ENCODING_DEFAULTBINARY:
32780 *service = (UA_Service)Service_HistoryUpdate;
32781 *requestType = &UA_TYPES[UA_TYPES_HISTORYUPDATEREQUEST];
32782 *responseType = &UA_TYPES[UA_TYPES_HISTORYUPDATERESPONSE];
32783 UA_SERVICECOUNTER_OFFSET(historyUpdateCount);
32784 break;
32785#endif
32786
32787#ifdef UA_ENABLE_METHODCALLS
32788 case UA_NS0ID_CALLREQUEST_ENCODING_DEFAULTBINARY:
32789 *service = (UA_Service)Service_Call;
32790 *requestType = &UA_TYPES[UA_TYPES_CALLREQUEST];
32791 *responseType = &UA_TYPES[UA_TYPES_CALLRESPONSE];
32792 UA_SERVICECOUNTER_OFFSET(callCount);
32793 break;
32794#endif
32795
32796#ifdef UA_ENABLE_NODEMANAGEMENT
32797 case UA_NS0ID_ADDNODESREQUEST_ENCODING_DEFAULTBINARY:
32798 *service = (UA_Service)Service_AddNodes;
32799 *requestType = &UA_TYPES[UA_TYPES_ADDNODESREQUEST];
32800 *responseType = &UA_TYPES[UA_TYPES_ADDNODESRESPONSE];
32801 UA_SERVICECOUNTER_OFFSET(addNodesCount);
32802 break;
32803 case UA_NS0ID_ADDREFERENCESREQUEST_ENCODING_DEFAULTBINARY:
32804 *service = (UA_Service)Service_AddReferences;
32805 *requestType = &UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST];
32806 *responseType = &UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE];
32807 UA_SERVICECOUNTER_OFFSET(addReferencesCount);
32808 break;
32809 case UA_NS0ID_DELETENODESREQUEST_ENCODING_DEFAULTBINARY:
32810 *service = (UA_Service)Service_DeleteNodes;
32811 *requestType = &UA_TYPES[UA_TYPES_DELETENODESREQUEST];
32812 *responseType = &UA_TYPES[UA_TYPES_DELETENODESRESPONSE];
32813 UA_SERVICECOUNTER_OFFSET(deleteNodesCount);
32814 break;
32815 case UA_NS0ID_DELETEREFERENCESREQUEST_ENCODING_DEFAULTBINARY:
32816 *service = (UA_Service)Service_DeleteReferences;
32817 *requestType = &UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST];
32818 *responseType = &UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE];
32819 UA_SERVICECOUNTER_OFFSET(deleteReferencesCount);
32820 break;
32821#endif
32822
32823 default:
32824 break;
32825 }
32826}
32827
32828/*************************/
32829/* Process Message Types */
32830/*************************/
32831
32832/* HEL -> Open up the connection */
32833static UA_StatusCode
32834processHEL(UA_Server *server, UA_SecureChannel *channel, const UA_ByteString *msg) {
32835 UA_LOCK_ASSERT(&server->serviceMutex, 1);
32836
32837 UA_ConnectionManager *cm = channel->connectionManager;
32838 if(!cm || (channel->state != UA_SECURECHANNELSTATE_CONNECTED &&
32839 channel->state != UA_SECURECHANNELSTATE_RHE_SENT))
32840 return UA_STATUSCODE_BADINTERNALERROR;
32841
32842 size_t offset = 0; /* Go to the beginning of the TcpHelloMessage */
32843 UA_TcpHelloMessage helloMessage;
32844 UA_StatusCode retval =
32845 UA_decodeBinaryInternal(src: msg, offset: &offset, dst: &helloMessage,
32846 type: &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE], NULL);
32847 if(retval != UA_STATUSCODE_GOOD)
32848 return retval;
32849
32850 /* Currently not checked */
32851 UA_String_copy(src: &helloMessage.endpointUrl, dst: &channel->endpointUrl);
32852 UA_String_clear(p: &helloMessage.endpointUrl);
32853
32854 /* Parameterize the connection. The TcpHelloMessage casts to a
32855 * TcpAcknowledgeMessage. */
32856 retval = UA_SecureChannel_processHELACK(channel,
32857 remoteConfig: (UA_TcpAcknowledgeMessage*)&helloMessage);
32858 if(retval != UA_STATUSCODE_GOOD) {
32859 UA_LOG_INFO_CHANNEL(server->config.logging, channel,
32860 "Error during the HEL/ACK handshake");
32861 return retval;
32862 }
32863
32864 /* Get the send buffer from the network layer */
32865 UA_ByteString ack_msg;
32866 UA_ByteString_init(p: &ack_msg);
32867 retval = cm->allocNetworkBuffer(cm, channel->connectionId,
32868 &ack_msg, channel->config.sendBufferSize);
32869 if(retval != UA_STATUSCODE_GOOD)
32870 return retval;
32871
32872 /* Build acknowledge response */
32873 UA_TcpAcknowledgeMessage ackMessage;
32874 ackMessage.protocolVersion = 0;
32875 ackMessage.receiveBufferSize = channel->config.recvBufferSize;
32876 ackMessage.sendBufferSize = channel->config.sendBufferSize;
32877 ackMessage.maxMessageSize = channel->config.localMaxMessageSize;
32878 ackMessage.maxChunkCount = channel->config.localMaxChunkCount;
32879
32880 UA_TcpMessageHeader ackHeader;
32881 ackHeader.messageTypeAndChunkType = UA_MESSAGETYPE_ACK + UA_CHUNKTYPE_FINAL;
32882 ackHeader.messageSize = 8 + 20; /* ackHeader + ackMessage */
32883
32884 /* Encode and send the response */
32885 UA_Byte *bufPos = ack_msg.data;
32886 const UA_Byte *bufEnd = &ack_msg.data[ack_msg.length];
32887 retval |= UA_encodeBinaryInternal(src: &ackHeader,
32888 type: &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER],
32889 bufPos: &bufPos, bufEnd: &bufEnd, NULL, NULL);
32890 retval |= UA_encodeBinaryInternal(src: &ackMessage,
32891 type: &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE],
32892 bufPos: &bufPos, bufEnd: &bufEnd, NULL, NULL);
32893 if(retval != UA_STATUSCODE_GOOD) {
32894 cm->freeNetworkBuffer(cm, channel->connectionId, &ack_msg);
32895 return retval;
32896 }
32897
32898 ack_msg.length = ackHeader.messageSize;
32899 retval = cm->sendWithConnection(cm, channel->connectionId, &UA_KEYVALUEMAP_NULL, &ack_msg);
32900 if(retval == UA_STATUSCODE_GOOD)
32901 channel->state = UA_SECURECHANNELSTATE_ACK_SENT;
32902 return retval;
32903}
32904
32905/* OPN -> Open up/renew the securechannel */
32906static UA_StatusCode
32907processOPN(UA_Server *server, UA_SecureChannel *channel,
32908 const UA_UInt32 requestId, const UA_ByteString *msg) {
32909 UA_LOCK_ASSERT(&server->serviceMutex, 1);
32910
32911 if(channel->state != UA_SECURECHANNELSTATE_ACK_SENT &&
32912 channel->state != UA_SECURECHANNELSTATE_OPEN)
32913 return UA_STATUSCODE_BADINTERNALERROR;
32914 /* Decode the request */
32915 UA_NodeId requestType;
32916 UA_OpenSecureChannelRequest openSecureChannelRequest;
32917 size_t offset = 0;
32918 UA_StatusCode retval = UA_NodeId_decodeBinary(src: msg, offset: &offset, dst: &requestType);
32919 if(retval != UA_STATUSCODE_GOOD) {
32920 UA_NodeId_clear(p: &requestType);
32921 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
32922 "Could not decode the NodeId. "
32923 "Closing the SecureChannel.");
32924 UA_SecureChannel_shutdown(channel, shutdownReason: UA_SHUTDOWNREASON_REJECT);
32925 return retval;
32926 }
32927 retval = UA_decodeBinaryInternal(src: msg, offset: &offset, dst: &openSecureChannelRequest,
32928 type: &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST], NULL);
32929
32930 /* Error occurred */
32931 const UA_NodeId *opnRequestId =
32932 &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST].binaryEncodingId;
32933 if(retval != UA_STATUSCODE_GOOD || !UA_NodeId_equal(p1: &requestType, p2: opnRequestId)) {
32934 UA_NodeId_clear(p: &requestType);
32935 UA_OpenSecureChannelRequest_clear(p: &openSecureChannelRequest);
32936 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
32937 "Could not decode the OPN message. "
32938 "Closing the SecureChannel.");
32939 UA_SecureChannel_shutdown(channel, shutdownReason: UA_SHUTDOWNREASON_REJECT);
32940 return retval;
32941 }
32942 UA_NodeId_clear(p: &requestType);
32943
32944 /* Call the service */
32945 UA_OpenSecureChannelResponse openScResponse;
32946 UA_OpenSecureChannelResponse_init(p: &openScResponse);
32947 Service_OpenSecureChannel(server, channel, request: &openSecureChannelRequest, response: &openScResponse);
32948 UA_OpenSecureChannelRequest_clear(p: &openSecureChannelRequest);
32949 if(openScResponse.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
32950 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
32951 "Could not open a SecureChannel. "
32952 "Closing the connection.");
32953 UA_SecureChannel_shutdown(channel, shutdownReason: UA_SHUTDOWNREASON_REJECT);
32954 return openScResponse.responseHeader.serviceResult;
32955 }
32956
32957 /* Send the response */
32958 retval = UA_SecureChannel_sendAsymmetricOPNMessage(channel, requestId, content: &openScResponse,
32959 contentType: &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE]);
32960 UA_OpenSecureChannelResponse_clear(p: &openScResponse);
32961 if(retval != UA_STATUSCODE_GOOD) {
32962 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
32963 "Could not send the OPN answer with error code %s",
32964 UA_StatusCode_name(retval));
32965 UA_SecureChannel_shutdown(channel, shutdownReason: UA_SHUTDOWNREASON_REJECT);
32966 }
32967
32968 return retval;
32969}
32970
32971/* The responseHeader must have the requestHandle already set */
32972UA_StatusCode
32973sendResponse(UA_Server *server, UA_Session *session, UA_SecureChannel *channel,
32974 UA_UInt32 requestId, UA_Response *response, const UA_DataType *responseType) {
32975 if(!channel)
32976 return UA_STATUSCODE_BADINTERNALERROR;
32977
32978 /* If the overall service call failed, answer with a ServiceFault */
32979 if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
32980 return sendServiceFault(channel, requestId, requestHandle: response->responseHeader.requestHandle,
32981 statusCode: response->responseHeader.serviceResult);
32982
32983 /* Prepare the ResponseHeader */
32984 response->responseHeader.timestamp = UA_DateTime_now();
32985
32986 if(session) {
32987#ifdef UA_ENABLE_TYPEDESCRIPTION
32988 UA_LOG_DEBUG_SESSION(server->config.logging, session,
32989 "Sending response for RequestId %u of type %s",
32990 (unsigned)requestId, responseType->typeName);
32991#else
32992 UA_LOG_DEBUG_SESSION(server->config.logging, session,
32993 "Sending reponse for RequestId %u of type %" PRIu32,
32994 (unsigned)requestId, responseType->binaryEncodingId.identifier.numeric);
32995#endif
32996 } else {
32997#ifdef UA_ENABLE_TYPEDESCRIPTION
32998 UA_LOG_DEBUG_CHANNEL(server->config.logging, channel,
32999 "Sending response for RequestId %u of type %s",
33000 (unsigned)requestId, responseType->typeName);
33001#else
33002 UA_LOG_DEBUG_CHANNEL(server->config.logging, channel,
33003 "Sending reponse for RequestId %u of type %" PRIu32,
33004 (unsigned)requestId, responseType->binaryEncodingId.identifier.numeric);
33005#endif
33006 }
33007
33008 /* Start the message context */
33009 UA_MessageContext mc;
33010 UA_StatusCode retval = UA_MessageContext_begin(mc: &mc, channel, requestId, messageType: UA_MESSAGETYPE_MSG);
33011 if(retval != UA_STATUSCODE_GOOD)
33012 return retval;
33013
33014 /* Assert's required for clang-analyzer */
33015 UA_assert(mc.buf_pos == &mc.messageBuffer.data[UA_SECURECHANNEL_SYMMETRIC_HEADER_TOTALLENGTH]);
33016 UA_assert(mc.buf_end <= &mc.messageBuffer.data[mc.messageBuffer.length]);
33017
33018 /* Encode the response type */
33019 retval = UA_MessageContext_encode(mc: &mc, content: &responseType->binaryEncodingId,
33020 contentType: &UA_TYPES[UA_TYPES_NODEID]);
33021 if(retval != UA_STATUSCODE_GOOD)
33022 return retval;
33023
33024 /* Encode the response */
33025 retval = UA_MessageContext_encode(mc: &mc, content: response, contentType: responseType);
33026 if(retval != UA_STATUSCODE_GOOD)
33027 return retval;
33028
33029 /* Finish / send out */
33030 return UA_MessageContext_finish(mc: &mc);
33031}
33032
33033/* A Session is "bound" to a SecureChannel if it was created by the
33034 * SecureChannel or if it was activated on it. A Session can only be bound to
33035 * one SecureChannel. A Session can only be closed from the SecureChannel to
33036 * which it is bound.
33037 *
33038 * Returns Good if the AuthenticationToken exists nowhere (for CTT). */
33039UA_StatusCode
33040getBoundSession(UA_Server *server, const UA_SecureChannel *channel,
33041 const UA_NodeId *token, UA_Session **session) {
33042 UA_LOCK_ASSERT(&server->serviceMutex, 1);
33043
33044 UA_DateTime now = UA_DateTime_nowMonotonic();
33045 UA_SessionHeader *sh;
33046 SLIST_FOREACH(sh, &channel->sessions, next) {
33047 if(!UA_NodeId_equal(p1: token, p2: &sh->authenticationToken))
33048 continue;
33049 UA_Session *current = (UA_Session*)sh;
33050 /* Has the session timed out? */
33051 if(current->validTill < now) {
33052 server->serverDiagnosticsSummary.rejectedSessionCount++;
33053 return UA_STATUSCODE_BADSESSIONCLOSED;
33054 }
33055 *session = current;
33056 return UA_STATUSCODE_GOOD;
33057 }
33058
33059 server->serverDiagnosticsSummary.rejectedSessionCount++;
33060
33061 /* Session exists on another SecureChannel. The CTT expect this error. */
33062 UA_Session *tmpSession = getSessionByToken(server, token);
33063 if(tmpSession) {
33064#ifdef UA_ENABLE_DIAGNOSTICS
33065 tmpSession->diagnostics.unauthorizedRequestCount++;
33066#endif
33067 return UA_STATUSCODE_BADSECURECHANNELIDINVALID;
33068 }
33069
33070 return UA_STATUSCODE_GOOD;
33071}
33072
33073static const UA_String securityPolicyNone =
33074 UA_STRING_STATIC("http://opcfoundation.org/UA/SecurityPolicy#None");
33075
33076/* Returns a status of the SecureChannel. The detailed service status (usually
33077 * part of the response) is set in the serviceResult argument. */
33078static UA_StatusCode
33079processMSGDecoded(UA_Server *server, UA_SecureChannel *channel, UA_UInt32 requestId,
33080 UA_Service service, const UA_Request *request,
33081 const UA_DataType *requestType, UA_Response *response,
33082 const UA_DataType *responseType, UA_Boolean sessionRequired,
33083 size_t counterOffset) {
33084 UA_LOCK_ASSERT(&server->serviceMutex, 1);
33085
33086 UA_Session anonymousSession;
33087 UA_Session *session = NULL;
33088 UA_StatusCode channelRes = UA_STATUSCODE_GOOD;
33089 UA_ResponseHeader *rh = &response->responseHeader;
33090
33091 /* If it is an unencrypted (#None) channel, only allow the discovery services */
33092 if(server->config.securityPolicyNoneDiscoveryOnly &&
33093 UA_String_equal(p1: &channel->securityPolicy->policyUri, p2: &securityPolicyNone ) &&
33094 requestType != &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST] &&
33095 requestType != &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST]
33096#if defined(UA_ENABLE_DISCOVERY) && defined(UA_ENABLE_DISCOVERY_MULTICAST)
33097 && requestType != &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST]
33098#endif
33099 ) {
33100 rh->serviceResult = UA_STATUSCODE_BADSECURITYPOLICYREJECTED;
33101 goto send_response;
33102 }
33103
33104 /* Session lifecycle services. */
33105 if(requestType == &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST] ||
33106 requestType == &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST] ||
33107 requestType == &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST]) {
33108 ((UA_ChannelService)service)(server, channel, request, response);
33109#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
33110 /* Store the authentication token so we can help fuzzing by setting
33111 * these values in the next request automatically */
33112 if(requestType == &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST]) {
33113 UA_CreateSessionResponse *res = &response->createSessionResponse;
33114 UA_NodeId_copy(&res->authenticationToken, &unsafe_fuzz_authenticationToken);
33115 }
33116#endif
33117 goto send_response;
33118 }
33119
33120 /* Get the Session bound to the SecureChannel (not necessarily activated) */
33121 if(!UA_NodeId_isNull(p: &request->requestHeader.authenticationToken)) {
33122 rh->serviceResult = getBoundSession(server, channel,
33123 token: &request->requestHeader.authenticationToken,
33124 session: &session);
33125 if(rh->serviceResult != UA_STATUSCODE_GOOD)
33126 goto send_response;
33127 }
33128
33129 /* Set an anonymous, inactive session for services that need no session */
33130 if(!session) {
33131 if(sessionRequired) {
33132#ifdef UA_ENABLE_TYPEDESCRIPTION
33133 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
33134 "%s refused without a valid session",
33135 requestType->typeName);
33136#else
33137 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
33138 "Service %" PRIu32 " refused without a valid session",
33139 requestType->binaryEncodingId.identifier.numeric);
33140#endif
33141 rh->serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
33142 goto send_response;
33143 }
33144
33145 UA_Session_init(session: &anonymousSession);
33146 anonymousSession.sessionId = UA_NODEID_GUID(nsIndex: 0, guid: UA_GUID_NULL);
33147 anonymousSession.header.channel = channel;
33148 session = &anonymousSession;
33149 }
33150
33151 UA_assert(session != NULL);
33152
33153 /* Trying to use a non-activated session? */
33154 if(sessionRequired && !session->activated) {
33155#ifdef UA_ENABLE_TYPEDESCRIPTION
33156 UA_LOG_WARNING_SESSION(server->config.logging, session,
33157 "%s refused on a non-activated session",
33158 requestType->typeName);
33159#else
33160 UA_LOG_WARNING_SESSION(server->config.logging, session,
33161 "Service %" PRIu32 " refused on a non-activated session",
33162 requestType->binaryEncodingId.identifier.numeric);
33163#endif
33164 if(session != &anonymousSession) {
33165 UA_Server_removeSessionByToken(server, token: &session->header.authenticationToken,
33166 shutdownReason: UA_SHUTDOWNREASON_ABORT);
33167 }
33168 rh->serviceResult = UA_STATUSCODE_BADSESSIONNOTACTIVATED;
33169 goto send_response;
33170 }
33171
33172 /* Update the session lifetime */
33173 UA_Session_updateLifetime(session);
33174
33175#ifdef UA_ENABLE_SUBSCRIPTIONS
33176 /* The publish request is not answered immediately */
33177 if(requestType == &UA_TYPES[UA_TYPES_PUBLISHREQUEST]) {
33178 rh->serviceResult =
33179 Service_Publish(server, session, request: &request->publishRequest, requestId);
33180
33181 /* Don't send a response */
33182 goto update_statistics;
33183 }
33184#endif
33185
33186#if UA_MULTITHREADING >= 100 && defined(UA_ENABLE_METHODCALLS)
33187 /* The call request might not be answered immediately */
33188 if(requestType == &UA_TYPES[UA_TYPES_CALLREQUEST]) {
33189 UA_Boolean finished = true;
33190 Service_CallAsync(server, session, requestId, &request->callRequest,
33191 &response->callResponse, &finished);
33192
33193 /* Async method calls remain. Don't send a response now. In case we have
33194 * an async call, count as a "good" request for the diagnostics
33195 * statistic. */
33196 if(UA_LIKELY(finished))
33197 goto send_response;
33198 goto update_statistics;
33199 }
33200#endif
33201
33202 /* Execute the synchronous service call */
33203 service(server, session, request, response);
33204
33205 /* Upon success, send the response. Otherwise a ServiceFault. */
33206 send_response:
33207 channelRes = sendResponse(server, session, channel,
33208 requestId, response, responseType);
33209
33210 /* Update the diagnostics statistics */
33211 update_statistics:
33212#ifdef UA_ENABLE_DIAGNOSTICS
33213 if(session && session != &server->adminSession) {
33214 session->diagnostics.totalRequestCount.totalCount++;
33215 if(rh->serviceResult != UA_STATUSCODE_GOOD)
33216 session->diagnostics.totalRequestCount.errorCount++;
33217 if(counterOffset != 0) {
33218 UA_ServiceCounterDataType *serviceCounter = (UA_ServiceCounterDataType*)
33219 (((uintptr_t)&session->diagnostics) + counterOffset);
33220 serviceCounter->totalCount++;
33221 if(rh->serviceResult != UA_STATUSCODE_GOOD)
33222 serviceCounter->errorCount++;
33223 }
33224 }
33225#endif
33226
33227 return channelRes;
33228}
33229
33230static UA_StatusCode
33231processMSG(UA_Server *server, UA_SecureChannel *channel,
33232 UA_UInt32 requestId, const UA_ByteString *msg) {
33233 UA_LOCK_ASSERT(&server->serviceMutex, 1);
33234
33235 if(channel->state != UA_SECURECHANNELSTATE_OPEN)
33236 return UA_STATUSCODE_BADINTERNALERROR;
33237 /* Decode the nodeid */
33238 size_t offset = 0;
33239 UA_NodeId requestTypeId;
33240 UA_StatusCode retval = UA_NodeId_decodeBinary(src: msg, offset: &offset, dst: &requestTypeId);
33241 if(retval != UA_STATUSCODE_GOOD)
33242 return retval;
33243 if(requestTypeId.namespaceIndex != 0 ||
33244 requestTypeId.identifierType != UA_NODEIDTYPE_NUMERIC)
33245 UA_NodeId_clear(p: &requestTypeId); /* leads to badserviceunsupported */
33246
33247 size_t requestPos = offset; /* Store the offset (for sendServiceFault) */
33248
33249 /* Get the service pointers */
33250 UA_Service service = NULL;
33251 UA_Boolean sessionRequired = true;
33252 const UA_DataType *requestType = NULL;
33253 const UA_DataType *responseType = NULL;
33254 size_t counterOffset = 0;
33255 getServicePointers(requestTypeId: requestTypeId.identifier.numeric, requestType: &requestType,
33256 responseType: &responseType, service: &service, requiresSession: &sessionRequired, counterOffset: &counterOffset);
33257 if(!requestType) {
33258 if(requestTypeId.identifier.numeric ==
33259 UA_NS0ID_CREATESUBSCRIPTIONREQUEST_ENCODING_DEFAULTBINARY) {
33260 UA_LOG_INFO_CHANNEL(server->config.logging, channel,
33261 "Client requested a subscription, "
33262 "but those are not enabled in the build");
33263 } else {
33264 UA_LOG_INFO_CHANNEL(server->config.logging, channel,
33265 "Unknown request with type identifier %" PRIi32,
33266 requestTypeId.identifier.numeric);
33267 }
33268 return decodeHeaderSendServiceFault(channel, msg, offset: requestPos,
33269 responseType: &UA_TYPES[UA_TYPES_SERVICEFAULT],
33270 requestId, UA_STATUSCODE_BADSERVICEUNSUPPORTED);
33271 }
33272 UA_assert(responseType);
33273
33274 /* Decode the request */
33275 UA_Request request;
33276 retval = UA_decodeBinaryInternal(src: msg, offset: &offset, dst: &request,
33277 type: requestType, customTypes: server->config.customDataTypes);
33278 if(retval != UA_STATUSCODE_GOOD) {
33279 UA_LOG_DEBUG_CHANNEL(server->config.logging, channel,
33280 "Could not decode the request with StatusCode %s",
33281 UA_StatusCode_name(retval));
33282 return decodeHeaderSendServiceFault(channel, msg, offset: requestPos,
33283 responseType, requestId, error: retval);
33284 }
33285
33286 /* Check timestamp in the request header */
33287 UA_RequestHeader *requestHeader = &request.requestHeader;
33288 if(requestHeader->timestamp == 0 &&
33289 server->config.verifyRequestTimestamp <= UA_RULEHANDLING_WARN) {
33290 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
33291 "The server sends no timestamp in the request header. "
33292 "See the 'verifyRequestTimestamp' setting.");
33293 if(server->config.verifyRequestTimestamp <= UA_RULEHANDLING_ABORT) {
33294 retval = sendServiceFault(channel, requestId, requestHandle: requestHeader->requestHandle,
33295 UA_STATUSCODE_BADINVALIDTIMESTAMP);
33296 UA_clear(p: &request, type: requestType);
33297 return retval;
33298 }
33299 }
33300
33301#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
33302 /* Set the authenticationToken from the create session request to help
33303 * fuzzing cover more lines */
33304 if(!UA_NodeId_isNull(&unsafe_fuzz_authenticationToken) &&
33305 !UA_NodeId_isNull(&requestHeader->authenticationToken)) {
33306 UA_NodeId_clear(&requestHeader->authenticationToken);
33307 UA_NodeId_copy(&unsafe_fuzz_authenticationToken, &requestHeader->authenticationToken);
33308 }
33309#endif
33310
33311 /* Prepare the respone and process the request */
33312 UA_Response response;
33313 UA_init(p: &response, type: responseType);
33314 response.responseHeader.requestHandle = requestHeader->requestHandle;
33315 retval = processMSGDecoded(server, channel, requestId, service, request: &request, requestType,
33316 response: &response, responseType, sessionRequired, counterOffset);
33317
33318 /* Clean up */
33319 UA_clear(p: &request, type: requestType);
33320 UA_clear(p: &response, type: responseType);
33321 return retval;
33322}
33323
33324/* Takes decoded messages starting at the nodeid of the content type. */
33325static UA_StatusCode
33326processSecureChannelMessage(UA_Server *server, UA_SecureChannel *channel,
33327 UA_MessageType messagetype, UA_UInt32 requestId,
33328 UA_ByteString *message) {
33329 UA_LOCK_ASSERT(&server->serviceMutex, 1);
33330
33331 UA_StatusCode retval = UA_STATUSCODE_GOOD;
33332 switch(messagetype) {
33333 case UA_MESSAGETYPE_HEL:
33334 UA_LOG_TRACE_CHANNEL(server->config.logging, channel, "Process a HEL message");
33335 retval = processHEL(server, channel, msg: message);
33336 break;
33337 case UA_MESSAGETYPE_OPN:
33338 UA_LOG_TRACE_CHANNEL(server->config.logging, channel, "Process an OPN message");
33339 retval = processOPN(server, channel, requestId, msg: message);
33340 break;
33341 case UA_MESSAGETYPE_MSG:
33342 UA_LOG_TRACE_CHANNEL(server->config.logging, channel, "Process a MSG");
33343 retval = processMSG(server, channel, requestId, msg: message);
33344 break;
33345 case UA_MESSAGETYPE_CLO:
33346 UA_LOG_TRACE_CHANNEL(server->config.logging, channel, "Process a CLO");
33347 Service_CloseSecureChannel(server, channel); /* Regular close */
33348 break;
33349 default:
33350 UA_LOG_TRACE_CHANNEL(server->config.logging, channel, "Invalid message type");
33351 retval = UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
33352 break;
33353 }
33354 if(retval != UA_STATUSCODE_GOOD) {
33355 if(!UA_SecureChannel_isConnected(channel)) {
33356 UA_LOG_INFO_CHANNEL(server->config.logging, channel,
33357 "Processing the message failed. Channel already closed "
33358 "with StatusCode %s. ", UA_StatusCode_name(retval));
33359 return retval;
33360 }
33361
33362 UA_LOG_INFO_CHANNEL(server->config.logging, channel,
33363 "Processing the message failed with StatusCode %s. "
33364 "Closing the channel.", UA_StatusCode_name(retval));
33365 UA_TcpErrorMessage errMsg;
33366 UA_TcpErrorMessage_init(p: &errMsg);
33367 errMsg.error = retval;
33368 UA_SecureChannel_sendError(channel, error: &errMsg);
33369 UA_ShutdownReason reason;
33370 switch(retval) {
33371 case UA_STATUSCODE_BADSECURITYMODEREJECTED:
33372 case UA_STATUSCODE_BADSECURITYCHECKSFAILED:
33373 case UA_STATUSCODE_BADSECURECHANNELIDINVALID:
33374 case UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN:
33375 case UA_STATUSCODE_BADSECURITYPOLICYREJECTED:
33376 case UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED:
33377 reason = UA_SHUTDOWNREASON_SECURITYREJECT;
33378 break;
33379 default:
33380 reason = UA_SHUTDOWNREASON_CLOSE;
33381 break;
33382 }
33383 UA_SecureChannel_shutdown(channel, shutdownReason: reason);
33384 }
33385
33386 return retval;
33387}
33388
33389/* remove the first channel that has no session attached */
33390static UA_Boolean
33391purgeFirstChannelWithoutSession(UA_BinaryProtocolManager *bpm) {
33392 channel_entry *entry;
33393 TAILQ_FOREACH(entry, &bpm->channels, pointers) {
33394 if(SLIST_FIRST(&entry->channel.sessions))
33395 continue;
33396 UA_LOG_INFO_CHANNEL(bpm->logging, &entry->channel,
33397 "Channel was purged since maxSecureChannels was "
33398 "reached and channel had no session attached");
33399 UA_SecureChannel_shutdown(channel: &entry->channel, shutdownReason: UA_SHUTDOWNREASON_PURGE);
33400 return true;
33401 }
33402 return false;
33403}
33404
33405static UA_StatusCode
33406configServerSecureChannel(void *application, UA_SecureChannel *channel,
33407 const UA_AsymmetricAlgorithmSecurityHeader *asymHeader) {
33408 if(channel->securityPolicy)
33409 return UA_STATUSCODE_GOOD;
33410
33411 /* Iterate over available endpoints and choose the correct one */
33412 UA_Server *server = (UA_Server *)application;
33413 UA_SecurityPolicy *securityPolicy = NULL;
33414 for(size_t i = 0; i < server->config.securityPoliciesSize; ++i) {
33415 UA_SecurityPolicy *policy = &server->config.securityPolicies[i];
33416 if(!UA_ByteString_equal(p1: &asymHeader->securityPolicyUri, p2: &policy->policyUri))
33417 continue;
33418
33419 UA_StatusCode res = policy->asymmetricModule.
33420 compareCertificateThumbprint(policy, &asymHeader->receiverCertificateThumbprint);
33421 if(res != UA_STATUSCODE_GOOD)
33422 continue;
33423
33424 /* We found the correct policy (except for security mode). The endpoint
33425 * needs to be selected by the client / server to match the security
33426 * mode in the endpoint for the session. */
33427 securityPolicy = policy;
33428 break;
33429 }
33430
33431 if(!securityPolicy)
33432 return UA_STATUSCODE_BADSECURITYPOLICYREJECTED;
33433
33434 /* If the sender provides a chain of certificates then we shall extract the
33435 * ApplicationInstanceCertificate. and ignore the extra bytes. See also: OPC
33436 * UA Part 6, V1.04, 6.7.2.3 Security Header, Table 42 - Asymmetric
33437 * algorithm Security header */
33438 UA_ByteString appInstCert = getLeafCertificate(chain: asymHeader->senderCertificate);
33439
33440 /* Create the channel context and parse the sender (remote) certificate used
33441 * for the secureChannel. */
33442 return UA_SecureChannel_setSecurityPolicy(channel, securityPolicy, remoteCertificate: &appInstCert);
33443}
33444
33445static UA_StatusCode
33446createServerSecureChannel(UA_BinaryProtocolManager *bpm, UA_ConnectionManager *cm,
33447 uintptr_t connectionId, UA_SecureChannel **outChannel) {
33448 UA_LOCK_ASSERT(&bpm->server->serviceMutex, 1);
33449
33450 UA_Server *server = bpm->server;
33451 UA_ServerConfig *config = &server->config;
33452
33453 /* Check if we have space for another SC, otherwise try to find an SC
33454 * without a session and purge it */
33455 UA_SecureChannelStatistics *scs = &server->secureChannelStatistics;
33456 if(scs->currentChannelCount >= config->maxSecureChannels &&
33457 !purgeFirstChannelWithoutSession(bpm))
33458 return UA_STATUSCODE_BADOUTOFMEMORY;
33459
33460 /* Allocate memory for the SecureChannel */
33461 channel_entry *entry = (channel_entry *)UA_calloc(nmemb: 1, size: sizeof(channel_entry));
33462 if(!entry)
33463 return UA_STATUSCODE_BADOUTOFMEMORY;
33464
33465 /* Set up the initial connection config */
33466 UA_ConnectionConfig connConfig;
33467 connConfig.protocolVersion = 0;
33468 connConfig.recvBufferSize = config->tcpBufSize;
33469 connConfig.sendBufferSize = config->tcpBufSize;
33470 connConfig.localMaxMessageSize = config->tcpMaxMsgSize;
33471 connConfig.remoteMaxMessageSize = config->tcpMaxMsgSize;
33472 connConfig.localMaxChunkCount = config->tcpMaxChunks;
33473 connConfig.remoteMaxChunkCount = config->tcpMaxChunks;
33474
33475 if(connConfig.recvBufferSize == 0)
33476 connConfig.recvBufferSize = 1 << 16; /* 64kB */
33477 if(connConfig.sendBufferSize == 0)
33478 connConfig.sendBufferSize = 1 << 16; /* 64kB */
33479
33480 /* Set up the new SecureChannel */
33481 UA_SecureChannel_init(channel: &entry->channel);
33482 entry->channel.config = connConfig;
33483 entry->channel.certificateVerification = &config->secureChannelPKI;
33484 entry->channel.processOPNHeader = configServerSecureChannel;
33485 entry->channel.processOPNHeaderApplication = server;
33486 entry->channel.connectionManager = cm;
33487 entry->channel.connectionId = connectionId;
33488
33489 /* Set the SecureChannel identifier already here. So we get the right
33490 * identifier for logging right away. The rest of the SecurityToken is set
33491 * in UA_SecureChannelManager_open. Set the ChannelId also in the
33492 * alternative security token, we don't touch this value during the token
33493 * rollover. */
33494 entry->channel.securityToken.channelId = bpm->lastChannelId++;
33495
33496 /* Set an initial timeout before the negotiation handshake. So the channel
33497 * is caught if the client is unresponsive.
33498 *
33499 * TODO: Make this a configuration option */
33500 entry->channel.securityToken.createdAt = UA_DateTime_nowMonotonic();
33501 entry->channel.securityToken.revisedLifetime = 10000; /* 10s should be enough */
33502
33503 /* Add to the server's list */
33504 TAILQ_INSERT_TAIL(&bpm->channels, entry, pointers);
33505
33506 /* Update the statistics */
33507 server->secureChannelStatistics.currentChannelCount++;
33508 server->secureChannelStatistics.cumulatedChannelCount++;
33509
33510 *outChannel = &entry->channel;
33511 return UA_STATUSCODE_GOOD;
33512}
33513
33514static void
33515addDiscoveryUrl(UA_Server *server, const UA_String hostname, UA_UInt16 port) {
33516 char urlstr[1024];
33517 mp_snprintf(s: urlstr, count: 1024, format: "opc.tcp://%.*s:%d",
33518 (int)hostname.length, (char*)hostname.data, port);
33519 UA_String discoveryServerUrl = UA_STRING(chars: urlstr);
33520
33521 /* Check if the ServerUrl is already present in the DiscoveryUrl array.
33522 * Add if not already there. */
33523 for(size_t i = 0; i < server->config.applicationDescription.discoveryUrlsSize; i++) {
33524 if(UA_String_equal(p1: &discoveryServerUrl,
33525 p2: &server->config.applicationDescription.discoveryUrls[i]))
33526 return;
33527 }
33528
33529 /* Add to the list of discovery url */
33530 UA_StatusCode res =
33531 UA_Array_appendCopy(p: (void **)&server->config.applicationDescription.discoveryUrls,
33532 size: &server->config.applicationDescription.discoveryUrlsSize,
33533 newElem: &discoveryServerUrl, type: &UA_TYPES[UA_TYPES_STRING]);
33534 if(res == UA_STATUSCODE_GOOD) {
33535 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
33536 msg: "New DiscoveryUrl added: %.*s", (int)discoveryServerUrl.length,
33537 (char*)discoveryServerUrl.data);
33538 } else {
33539 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
33540 msg: "Could not register DiscoveryUrl -- out of memory");
33541 }
33542}
33543
33544/* Callback of a TCP socket (server socket or an active connection) */
33545static void
33546serverNetworkCallbackLocked(UA_ConnectionManager *cm, uintptr_t connectionId,
33547 void *application, void **connectionContext,
33548 UA_ConnectionState state,
33549 const UA_KeyValueMap *params,
33550 UA_ByteString msg) {
33551 UA_BinaryProtocolManager *bpm = (UA_BinaryProtocolManager*)application;
33552 UA_LOCK_ASSERT(&bpm->server->serviceMutex, 1);
33553
33554 /* A server socket that is not yet registered in the server. Register it and
33555 * set the connection context to the pointer in the
33556 * bpm->serverConnections list. New connections on that server socket
33557 * inherit the context (and on the first callback we set the context of
33558 * client-connections to a SecureChannel). */
33559 if(*connectionContext == NULL) {
33560 /* The socket is closing without being previously registered -> ignore */
33561 if(state == UA_CONNECTIONSTATE_CLOSED ||
33562 state == UA_CONNECTIONSTATE_CLOSING)
33563 return;
33564
33565 /* Cannot register */
33566 if(bpm->serverConnectionsSize >= UA_MAXSERVERCONNECTIONS) {
33567 UA_LOG_WARNING(logger: bpm->logging, category: UA_LOGCATEGORY_SERVER,
33568 msg: "Cannot register server socket - too many already open");
33569 cm->closeConnection(cm, connectionId);
33570 return;
33571 }
33572
33573 /* Find and use a free connection slot */
33574 bpm->serverConnectionsSize++;
33575 UA_ServerConnection *sc = bpm->serverConnections;
33576 while(sc->connectionId != 0)
33577 sc++;
33578 sc->state = state;
33579 sc->connectionId = connectionId;
33580 sc->connectionManager = cm;
33581 *connectionContext = (void*)sc; /* Set the context pointer in the connection */
33582
33583 /* Add to the DiscoveryUrls */
33584 const UA_UInt16 *port = (const UA_UInt16*)
33585 UA_KeyValueMap_getScalar(map: params, key: UA_QUALIFIEDNAME(nsIndex: 0, chars: "listen-port"),
33586 type: &UA_TYPES[UA_TYPES_UINT16]);
33587 const UA_String *address = (const UA_String*)
33588 UA_KeyValueMap_getScalar(map: params, key: UA_QUALIFIEDNAME(nsIndex: 0, chars: "listen-address"),
33589 type: &UA_TYPES[UA_TYPES_STRING]);
33590 if(port && address)
33591 addDiscoveryUrl(server: bpm->server, hostname: *address, port: *port);
33592 return;
33593 }
33594
33595 UA_ServerConnection *sc = (UA_ServerConnection*)*connectionContext;
33596 UA_SecureChannel *channel = (UA_SecureChannel*)*connectionContext;
33597 UA_Boolean serverSocket = (sc >= bpm->serverConnections &&
33598 sc < &bpm->serverConnections[UA_MAXSERVERCONNECTIONS]);
33599
33600 /* The connection is closing. This is the last callback for it. */
33601 if(state == UA_CONNECTIONSTATE_CLOSING) {
33602 if(serverSocket) {
33603 /* Server socket is closed */
33604 sc->state = UA_CONNECTIONSTATE_CLOSED;
33605 sc->connectionId = 0;
33606 bpm->serverConnectionsSize--;
33607 } else {
33608 /* A connection attached to a SecureChannel is closing. This is the
33609 * only place where deleteSecureChannel must be used. */
33610 deleteServerSecureChannel(bpm, channel);
33611 }
33612
33613 /* Set BinaryProtocolManager to STOPPED if it is STOPPING and the last
33614 * socket just closed */
33615 if(bpm->sc.state == UA_LIFECYCLESTATE_STOPPING &&
33616 bpm->serverConnectionsSize == 0 &&
33617 LIST_EMPTY(&bpm->reverseConnects) &&
33618 TAILQ_EMPTY(&bpm->channels)) {
33619 setBinaryProtocolManagerState(server: bpm->server, bpm,
33620 state: UA_LIFECYCLESTATE_STOPPED);
33621 }
33622 return;
33623 }
33624
33625 UA_StatusCode retval = UA_STATUSCODE_GOOD;
33626 if(serverSocket) {
33627 /* A new connection is opening. This is the only place where
33628 * createSecureChannel is used. */
33629 retval = createServerSecureChannel(bpm, cm, connectionId, outChannel: &channel);
33630 if(retval != UA_STATUSCODE_GOOD) {
33631 UA_LOG_WARNING(logger: bpm->logging, category: UA_LOGCATEGORY_SERVER,
33632 msg: "TCP %lu\t| Could not accept the connection with status %s",
33633 (unsigned long)sc->connectionId, UA_StatusCode_name(code: retval));
33634 *connectionContext = NULL;
33635 cm->closeConnection(cm, connectionId);
33636 return;
33637 }
33638
33639 /* Set the new channel as the new context for the connection */
33640 *connectionContext = (void*)channel;
33641
33642 /* Set the channel state to CONNECTED until the HEL message is received */
33643 channel->state = UA_SECURECHANNELSTATE_CONNECTED;
33644
33645 UA_LOG_INFO_CHANNEL(bpm->logging, channel, "SecureChannel created");
33646 }
33647
33648 /* Received a message on a normal connection */
33649#ifdef UA_DEBUG_DUMP_PKGS
33650 UA_dump_hex_pkg(message->data, message->length);
33651#endif
33652#ifdef UA_DEBUG_DUMP_PKGS_FILE
33653 UA_debug_dumpCompleteChunk(server, channel->connection, message);
33654#endif
33655
33656 /* Process all complete messages */
33657 retval = UA_SecureChannel_loadBuffer(channel, buffer: msg);
33658 while(UA_LIKELY(retval == UA_STATUSCODE_GOOD)) {
33659 UA_MessageType messageType;
33660 UA_UInt32 requestId = 0;
33661 UA_ByteString payload = UA_BYTESTRING_NULL;
33662 UA_Boolean copied = false;
33663 retval = UA_SecureChannel_getCompleteMessage(channel, messageType: &messageType, requestId: &requestId,
33664 payload: &payload, copied: &copied);
33665 if(retval != UA_STATUSCODE_GOOD || payload.length == 0)
33666 break;
33667 retval = processSecureChannelMessage(server: bpm->server, channel,
33668 messagetype: messageType, requestId, message: &payload);
33669 if(copied)
33670 UA_ByteString_clear(p: &payload);
33671 }
33672 retval |= UA_SecureChannel_persistBuffer(channel);
33673
33674 if(retval != UA_STATUSCODE_GOOD) {
33675 UA_LOG_WARNING_CHANNEL(bpm->logging, channel,
33676 "Processing the message failed with error %s",
33677 UA_StatusCode_name(retval));
33678
33679 /* Send an ERR message and close the connection */
33680 UA_TcpErrorMessage error;
33681 error.error = retval;
33682 error.reason = UA_STRING_NULL;
33683 UA_SecureChannel_sendError(channel, error: &error);
33684 UA_SecureChannel_shutdown(channel, shutdownReason: UA_SHUTDOWNREASON_ABORT);
33685 }
33686}
33687
33688void
33689serverNetworkCallback(UA_ConnectionManager *cm, uintptr_t connectionId,
33690 void *application, void **connectionContext,
33691 UA_ConnectionState state,
33692 const UA_KeyValueMap *params,
33693 UA_ByteString msg) {
33694 UA_BinaryProtocolManager *bpm = (UA_BinaryProtocolManager*)application;
33695 lockServer(server: bpm->server);
33696 serverNetworkCallbackLocked(cm, connectionId, application, connectionContext,
33697 state, params, msg);
33698 unlockServer(server: bpm->server);
33699}
33700
33701static UA_StatusCode
33702createServerConnection(UA_BinaryProtocolManager *bpm, const UA_String *serverUrl) {
33703 UA_Server *server = bpm->server;
33704 UA_ServerConfig *config = &server->config;
33705
33706 UA_LOCK_ASSERT(&server->serviceMutex, 1);
33707
33708 /* Extract the protocol, hostname and port from the url */
33709 UA_String hostname = UA_STRING_NULL;
33710 UA_String path = UA_STRING_NULL;
33711 UA_UInt16 port = 4840; /* default */
33712 UA_StatusCode res = UA_parseEndpointUrl(endpointUrl: serverUrl, outHostname: &hostname, outPort: &port, outPath: &path);
33713 if(res != UA_STATUSCODE_GOOD)
33714 return res;
33715
33716 UA_String tcpString = UA_STRING(chars: "tcp");
33717 for(UA_EventSource *es = config->eventLoop->eventSources;
33718 es != NULL; es = es->next) {
33719 /* Is this a usable connection manager? */
33720 if(es->eventSourceType != UA_EVENTSOURCETYPE_CONNECTIONMANAGER)
33721 continue;
33722 UA_ConnectionManager *cm = (UA_ConnectionManager*)es;
33723 if(!UA_String_equal(p1: &tcpString, p2: &cm->protocol))
33724 continue;
33725
33726 /* Set up the parameters */
33727 UA_KeyValuePair params[4];
33728 size_t paramsSize = 3;
33729
33730 params[0].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "port");
33731 UA_Variant_setScalar(v: &params[0].value, p: &port, type: &UA_TYPES[UA_TYPES_UINT16]);
33732
33733 UA_Boolean listen = true;
33734 params[1].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "listen");
33735 UA_Variant_setScalar(v: &params[1].value, p: &listen, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
33736
33737 UA_Boolean reuseaddr = config->tcpReuseAddr;
33738 params[2].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "reuse");
33739 UA_Variant_setScalar(v: &params[2].value, p: &reuseaddr, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
33740
33741 /* The hostname is non-empty */
33742 if(hostname.length > 0) {
33743 params[3].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "address");
33744 UA_Variant_setArray(v: &params[3].value, array: &hostname, arraySize: 1, type: &UA_TYPES[UA_TYPES_STRING]);
33745 paramsSize = 4;
33746 }
33747
33748 UA_KeyValueMap paramsMap;
33749 paramsMap.map = params;
33750 paramsMap.mapSize = paramsSize;
33751
33752 /* Open the server connection */
33753 res = cm->openConnection(cm, &paramsMap, bpm, NULL, serverNetworkCallback);
33754 if(res == UA_STATUSCODE_GOOD)
33755 return res;
33756 }
33757
33758 return UA_STATUSCODE_BADINTERNALERROR;
33759}
33760
33761/* Remove timed out SecureChannels */
33762static void
33763secureChannelHouseKeeping(UA_Server *server, void *context) {
33764 UA_BinaryProtocolManager *bpm = (UA_BinaryProtocolManager*)context;
33765 lockServer(server);
33766
33767 UA_DateTime nowMonotonic = UA_DateTime_nowMonotonic();
33768 channel_entry *entry;
33769 TAILQ_FOREACH(entry, &bpm->channels, pointers) {
33770 /* Compute the timeout date of the SecurityToken */
33771 UA_DateTime timeout =
33772 entry->channel.securityToken.createdAt +
33773 (UA_DateTime)(entry->channel.securityToken.revisedLifetime * UA_DATETIME_MSEC);
33774
33775 /* The token has timed out. Try to do the token revolving now instead of
33776 * shutting the channel down.
33777 *
33778 * Part 4, 5.5.2 says: Servers shall use the existing SecurityToken to
33779 * secure outgoing Messages until the SecurityToken expires or the
33780 * Server receives a Message secured with a new SecurityToken.*/
33781 if(timeout < nowMonotonic &&
33782 entry->channel.renewState == UA_SECURECHANNELRENEWSTATE_NEWTOKEN_SERVER) {
33783 /* Revolve the token manually. This is otherwise done in checkSymHeader. */
33784 entry->channel.renewState = UA_SECURECHANNELRENEWSTATE_NORMAL;
33785 entry->channel.securityToken = entry->channel.altSecurityToken;
33786 UA_ChannelSecurityToken_init(p: &entry->channel.altSecurityToken);
33787 UA_SecureChannel_generateLocalKeys(channel: &entry->channel);
33788 generateRemoteKeys(channel: &entry->channel);
33789
33790 /* Use the timeout of the new SecurityToken */
33791 timeout = entry->channel.securityToken.createdAt +
33792 (UA_DateTime)(entry->channel.securityToken.revisedLifetime * UA_DATETIME_MSEC);
33793 }
33794
33795 if(timeout < nowMonotonic) {
33796 UA_LOG_INFO_CHANNEL(bpm->logging, &entry->channel,
33797 "SecureChannel has timed out");
33798 UA_SecureChannel_shutdown(channel: &entry->channel, shutdownReason: UA_SHUTDOWNREASON_TIMEOUT);
33799 }
33800 }
33801 unlockServer(server);
33802}
33803
33804/**********************/
33805/* Reverse Connection */
33806/**********************/
33807
33808#define UA_MINMESSAGESIZE 8192
33809
33810static UA_StatusCode
33811sendRHEMessage(UA_Server *server, uintptr_t connectionId,
33812 UA_ConnectionManager *cm) {
33813 UA_ServerConfig *config = UA_Server_getConfig(server);
33814
33815 /* Get a buffer */
33816 UA_ByteString message;
33817 UA_StatusCode retval =
33818 cm->allocNetworkBuffer(cm, connectionId, &message, UA_MINMESSAGESIZE);
33819 if(retval != UA_STATUSCODE_GOOD)
33820 return retval;
33821
33822 /* Prepare the RHE message and encode at offset 8 */
33823 UA_TcpReverseHelloMessage reverseHello;
33824 UA_TcpReverseHelloMessage_init(p: &reverseHello);
33825 reverseHello.serverUri = config->applicationDescription.applicationUri;
33826 if(config->applicationDescription.discoveryUrlsSize)
33827 reverseHello.endpointUrl = config->applicationDescription.discoveryUrls[0];
33828
33829 UA_Byte *bufPos = &message.data[8]; /* skip the header */
33830 const UA_Byte *bufEnd = &message.data[message.length];
33831 UA_StatusCode result =
33832 UA_encodeBinaryInternal(src: &reverseHello,
33833 type: &UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE],
33834 bufPos: &bufPos, bufEnd: &bufEnd, NULL, NULL);
33835
33836 if(result != UA_STATUSCODE_GOOD) {
33837 cm->freeNetworkBuffer(cm, connectionId, &message);
33838 return result;
33839 }
33840
33841 /* Encode the message header at offset 0 */
33842 UA_TcpMessageHeader messageHeader;
33843 messageHeader.messageTypeAndChunkType = UA_CHUNKTYPE_FINAL + UA_MESSAGETYPE_RHE;
33844 messageHeader.messageSize = (UA_UInt32) ((uintptr_t)bufPos - (uintptr_t)message.data);
33845 bufPos = message.data;
33846 retval = UA_encodeBinaryInternal(src: &messageHeader,
33847 type: &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER],
33848 bufPos: &bufPos, bufEnd: &bufEnd, NULL, NULL);
33849 if(retval != UA_STATUSCODE_GOOD) {
33850 cm->freeNetworkBuffer(cm, connectionId, &message);
33851 return retval;
33852 }
33853
33854 /* Send the RHE message */
33855 message.length = messageHeader.messageSize;
33856 return cm->sendWithConnection(cm, connectionId, NULL, &message);
33857}
33858
33859static void
33860retryReverseConnectCallback(UA_Server *server, void *context) {
33861 lockServer(server);
33862
33863 UA_BinaryProtocolManager *bpm = (UA_BinaryProtocolManager*)context;
33864
33865 reverse_connect_context *rc = NULL;
33866 LIST_FOREACH(rc, &bpm->reverseConnects, next) {
33867 if(rc->currentConnection.connectionId)
33868 continue;
33869 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
33870 msg: "Attempt to reverse reconnect to %.*s:%d",
33871 (int)rc->hostname.length, rc->hostname.data, rc->port);
33872 attemptReverseConnect(bpm, context: rc);
33873 }
33874
33875 unlockServer(server);
33876}
33877
33878UA_StatusCode
33879setReverseConnectRetryCallback(UA_BinaryProtocolManager *bpm, UA_Boolean enabled) {
33880 UA_Server *server = bpm->server;
33881 UA_ServerConfig *config = &server->config;
33882
33883 if(enabled && !bpm->reverseConnectsCheckHandle) {
33884 UA_UInt32 reconnectInterval = config->reverseReconnectInterval ?
33885 config->reverseReconnectInterval : 15000;
33886 return addRepeatedCallback(server, callback: retryReverseConnectCallback, data: bpm,
33887 interval_ms: reconnectInterval, callbackId: &bpm->reverseConnectsCheckHandle);
33888 } else if(!enabled && bpm->reverseConnectsCheckHandle) {
33889 removeCallback(server, callbackId: bpm->reverseConnectsCheckHandle);
33890 bpm->reverseConnectsCheckHandle = 0;
33891 }
33892 return UA_STATUSCODE_GOOD;
33893}
33894
33895void
33896setReverseConnectState(UA_Server *server, reverse_connect_context *context,
33897 UA_SecureChannelState newState) {
33898 if(context->state == newState)
33899 return;
33900
33901 context->state = newState;
33902
33903 if(context->stateCallback)
33904 context->stateCallback(server, context->handle, context->state,
33905 context->callbackContext);
33906}
33907
33908static void
33909serverReverseConnectCallback(UA_ConnectionManager *cm, uintptr_t connectionId,
33910 void *application, void **connectionContext,
33911 UA_ConnectionState state, const UA_KeyValueMap *params,
33912 UA_ByteString msg);
33913
33914UA_StatusCode
33915attemptReverseConnect(UA_BinaryProtocolManager *bpm, reverse_connect_context *context) {
33916 UA_Server *server = bpm->server;
33917 UA_ServerConfig *config = &server->config;
33918 UA_EventLoop *el = config->eventLoop;
33919
33920 UA_LOCK_ASSERT(&server->serviceMutex, 1);
33921
33922 /* Find a TCP ConnectionManager */
33923 UA_String tcpString = UA_STRING_STATIC("tcp");
33924 for(UA_EventSource *es = el->eventSources; es != NULL; es = es->next) {
33925 /* Is this a usable connection manager? */
33926 if(es->eventSourceType != UA_EVENTSOURCETYPE_CONNECTIONMANAGER)
33927 continue;
33928
33929 UA_ConnectionManager *cm = (UA_ConnectionManager*)es;
33930 if(!UA_String_equal(p1: &tcpString, p2: &cm->protocol))
33931 continue;
33932
33933 if(es->state != UA_EVENTSOURCESTATE_STARTED)
33934 continue;
33935
33936 /* Set up the parameters */
33937 UA_KeyValuePair params[2];
33938 params[0].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "address");
33939 UA_Variant_setScalar(v: &params[0].value, p: &context->hostname,
33940 type: &UA_TYPES[UA_TYPES_STRING]);
33941 params[1].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "port");
33942 UA_Variant_setScalar(v: &params[1].value, p: &context->port,
33943 type: &UA_TYPES[UA_TYPES_UINT16]);
33944 UA_KeyValueMap kvm = {2, params};
33945
33946 /* Open the connection */
33947 UA_StatusCode res = cm->openConnection(cm, &kvm, bpm, context,
33948 serverReverseConnectCallback);
33949 if(res != UA_STATUSCODE_GOOD) {
33950 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
33951 msg: "Failed to create connection for reverse connect: %s\n",
33952 UA_StatusCode_name(code: res));
33953 }
33954 return res;
33955 }
33956
33957 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
33958 msg: "No ConnectionManager found for reverse connect");
33959 return UA_STATUSCODE_BADINTERNALERROR;
33960}
33961
33962UA_StatusCode
33963UA_Server_addReverseConnect(UA_Server *server, UA_String url,
33964 UA_Server_ReverseConnectStateCallback stateCallback,
33965 void *callbackContext, UA_UInt64 *handle) {
33966 UA_ServerConfig *config = UA_Server_getConfig(server);
33967 UA_ServerComponent *sc =
33968 getServerComponentByName(server, name: UA_STRING(chars: "binary"));
33969 UA_BinaryProtocolManager *bpm = (UA_BinaryProtocolManager*)sc;
33970 if(!bpm) {
33971 UA_LOG_ERROR(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
33972 msg: "No BinaryProtocolManager configured");
33973 return UA_STATUSCODE_BADINTERNALERROR;
33974 }
33975
33976 /* Parse the reverse connect URL */
33977 UA_String hostname = UA_STRING_NULL;
33978 UA_UInt16 port = 0;
33979 UA_StatusCode res = UA_parseEndpointUrl(endpointUrl: &url, outHostname: &hostname, outPort: &port, NULL);
33980 if(res != UA_STATUSCODE_GOOD) {
33981 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
33982 msg: "OPC UA URL is invalid: %.*s",
33983 (int)url.length, url.data);
33984 return res;
33985 }
33986
33987 /* Set up the reverse connection */
33988 reverse_connect_context *newContext = (reverse_connect_context *)
33989 UA_calloc(nmemb: 1, size: sizeof(reverse_connect_context));
33990 if(!newContext)
33991 return UA_STATUSCODE_BADOUTOFMEMORY;
33992
33993 UA_String_copy(src: &hostname, dst: &newContext->hostname);
33994 newContext->port = port;
33995 newContext->handle = ++bpm->lastReverseConnectHandle;
33996 newContext->stateCallback = stateCallback;
33997 newContext->callbackContext = callbackContext;
33998
33999 lockServer(server);
34000
34001 /* Register the retry callback */
34002 setReverseConnectRetryCallback(bpm, true);
34003
34004 /* Register the new reverse connection */
34005 LIST_INSERT_HEAD(&bpm->reverseConnects, newContext, next);
34006
34007 if(handle)
34008 *handle = newContext->handle;
34009
34010 /* Attempt to connect right away */
34011 res = attemptReverseConnect(bpm, context: newContext);
34012
34013 unlockServer(server);
34014 return res;
34015}
34016
34017UA_StatusCode
34018UA_Server_removeReverseConnect(UA_Server *server, UA_UInt64 handle) {
34019 UA_StatusCode result = UA_STATUSCODE_BADNOTFOUND;
34020
34021 lockServer(server);
34022
34023 UA_ServerComponent *sc =
34024 getServerComponentByName(server, name: UA_STRING(chars: "binary"));
34025 UA_BinaryProtocolManager *bpm = (UA_BinaryProtocolManager*)sc;
34026 if(!bpm) {
34027 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
34028 msg: "No BinaryProtocolManager configured");
34029 unlockServer(server);
34030 return UA_STATUSCODE_BADINTERNALERROR;
34031 }
34032
34033 reverse_connect_context *rev, *temp;
34034 LIST_FOREACH_SAFE(rev, &bpm->reverseConnects, next, temp) {
34035 if(rev->handle != handle)
34036 continue;
34037
34038 LIST_REMOVE(rev, next);
34039
34040 /* Connected -> disconnect, otherwise free immediately */
34041 if(rev->currentConnection.connectionId) {
34042 UA_ConnectionManager *cm = rev->currentConnection.connectionManager;
34043 rev->destruction = true;
34044 cm->closeConnection(cm, rev->currentConnection.connectionId);
34045 } else {
34046 setReverseConnectState(server, context: rev, newState: UA_SECURECHANNELSTATE_CLOSED);
34047 UA_String_clear(p: &rev->hostname);
34048 UA_free(ptr: rev);
34049 }
34050 result = UA_STATUSCODE_GOOD;
34051 break;
34052 }
34053
34054 if(LIST_EMPTY(&bpm->reverseConnects))
34055 setReverseConnectRetryCallback(bpm, false);
34056
34057 unlockServer(server);
34058 return result;
34059}
34060
34061static void
34062serverReverseConnectCallbackLocked(UA_ConnectionManager *cm, uintptr_t connectionId,
34063 void *application, void **connectionContext,
34064 UA_ConnectionState state, const UA_KeyValueMap *params,
34065 UA_ByteString msg) {
34066 (void)params;
34067 UA_BinaryProtocolManager *bpm = (UA_BinaryProtocolManager*)application;
34068 UA_LOCK_ASSERT(&bpm->server->serviceMutex, 1);
34069
34070 UA_LOG_DEBUG(logger: bpm->logging, category: UA_LOGCATEGORY_SERVER,
34071 msg: "Activity for reverse connect %lu with state %d",
34072 (long unsigned)connectionId, state);
34073
34074 reverse_connect_context *context = (reverse_connect_context *)*connectionContext;
34075 context->currentConnection.state = state;
34076
34077 /* New connection */
34078 if(context->currentConnection.connectionId == 0) {
34079 context->currentConnection.connectionId = connectionId;
34080 context->currentConnection.connectionManager = cm;
34081 setReverseConnectState(server: bpm->server, context, newState: UA_SECURECHANNELSTATE_CONNECTING);
34082 /* Fall through -- e.g. if state == ESTABLISHED already */
34083 }
34084
34085 /* The connection is closing. This is the last callback for it. */
34086 if(state == UA_CONNECTIONSTATE_CLOSING) {
34087 if(context->channel) {
34088 deleteServerSecureChannel(bpm, channel: context->channel);
34089 context->channel = NULL;
34090 }
34091
34092 /* Delete the ReverseConnect entry */
34093 if(context->destruction) {
34094 setReverseConnectState(server: bpm->server, context, newState: UA_SECURECHANNELSTATE_CLOSED);
34095 LIST_REMOVE(context, next);
34096 UA_String_clear(p: &context->hostname);
34097 UA_free(ptr: context);
34098
34099 /* Check if the Binary Protocol Manager is stopped */
34100 if(bpm->sc.state == UA_LIFECYCLESTATE_STOPPING &&
34101 bpm->serverConnectionsSize == 0 &&
34102 LIST_EMPTY(&bpm->reverseConnects) &&
34103 TAILQ_EMPTY(&bpm->channels)) {
34104 setBinaryProtocolManagerState(server: bpm->server, bpm,
34105 state: UA_LIFECYCLESTATE_STOPPED);
34106 }
34107 return;
34108 }
34109
34110 /* Reset. Will be picked up in the regular retry callback. */
34111 context->currentConnection.connectionId = 0;
34112 setReverseConnectState(server: bpm->server, context, newState: UA_SECURECHANNELSTATE_CONNECTING);
34113 return;
34114 }
34115
34116 if(state != UA_CONNECTIONSTATE_ESTABLISHED)
34117 return;
34118
34119 /* A new connection is opening. This is the only place where
34120 * createSecureChannel is used. */
34121 UA_StatusCode retval = UA_STATUSCODE_GOOD;
34122 if(!context->channel) {
34123 retval = createServerSecureChannel(bpm, cm, connectionId, outChannel: &context->channel);
34124 if(retval != UA_STATUSCODE_GOOD) {
34125 UA_LOG_WARNING(logger: bpm->logging, category: UA_LOGCATEGORY_SERVER,
34126 msg: "TCP %lu\t| Could not accept the reverse "
34127 "connection with status %s",
34128 (unsigned long)context->currentConnection.connectionId,
34129 UA_StatusCode_name(code: retval));
34130 cm->closeConnection(cm, connectionId);
34131 return;
34132 }
34133
34134 /* Send the RHE message */
34135 retval = sendRHEMessage(server: bpm->server, connectionId, cm);
34136 if(retval != UA_STATUSCODE_GOOD) {
34137 UA_LOG_WARNING(logger: bpm->logging, category: UA_LOGCATEGORY_SERVER,
34138 msg: "TCP %lu\t| Could not send the RHE message "
34139 "with status %s",
34140 (unsigned long)context->currentConnection.connectionId,
34141 UA_StatusCode_name(code: retval));
34142 cm->closeConnection(cm, connectionId);
34143 return;
34144 }
34145
34146 context->channel->state = UA_SECURECHANNELSTATE_RHE_SENT;
34147 setReverseConnectState(server: bpm->server, context, newState: UA_SECURECHANNELSTATE_RHE_SENT);
34148 return;
34149 }
34150
34151 /* The connection is fully opened and we have a SecureChannel.
34152 * Process the received buffer */
34153 retval = UA_SecureChannel_loadBuffer(channel: context->channel, buffer: msg);
34154 while(UA_LIKELY(retval == UA_STATUSCODE_GOOD)) {
34155 UA_MessageType messageType;
34156 UA_UInt32 requestId = 0;
34157 UA_ByteString payload = UA_BYTESTRING_NULL;
34158 UA_Boolean copied = false;
34159 retval = UA_SecureChannel_getCompleteMessage(channel: context->channel, messageType: &messageType,
34160 requestId: &requestId, payload: &payload, copied: &copied);
34161 if(retval != UA_STATUSCODE_GOOD || payload.length == 0)
34162 break;
34163 retval = processSecureChannelMessage(server: bpm->server, channel: context->channel,
34164 messagetype: messageType, requestId, message: &payload);
34165 if(copied)
34166 UA_ByteString_clear(p: &payload);
34167 }
34168 retval |= UA_SecureChannel_persistBuffer(channel: context->channel);
34169
34170 if(retval != UA_STATUSCODE_GOOD) {
34171 UA_LOG_WARNING_CHANNEL(bpm->logging, context->channel,
34172 "Processing the message failed with error %s",
34173 UA_StatusCode_name(retval));
34174
34175 /* Processing the buffer failed within the SecureChannel.
34176 * Send an ERR message and close the connection. */
34177 UA_TcpErrorMessage error;
34178 error.error = retval;
34179 error.reason = UA_STRING_NULL;
34180 UA_SecureChannel_sendError(channel: context->channel, error: &error);
34181 UA_SecureChannel_shutdown(channel: context->channel, shutdownReason: UA_SHUTDOWNREASON_ABORT);
34182 setReverseConnectState(server: bpm->server, context, newState: UA_SECURECHANNELSTATE_CLOSING);
34183 return;
34184 }
34185
34186 /* Update the state with the current SecureChannel state */
34187 setReverseConnectState(server: bpm->server, context, newState: context->channel->state);
34188}
34189
34190void
34191serverReverseConnectCallback(UA_ConnectionManager *cm, uintptr_t connectionId,
34192 void *application, void **connectionContext,
34193 UA_ConnectionState state, const UA_KeyValueMap *params,
34194 UA_ByteString msg) {
34195 UA_BinaryProtocolManager *bpm = (UA_BinaryProtocolManager*)application;
34196 lockServer(server: bpm->server);
34197 serverReverseConnectCallbackLocked(cm, connectionId, application, connectionContext,
34198 state, params, msg);
34199 unlockServer(server: bpm->server);
34200}
34201
34202/***************************/
34203/* Binary Protocol Manager */
34204/***************************/
34205
34206static UA_StatusCode
34207UA_BinaryProtocolManager_start(UA_Server *server,
34208 UA_ServerComponent *sc) {
34209 UA_BinaryProtocolManager *bpm = (UA_BinaryProtocolManager*)sc;
34210 UA_ServerConfig *config = &server->config;
34211
34212 UA_StatusCode retVal =
34213 addRepeatedCallback(server, callback: secureChannelHouseKeeping,
34214 data: bpm, interval_ms: 1000.0, callbackId: &bpm->houseKeepingCallbackId);
34215 if(retVal != UA_STATUSCODE_GOOD)
34216 return retVal;
34217
34218 /* Open server sockets */
34219 UA_Boolean haveServerSocket = false;
34220 if(config->serverUrlsSize == 0) {
34221 /* Empty hostname -> listen on all devices */
34222 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
34223 msg: "No Server URL configured. Using \"opc.tcp://:4840\" "
34224 "to configure the listen socket.");
34225 UA_String defaultUrl = UA_STRING(chars: "opc.tcp://:4840");
34226 retVal = createServerConnection(bpm, serverUrl: &defaultUrl);
34227 if(retVal == UA_STATUSCODE_GOOD)
34228 haveServerSocket = true;
34229 } else {
34230 for(size_t i = 0; i < config->serverUrlsSize; i++) {
34231 retVal = createServerConnection(bpm, serverUrl: &config->serverUrls[i]);
34232 if(retVal == UA_STATUSCODE_GOOD)
34233 haveServerSocket = true;
34234 }
34235 }
34236
34237 if(!haveServerSocket) {
34238 UA_LOG_ERROR(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
34239 msg: "The server has no server socket");
34240 return UA_STATUSCODE_BADINTERNALERROR;
34241 }
34242
34243 /* Update the application description to include the server urls for
34244 * discovery. Don't add the urls with an empty host (listening on all
34245 * interfaces) */
34246 for(size_t i = 0; i < config->serverUrlsSize; i++) {
34247 UA_String hostname = UA_STRING_NULL;
34248 UA_String path = UA_STRING_NULL;
34249 UA_UInt16 port = 0;
34250 retVal = UA_parseEndpointUrl(endpointUrl: &config->serverUrls[i],
34251 outHostname: &hostname, outPort: &port, outPath: &path);
34252 if(retVal != UA_STATUSCODE_GOOD || hostname.length == 0)
34253 continue;
34254
34255 /* Check if the ServerUrl is already present in the DiscoveryUrl array.
34256 * Add if not already there. */
34257 size_t j = 0;
34258 for(; j < config->applicationDescription.discoveryUrlsSize; j++) {
34259 if(UA_String_equal(p1: &config->serverUrls[i],
34260 p2: &config->applicationDescription.discoveryUrls[j]))
34261 break;
34262 }
34263 if(j == config->applicationDescription.discoveryUrlsSize) {
34264 retVal =
34265 UA_Array_appendCopy(p: (void**)&config->applicationDescription.discoveryUrls,
34266 size: &config->applicationDescription.discoveryUrlsSize,
34267 newElem: &config->serverUrls[i], type: &UA_TYPES[UA_TYPES_STRING]);
34268 (void)retVal;
34269 }
34270 }
34271
34272 /* Set the state to started */
34273 setBinaryProtocolManagerState(server: bpm->server, bpm,
34274 state: UA_LIFECYCLESTATE_STARTED);
34275
34276 return UA_STATUSCODE_GOOD;
34277}
34278
34279static void
34280UA_BinaryProtocolManager_stop(UA_Server *server,
34281 UA_ServerComponent *comp) {
34282 UA_BinaryProtocolManager *bpm = (UA_BinaryProtocolManager*)comp;
34283
34284 /* Stop the Housekeeping Task */
34285 removeCallback(server, callbackId: bpm->houseKeepingCallbackId);
34286 bpm->houseKeepingCallbackId = 0;
34287
34288 /* Stop the regular retry callback */
34289 setReverseConnectRetryCallback(bpm, false);
34290
34291 /* Close or free all reverse connections */
34292 reverse_connect_context *rev, *rev_tmp;
34293 LIST_FOREACH_SAFE(rev, &bpm->reverseConnects, next, rev_tmp) {
34294 if(rev->currentConnection.connectionId) {
34295 UA_ConnectionManager *cm = rev->currentConnection.connectionManager;
34296 rev->destruction = true;
34297 cm->closeConnection(cm, rev->currentConnection.connectionId);
34298 } else {
34299 LIST_REMOVE(rev, next);
34300 setReverseConnectState(server, context: rev, newState: UA_SECURECHANNELSTATE_CLOSED);
34301 UA_String_clear(p: &rev->hostname);
34302 UA_free(ptr: rev);
34303 }
34304 }
34305
34306 /* Stop all SecureChannels */
34307 channel_entry *entry;
34308 TAILQ_FOREACH(entry, &bpm->channels, pointers) {
34309 UA_SecureChannel_shutdown(channel: &entry->channel, shutdownReason: UA_SHUTDOWNREASON_CLOSE);
34310 }
34311
34312 /* Stop all server sockets */
34313 for(size_t i = 0; i < UA_MAXSERVERCONNECTIONS; i++) {
34314 UA_ServerConnection *sc = &bpm->serverConnections[i];
34315 UA_ConnectionManager *cm = sc->connectionManager;
34316 if(sc->connectionId > 0)
34317 cm->closeConnection(cm, sc->connectionId);
34318 }
34319
34320 /* If open sockets remain, set to STOPPING */
34321 if(bpm->serverConnectionsSize == 0 &&
34322 LIST_EMPTY(&bpm->reverseConnects) &&
34323 TAILQ_EMPTY(&bpm->channels)) {
34324 setBinaryProtocolManagerState(server: bpm->server, bpm,
34325 state: UA_LIFECYCLESTATE_STOPPED);
34326 } else {
34327 setBinaryProtocolManagerState(server: bpm->server, bpm,
34328 state: UA_LIFECYCLESTATE_STOPPING);
34329 }
34330}
34331
34332static UA_StatusCode
34333UA_BinaryProtocolManager_free(UA_Server *server,
34334 UA_ServerComponent *sc) {
34335 if(sc->state != UA_LIFECYCLESTATE_STOPPED)
34336 return UA_STATUSCODE_BADINTERNALERROR;
34337
34338 UA_free(ptr: sc);
34339 return UA_STATUSCODE_GOOD;
34340}
34341
34342UA_ServerComponent *
34343UA_BinaryProtocolManager_new(UA_Server *server) {
34344 UA_BinaryProtocolManager *bpm = (UA_BinaryProtocolManager*)
34345 UA_calloc(nmemb: 1, size: sizeof(UA_BinaryProtocolManager));
34346 if(!bpm)
34347 return NULL;
34348
34349 bpm->server = server;
34350 bpm->logging = server->config.logging;
34351
34352 /* Initialize SecureChannel */
34353 TAILQ_INIT(&bpm->channels);
34354
34355 /* TODO: use an ID that is likely to be unique after a restart */
34356 bpm->lastChannelId = STARTCHANNELID;
34357 bpm->lastTokenId = STARTTOKENID;
34358
34359 bpm->sc.name = UA_STRING(chars: "binary");
34360 bpm->sc.start = UA_BinaryProtocolManager_start;
34361 bpm->sc.stop = UA_BinaryProtocolManager_stop;
34362 bpm->sc.free = UA_BinaryProtocolManager_free;
34363 return &bpm->sc;
34364}
34365
34366/**** amalgamated original file "/src/server/ua_server_utils.c" ****/
34367
34368/* This Source Code Form is subject to the terms of the Mozilla Public
34369 * License, v. 2.0. If a copy of the MPL was not distributed with this
34370 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
34371 *
34372 * Copyright 2016-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
34373 * Copyright 2016 (c) Lorenz Haas
34374 * Copyright 2017 (c) frax2222
34375 * Copyright 2017 (c) Florian Palm
34376 * Copyright 2017-2018 (c) Stefan Profanter, fortiss GmbH
34377 * Copyright 2017 (c) Julian Grothoff
34378 */
34379
34380
34381const UA_DataType *
34382UA_Server_findDataType(UA_Server *server, const UA_NodeId *typeId) {
34383 return UA_findDataTypeWithCustom(typeId, customTypes: server->config.customDataTypes);
34384}
34385
34386/********************************/
34387/* Information Model Operations */
34388/********************************/
34389
34390static void *
34391returnFirstType(void *context, UA_ReferenceTarget *t) {
34392 UA_Server *server = (UA_Server*)context;
34393 /* Don't release the node that is returned.
34394 * Continues to iterate if NULL is returned. */
34395 return (void*)(uintptr_t)UA_NODESTORE_GETFROMREF(server, target: t->targetId);
34396}
34397
34398const UA_Node *
34399getNodeType(UA_Server *server, const UA_NodeHead *head) {
34400 /* The reference to the parent is different for variable and variabletype */
34401 UA_Byte parentRefIndex;
34402 UA_Boolean inverse;
34403 switch(head->nodeClass) {
34404 case UA_NODECLASS_OBJECT:
34405 case UA_NODECLASS_VARIABLE:
34406 parentRefIndex = UA_REFERENCETYPEINDEX_HASTYPEDEFINITION;
34407 inverse = false;
34408 break;
34409 case UA_NODECLASS_OBJECTTYPE:
34410 case UA_NODECLASS_VARIABLETYPE:
34411 case UA_NODECLASS_REFERENCETYPE:
34412 case UA_NODECLASS_DATATYPE:
34413 parentRefIndex = UA_REFERENCETYPEINDEX_HASSUBTYPE;
34414 inverse = true;
34415 break;
34416 default:
34417 return NULL;
34418 }
34419
34420 /* Return the first matching candidate */
34421 for(size_t i = 0; i < head->referencesSize; ++i) {
34422 UA_NodeReferenceKind *rk = &head->references[i];
34423 if(rk->isInverse != inverse)
34424 continue;
34425 if(rk->referenceTypeIndex != parentRefIndex)
34426 continue;
34427 const UA_Node *type = (const UA_Node*)
34428 UA_NodeReferenceKind_iterate(rk, callback: returnFirstType, context: server);
34429 if(type)
34430 return type;
34431 }
34432
34433 return NULL;
34434}
34435
34436UA_Boolean
34437UA_Node_hasSubTypeOrInstances(const UA_NodeHead *head) {
34438 for(size_t i = 0; i < head->referencesSize; ++i) {
34439 if(head->references[i].isInverse == false &&
34440 head->references[i].referenceTypeIndex == UA_REFERENCETYPEINDEX_HASSUBTYPE)
34441 return true;
34442 if(head->references[i].isInverse == true &&
34443 head->references[i].referenceTypeIndex == UA_REFERENCETYPEINDEX_HASTYPEDEFINITION)
34444 return true;
34445 }
34446 return false;
34447}
34448
34449UA_StatusCode
34450getParentTypeAndInterfaceHierarchy(UA_Server *server, const UA_NodeId *typeNode,
34451 UA_NodeId **typeHierarchy, size_t *typeHierarchySize) {
34452 UA_ReferenceTypeSet reftypes_subtype =
34453 UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASSUBTYPE);
34454 UA_ExpandedNodeId *subTypes = NULL;
34455 size_t subTypesSize = 0;
34456 UA_StatusCode retval = browseRecursive(server, startNodesSize: 1, startNodes: typeNode,
34457 browseDirection: UA_BROWSEDIRECTION_INVERSE,
34458 refTypes: &reftypes_subtype, nodeClassMask: UA_NODECLASS_UNSPECIFIED,
34459 false, resultsSize: &subTypesSize, results: &subTypes);
34460 if(retval != UA_STATUSCODE_GOOD)
34461 return retval;
34462
34463 UA_assert(subTypesSize < 1000);
34464
34465 UA_ReferenceTypeSet reftypes_interface =
34466 UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASINTERFACE);
34467 UA_ExpandedNodeId *interfaces = NULL;
34468 size_t interfacesSize = 0;
34469 retval = browseRecursive(server, startNodesSize: 1, startNodes: typeNode, browseDirection: UA_BROWSEDIRECTION_FORWARD,
34470 refTypes: &reftypes_interface, nodeClassMask: UA_NODECLASS_UNSPECIFIED,
34471 false, resultsSize: &interfacesSize, results: &interfaces);
34472 if(retval != UA_STATUSCODE_GOOD) {
34473 UA_Array_delete(p: subTypes, size: subTypesSize, type: &UA_TYPES[UA_TYPES_NODEID]);
34474 return retval;
34475 }
34476
34477 UA_assert(interfacesSize < 1000);
34478
34479 UA_NodeId *hierarchy = (UA_NodeId*)
34480 UA_malloc(size: sizeof(UA_NodeId) * (1 + subTypesSize + interfacesSize));
34481 if(!hierarchy) {
34482 UA_Array_delete(p: subTypes, size: subTypesSize, type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34483 UA_Array_delete(p: interfaces, size: interfacesSize, type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34484 return UA_STATUSCODE_BADOUTOFMEMORY;
34485 }
34486
34487 retval = UA_NodeId_copy(src: typeNode, dst: hierarchy);
34488 if(retval != UA_STATUSCODE_GOOD) {
34489 UA_free(ptr: hierarchy);
34490 UA_Array_delete(p: subTypes, size: subTypesSize, type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34491 UA_Array_delete(p: interfaces, size: interfacesSize, type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34492 return UA_STATUSCODE_BADOUTOFMEMORY;
34493 }
34494
34495 for(size_t i = 0; i < subTypesSize; i++) {
34496 hierarchy[i+1] = subTypes[i].nodeId;
34497 UA_NodeId_init(p: &subTypes[i].nodeId);
34498 }
34499 for(size_t i = 0; i < interfacesSize; i++) {
34500 hierarchy[i+1+subTypesSize] = interfaces[i].nodeId;
34501 UA_NodeId_init(p: &interfaces[i].nodeId);
34502 }
34503
34504 *typeHierarchy = hierarchy;
34505 *typeHierarchySize = subTypesSize + interfacesSize + 1;
34506
34507 UA_assert(*typeHierarchySize < 1000);
34508
34509 UA_Array_delete(p: subTypes, size: subTypesSize, type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34510 UA_Array_delete(p: interfaces, size: interfacesSize, type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34511 return UA_STATUSCODE_GOOD;
34512}
34513
34514UA_StatusCode
34515getAllInterfaceChildNodeIds(UA_Server *server, const UA_NodeId *objectNode,
34516 const UA_NodeId *objectTypeNode,
34517 UA_NodeId **interfaceChildNodes,
34518 size_t *interfaceChildNodesSize) {
34519 if(interfaceChildNodesSize == NULL || interfaceChildNodes == NULL)
34520 return UA_STATUSCODE_BADINTERNALERROR;
34521 *interfaceChildNodesSize = 0;
34522 *interfaceChildNodes = NULL;
34523
34524 UA_ExpandedNodeId *hasInterfaceCandidates = NULL;
34525 size_t hasInterfaceCandidatesSize = 0;
34526 UA_ReferenceTypeSet reftypes_subtype =
34527 UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASSUBTYPE);
34528
34529 UA_StatusCode retval =
34530 browseRecursive(server, startNodesSize: 1, startNodes: objectTypeNode, browseDirection: UA_BROWSEDIRECTION_INVERSE,
34531 refTypes: &reftypes_subtype, nodeClassMask: UA_NODECLASS_OBJECTTYPE,
34532 true, resultsSize: &hasInterfaceCandidatesSize,
34533 results: &hasInterfaceCandidates);
34534
34535 if(retval != UA_STATUSCODE_GOOD)
34536 return retval;
34537
34538 /* The interface could also have been added manually before calling UA_Server_addNode_finish
34539 * This can be handled by adding the object node as a start node for the HasInterface lookup */
34540 UA_ExpandedNodeId *resizedHasInterfaceCandidates = (UA_ExpandedNodeId*)
34541 UA_realloc(ptr: hasInterfaceCandidates,
34542 size: (hasInterfaceCandidatesSize + 1) * sizeof(UA_ExpandedNodeId));
34543
34544 if(!resizedHasInterfaceCandidates) {
34545 if(hasInterfaceCandidates)
34546 UA_Array_delete(p: hasInterfaceCandidates, size: hasInterfaceCandidatesSize,
34547 type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34548 return UA_STATUSCODE_BADOUTOFMEMORY;
34549 }
34550
34551 hasInterfaceCandidates = resizedHasInterfaceCandidates;
34552 hasInterfaceCandidatesSize += 1;
34553 UA_ExpandedNodeId_init(p: &hasInterfaceCandidates[hasInterfaceCandidatesSize - 1]);
34554
34555 UA_ExpandedNodeId_init(p: &hasInterfaceCandidates[hasInterfaceCandidatesSize - 1]);
34556 UA_NodeId_copy(src: objectNode, dst: &hasInterfaceCandidates[hasInterfaceCandidatesSize - 1].nodeId);
34557
34558 size_t outputIndex = 0;
34559
34560 for(size_t i = 0; i < hasInterfaceCandidatesSize; ++i) {
34561 UA_ReferenceTypeSet reftypes_interface =
34562 UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASINTERFACE);
34563 UA_ExpandedNodeId *interfaceChildren = NULL;
34564 size_t interfacesChildrenSize = 0;
34565 retval = browseRecursive(server, startNodesSize: 1, startNodes: &hasInterfaceCandidates[i].nodeId,
34566 browseDirection: UA_BROWSEDIRECTION_FORWARD,
34567 refTypes: &reftypes_interface, nodeClassMask: UA_NODECLASS_OBJECTTYPE,
34568 false, resultsSize: &interfacesChildrenSize, results: &interfaceChildren);
34569 if(retval != UA_STATUSCODE_GOOD) {
34570 UA_Array_delete(p: hasInterfaceCandidates, size: hasInterfaceCandidatesSize,
34571 type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34572 if(*interfaceChildNodesSize) {
34573 UA_Array_delete(p: *interfaceChildNodes, size: *interfaceChildNodesSize,
34574 type: &UA_TYPES[UA_TYPES_NODEID]);
34575 *interfaceChildNodesSize = 0;
34576 }
34577 return retval;
34578 }
34579
34580 UA_assert(interfacesChildrenSize < 1000);
34581
34582 if(interfacesChildrenSize == 0) {
34583 continue;
34584 }
34585
34586 if(!*interfaceChildNodes) {
34587 *interfaceChildNodes = (UA_NodeId*)
34588 UA_calloc(nmemb: interfacesChildrenSize, size: sizeof(UA_NodeId));
34589 *interfaceChildNodesSize = interfacesChildrenSize;
34590
34591 if(!*interfaceChildNodes) {
34592 UA_Array_delete(p: interfaceChildren, size: interfacesChildrenSize,
34593 type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34594 UA_Array_delete(p: hasInterfaceCandidates, size: hasInterfaceCandidatesSize,
34595 type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34596 return UA_STATUSCODE_BADOUTOFMEMORY;
34597 }
34598 } else {
34599 UA_NodeId *resizedInterfaceChildNodes = (UA_NodeId*)
34600 UA_realloc(ptr: *interfaceChildNodes,
34601 size: ((*interfaceChildNodesSize + interfacesChildrenSize) * sizeof(UA_NodeId)));
34602
34603 if(!resizedInterfaceChildNodes) {
34604 UA_Array_delete(p: hasInterfaceCandidates, size: hasInterfaceCandidatesSize,
34605 type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34606 UA_Array_delete(p: interfaceChildren, size: interfacesChildrenSize,
34607 type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34608 return UA_STATUSCODE_BADOUTOFMEMORY;
34609 }
34610
34611 const size_t oldSize = *interfaceChildNodesSize;
34612 *interfaceChildNodesSize += interfacesChildrenSize;
34613 *interfaceChildNodes = resizedInterfaceChildNodes;
34614
34615 for(size_t j = oldSize; j < *interfaceChildNodesSize; ++j)
34616 UA_NodeId_init(p: &(*interfaceChildNodes)[j]);
34617 }
34618
34619 for(size_t j = 0; j < interfacesChildrenSize; j++) {
34620 (*interfaceChildNodes)[outputIndex++] = interfaceChildren[j].nodeId;
34621 }
34622
34623 UA_assert(*interfaceChildNodesSize < 1000);
34624 UA_Array_delete(p: interfaceChildren, size: interfacesChildrenSize, type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34625 }
34626
34627 UA_Array_delete(p: hasInterfaceCandidates, size: hasInterfaceCandidatesSize, type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
34628
34629 return UA_STATUSCODE_GOOD;
34630}
34631
34632/* For mulithreading: make a copy of the node, edit and replace.
34633 * For singlethreading: edit the original */
34634UA_StatusCode
34635UA_Server_editNode(UA_Server *server, UA_Session *session,
34636 const UA_NodeId *nodeId, UA_EditNodeCallback callback,
34637 void *data) {
34638#ifndef UA_ENABLE_IMMUTABLE_NODES
34639 /* Get the node and process it in-situ */
34640 const UA_Node *node = UA_NODESTORE_GET(server, nodeId);
34641 if(!node)
34642 return UA_STATUSCODE_BADNODEIDUNKNOWN;
34643 UA_StatusCode retval = callback(server, session, (UA_Node*)(uintptr_t)node, data);
34644 UA_NODESTORE_RELEASE(server, node);
34645 return retval;
34646#else
34647 UA_StatusCode retval;
34648 do {
34649 /* Get an editable copy of the node */
34650 UA_Node *node;
34651 retval = UA_NODESTORE_GETCOPY(server, nodeId, &node);
34652 if(retval != UA_STATUSCODE_GOOD)
34653 return retval;
34654
34655 /* Run the operation on the copy */
34656 retval = callback(server, session, node, data);
34657 if(retval != UA_STATUSCODE_GOOD) {
34658 UA_NODESTORE_DELETE(server, node);
34659 return retval;
34660 }
34661
34662 /* Replace the node */
34663 retval = UA_NODESTORE_REPLACE(server, node);
34664 } while(retval != UA_STATUSCODE_GOOD);
34665 return retval;
34666#endif
34667}
34668
34669UA_StatusCode
34670UA_Server_processServiceOperations(UA_Server *server, UA_Session *session,
34671 UA_ServiceOperation operationCallback,
34672 const void *context, const size_t *requestOperations,
34673 const UA_DataType *requestOperationsType,
34674 size_t *responseOperations,
34675 const UA_DataType *responseOperationsType) {
34676 size_t ops = *requestOperations;
34677 if(ops == 0)
34678 return UA_STATUSCODE_BADNOTHINGTODO;
34679
34680 /* No padding after size_t */
34681 void **respPos = (void**)((uintptr_t)responseOperations + sizeof(size_t));
34682 *respPos = UA_Array_new(size: ops, type: responseOperationsType);
34683 if(!(*respPos))
34684 return UA_STATUSCODE_BADOUTOFMEMORY;
34685
34686 *responseOperations = ops;
34687 uintptr_t respOp = (uintptr_t)*respPos;
34688 /* No padding after size_t */
34689 uintptr_t reqOp = *(uintptr_t*)((uintptr_t)requestOperations + sizeof(size_t));
34690 for(size_t i = 0; i < ops; i++) {
34691 operationCallback(server, session, context, (void*)reqOp, (void*)respOp);
34692 reqOp += requestOperationsType->memSize;
34693 respOp += responseOperationsType->memSize;
34694 }
34695 return UA_STATUSCODE_GOOD;
34696}
34697
34698/* A few global NodeId definitions */
34699const UA_NodeId subtypeId = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASSUBTYPE}};
34700const UA_NodeId hierarchicalReferences = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HIERARCHICALREFERENCES}};
34701
34702/*********************************/
34703/* Default attribute definitions */
34704/*********************************/
34705
34706const UA_ObjectAttributes UA_ObjectAttributes_default = {
34707 0, /* specifiedAttributes */
34708 {{0, NULL}, {0, NULL}}, /* displayName */
34709 {{0, NULL}, {0, NULL}}, /* description */
34710 0, 0, /* writeMask (userWriteMask) */
34711 0 /* eventNotifier */
34712};
34713
34714const UA_VariableAttributes UA_VariableAttributes_default = {
34715 0, /* specifiedAttributes */
34716 {{0, NULL}, {0, NULL}}, /* displayName */
34717 {{0, NULL}, {0, NULL}}, /* description */
34718 0, 0, /* writeMask (userWriteMask) */
34719 {NULL, UA_VARIANT_DATA,
34720 0, NULL, 0, NULL}, /* value */
34721 {0, UA_NODEIDTYPE_NUMERIC,
34722 {UA_NS0ID_BASEDATATYPE}}, /* dataType */
34723 UA_VALUERANK_ANY, /* valueRank */
34724 0, NULL, /* arrayDimensions */
34725 UA_ACCESSLEVELMASK_READ | /* accessLevel */
34726 UA_ACCESSLEVELMASK_STATUSWRITE |
34727 UA_ACCESSLEVELMASK_TIMESTAMPWRITE,
34728 0, /* userAccessLevel */
34729 0.0, /* minimumSamplingInterval */
34730 false /* historizing */
34731};
34732
34733const UA_MethodAttributes UA_MethodAttributes_default = {
34734 0, /* specifiedAttributes */
34735 {{0, NULL}, {0, NULL}}, /* displayName */
34736 {{0, NULL}, {0, NULL}}, /* description */
34737 0, 0, /* writeMask (userWriteMask) */
34738 true, true /* executable (userExecutable) */
34739};
34740
34741const UA_ObjectTypeAttributes UA_ObjectTypeAttributes_default = {
34742 0, /* specifiedAttributes */
34743 {{0, NULL}, {0, NULL}}, /* displayName */
34744 {{0, NULL}, {0, NULL}}, /* description */
34745 0, 0, /* writeMask (userWriteMask) */
34746 false /* isAbstract */
34747};
34748
34749const UA_VariableTypeAttributes UA_VariableTypeAttributes_default = {
34750 0, /* specifiedAttributes */
34751 {{0, NULL}, {0, NULL}}, /* displayName */
34752 {{0, NULL}, {0, NULL}}, /* description */
34753 0, 0, /* writeMask (userWriteMask) */
34754 {NULL, UA_VARIANT_DATA,
34755 0, NULL, 0, NULL}, /* value */
34756 {0, UA_NODEIDTYPE_NUMERIC,
34757 {UA_NS0ID_BASEDATATYPE}}, /* dataType */
34758 UA_VALUERANK_ANY, /* valueRank */
34759 0, NULL, /* arrayDimensions */
34760 false /* isAbstract */
34761};
34762
34763const UA_ReferenceTypeAttributes UA_ReferenceTypeAttributes_default = {
34764 0, /* specifiedAttributes */
34765 {{0, NULL}, {0, NULL}}, /* displayName */
34766 {{0, NULL}, {0, NULL}}, /* description */
34767 0, 0, /* writeMask (userWriteMask) */
34768 false, /* isAbstract */
34769 false, /* symmetric */
34770 {{0, NULL}, {0, NULL}} /* inverseName */
34771};
34772
34773const UA_DataTypeAttributes UA_DataTypeAttributes_default = {
34774 0, /* specifiedAttributes */
34775 {{0, NULL}, {0, NULL}}, /* displayName */
34776 {{0, NULL}, {0, NULL}}, /* description */
34777 0, 0, /* writeMask (userWriteMask) */
34778 false /* isAbstract */
34779};
34780
34781const UA_ViewAttributes UA_ViewAttributes_default = {
34782 0, /* specifiedAttributes */
34783 {{0, NULL}, {0, NULL}}, /* displayName */
34784 {{0, NULL}, {0, NULL}}, /* description */
34785 0, 0, /* writeMask (userWriteMask) */
34786 false, /* containsNoLoops */
34787 0 /* eventNotifier */
34788};
34789
34790
34791/**** amalgamated original file "/src/server/ua_server_async.c" ****/
34792
34793/* This Source Code Form is subject to the terms of the Mozilla Public
34794 * License, v. 2.0. If a copy of the MPL was not distributed with this
34795 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
34796 *
34797 * Copyright 2019 (c) Fraunhofer IOSB (Author: Klaus Schick)
34798 * Copyright 2019 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
34799 */
34800
34801
34802#if UA_MULTITHREADING >= 100
34803
34804static void
34805UA_AsyncOperation_delete(UA_AsyncOperation *ar) {
34806 UA_CallMethodRequest_clear(&ar->request);
34807 UA_CallMethodResult_clear(&ar->response);
34808 UA_free(ar);
34809}
34810
34811static void
34812UA_AsyncManager_sendAsyncResponse(UA_AsyncManager *am, UA_Server *server,
34813 UA_AsyncResponse *ar) {
34814 UA_LOCK_ASSERT(&server->serviceMutex, 1);
34815 UA_LOCK_ASSERT(&am->queueLock, 1);
34816
34817 /* Get the session */
34818 UA_Session* session = getSessionById(server, &ar->sessionId);
34819 if(!session) {
34820 UA_String sessionId = UA_STRING_NULL;
34821 UA_NodeId_print(&ar->sessionId, &sessionId);
34822 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_SERVER,
34823 "Async Service: Session %.*s no longer exists",
34824 (int)sessionId.length, sessionId.data);
34825 UA_String_clear(&sessionId);
34826 UA_AsyncManager_removeAsyncResponse(&server->asyncManager, ar);
34827 return;
34828 }
34829
34830 /* Check the channel */
34831 UA_SecureChannel *channel = session->header.channel;
34832 if(!channel) {
34833 UA_LOG_WARNING_SESSION(server->config.logging, session,
34834 "Async Service Response cannot be sent. "
34835 "No SecureChannel for the session.");
34836 UA_AsyncManager_removeAsyncResponse(&server->asyncManager, ar);
34837 return;
34838 }
34839
34840 /* Set the request handle */
34841 UA_ResponseHeader *responseHeader = (UA_ResponseHeader*)
34842 &ar->response.callResponse.responseHeader;
34843 responseHeader->requestHandle = ar->requestHandle;
34844
34845 /* Send the Response */
34846 UA_StatusCode res =
34847 sendResponse(server, session, channel, ar->requestId,
34848 (UA_Response*)&ar->response, &UA_TYPES[UA_TYPES_CALLRESPONSE]);
34849 if(res != UA_STATUSCODE_GOOD) {
34850 UA_LOG_WARNING_SESSION(server->config.logging, session,
34851 "Async Response for Req# %" PRIu32 " failed "
34852 "with StatusCode %s", ar->requestId,
34853 UA_StatusCode_name(res));
34854 }
34855 UA_AsyncManager_removeAsyncResponse(&server->asyncManager, ar);
34856}
34857
34858/* Integrate operation result in the AsyncResponse and send out the response if
34859 * it is ready. */
34860static UA_Boolean
34861integrateOperationResult(UA_AsyncManager *am, UA_Server *server,
34862 UA_AsyncOperation *ao) {
34863 UA_LOCK_ASSERT(&server->serviceMutex, 1);
34864 UA_LOCK_ASSERT(&am->queueLock, 1);
34865
34866 /* Grab the open request, so we can continue to construct the response */
34867 UA_AsyncResponse *ar = ao->parent;
34868
34869 /* Reduce the number of open results */
34870 ar->opCountdown -= 1;
34871
34872 UA_LOG_DEBUG(server->config.logging, UA_LOGCATEGORY_SERVER,
34873 "Return result in the server thread with %" PRIu32 " remaining",
34874 ar->opCountdown);
34875
34876 /* Move the UA_CallMethodResult to UA_CallResponse */
34877 ar->response.callResponse.results[ao->index] = ao->response;
34878 UA_CallMethodResult_init(&ao->response);
34879
34880 /* Done with all operations -> send the response */
34881 UA_Boolean done = (ar->opCountdown == 0);
34882 if(done)
34883 UA_AsyncManager_sendAsyncResponse(am, server, ar);
34884 return done;
34885}
34886
34887/* Process all operations in the result queue -> move content over to the
34888 * AsyncResponse. This is only done by the server thread. Returns the nmber of
34889 * completed async sesponses. */
34890static UA_UInt32
34891processAsyncResults(UA_Server *server) {
34892 UA_AsyncManager *am = &server->asyncManager;
34893 UA_LOCK_ASSERT(&server->serviceMutex, 1);
34894
34895 UA_UInt32 count = 0;
34896 UA_AsyncOperation *ao;
34897 UA_LOCK(&am->queueLock);
34898 while((ao = TAILQ_FIRST(&am->resultQueue))) {
34899 TAILQ_REMOVE(&am->resultQueue, ao, pointers);
34900 if(integrateOperationResult(am, server, ao))
34901 count++;
34902 UA_AsyncOperation_delete(ao);
34903 /* Pacify clang-analyzer */
34904 UA_assert(TAILQ_FIRST(&am->resultQueue) != ao);
34905 am->opsCount--;
34906 }
34907 UA_UNLOCK(&am->queueLock);
34908 return count;
34909}
34910
34911/* Check if any operations have timed out */
34912static void
34913checkTimeouts(UA_Server *server, void *_) {
34914 /* Timeouts are not configured */
34915 if(server->config.asyncOperationTimeout <= 0.0)
34916 return;
34917
34918 UA_AsyncManager *am = &server->asyncManager;
34919 const UA_DateTime tNow = UA_DateTime_now();
34920
34921 UA_LOCK(&am->queueLock);
34922
34923 /* Loop over the queue of dispatched ops */
34924 UA_AsyncOperation *op = NULL, *op_tmp = NULL;
34925 TAILQ_FOREACH_SAFE(op, &am->dispatchedQueue, pointers, op_tmp) {
34926 /* The timeout has not passed. Also for all elements following in the queue. */
34927 if(tNow <= op->parent->timeout)
34928 break;
34929
34930 /* Mark as timed out and put it into the result queue */
34931 op->response.statusCode = UA_STATUSCODE_BADTIMEOUT;
34932 TAILQ_REMOVE(&am->dispatchedQueue, op, pointers);
34933 TAILQ_INSERT_TAIL(&am->resultQueue, op, pointers);
34934 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_SERVER,
34935 "Operation was removed due to a timeout");
34936 }
34937
34938 /* Loop over the queue of new ops */
34939 TAILQ_FOREACH_SAFE(op, &am->newQueue, pointers, op_tmp) {
34940 /* The timeout has not passed. Also for all elements following in the queue. */
34941 if(tNow <= op->parent->timeout)
34942 break;
34943
34944 /* Mark as timed out and put it into the result queue */
34945 op->response.statusCode = UA_STATUSCODE_BADTIMEOUT;
34946 TAILQ_REMOVE(&am->newQueue, op, pointers);
34947 TAILQ_INSERT_TAIL(&am->resultQueue, op, pointers);
34948 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_SERVER,
34949 "Operation was removed due to a timeout");
34950 }
34951
34952 UA_UNLOCK(&am->queueLock);
34953
34954 /* Integrate async results and send out complete responses */
34955 lockServer(server);
34956 processAsyncResults(server);
34957 unlockServer(server);
34958}
34959
34960void
34961UA_AsyncManager_init(UA_AsyncManager *am, UA_Server *server) {
34962 memset(am, 0, sizeof(UA_AsyncManager));
34963 TAILQ_INIT(&am->asyncResponses);
34964 TAILQ_INIT(&am->newQueue);
34965 TAILQ_INIT(&am->dispatchedQueue);
34966 TAILQ_INIT(&am->resultQueue);
34967 UA_LOCK_INIT(&am->queueLock);
34968
34969 /* Add a regular callback for cleanup and sending finished responses at a
34970 * 1s interval. */
34971 addRepeatedCallback(server, (UA_ServerCallback)checkTimeouts,
34972 NULL, 1000.0, &am->checkTimeoutCallbackId);
34973}
34974
34975void
34976UA_AsyncManager_clear(UA_AsyncManager *am, UA_Server *server) {
34977 removeCallback(server, am->checkTimeoutCallbackId);
34978
34979 UA_AsyncOperation *ar, *ar_tmp;
34980
34981 /* Clean up queues */
34982 UA_LOCK(&am->queueLock);
34983 TAILQ_FOREACH_SAFE(ar, &am->newQueue, pointers, ar_tmp) {
34984 TAILQ_REMOVE(&am->newQueue, ar, pointers);
34985 UA_AsyncOperation_delete(ar);
34986 }
34987 TAILQ_FOREACH_SAFE(ar, &am->dispatchedQueue, pointers, ar_tmp) {
34988 TAILQ_REMOVE(&am->dispatchedQueue, ar, pointers);
34989 UA_AsyncOperation_delete(ar);
34990 }
34991 TAILQ_FOREACH_SAFE(ar, &am->resultQueue, pointers, ar_tmp) {
34992 TAILQ_REMOVE(&am->resultQueue, ar, pointers);
34993 UA_AsyncOperation_delete(ar);
34994 }
34995 UA_UNLOCK(&am->queueLock);
34996
34997 /* Remove responses */
34998 UA_AsyncResponse *current, *temp;
34999 TAILQ_FOREACH_SAFE(current, &am->asyncResponses, pointers, temp) {
35000 UA_AsyncManager_removeAsyncResponse(am, current);
35001 }
35002
35003 /* Delete all locks */
35004 UA_LOCK_DESTROY(&am->queueLock);
35005}
35006
35007UA_StatusCode
35008UA_AsyncManager_createAsyncResponse(UA_AsyncManager *am, UA_Server *server,
35009 const UA_NodeId *sessionId,
35010 const UA_UInt32 requestId, const UA_UInt32 requestHandle,
35011 const UA_AsyncOperationType operationType,
35012 UA_AsyncResponse **outAr) {
35013 UA_AsyncResponse *newentry = (UA_AsyncResponse*)UA_calloc(1, sizeof(UA_AsyncResponse));
35014 if(!newentry)
35015 return UA_STATUSCODE_BADOUTOFMEMORY;
35016
35017 UA_StatusCode res = UA_NodeId_copy(sessionId, &newentry->sessionId);
35018 if(res != UA_STATUSCODE_GOOD) {
35019 UA_free(newentry);
35020 return res;
35021 }
35022
35023 am->asyncResponsesCount += 1;
35024 newentry->requestId = requestId;
35025 newentry->requestHandle = requestHandle;
35026 newentry->timeout = UA_DateTime_now();
35027 if(server->config.asyncOperationTimeout > 0.0)
35028 newentry->timeout += (UA_DateTime)
35029 (server->config.asyncOperationTimeout * (UA_DateTime)UA_DATETIME_MSEC);
35030 TAILQ_INSERT_TAIL(&am->asyncResponses, newentry, pointers);
35031
35032 *outAr = newentry;
35033 return UA_STATUSCODE_GOOD;
35034}
35035
35036/* Remove entry and free all allocated data */
35037void
35038UA_AsyncManager_removeAsyncResponse(UA_AsyncManager *am, UA_AsyncResponse *ar) {
35039 TAILQ_REMOVE(&am->asyncResponses, ar, pointers);
35040 am->asyncResponsesCount -= 1;
35041 UA_CallResponse_clear(&ar->response.callResponse);
35042 UA_NodeId_clear(&ar->sessionId);
35043 UA_free(ar);
35044}
35045
35046/* Enqueue next MethodRequest */
35047UA_StatusCode
35048UA_AsyncManager_createAsyncOp(UA_AsyncManager *am, UA_Server *server,
35049 UA_AsyncResponse *ar, size_t opIndex,
35050 const UA_CallMethodRequest *opRequest) {
35051 if(server->config.maxAsyncOperationQueueSize != 0 &&
35052 am->opsCount >= server->config.maxAsyncOperationQueueSize) {
35053 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_SERVER,
35054 "UA_Server_SetNextAsyncMethod: Queue exceeds limit (%d).",
35055 (int unsigned)server->config.maxAsyncOperationQueueSize);
35056 return UA_STATUSCODE_BADUNEXPECTEDERROR;
35057 }
35058
35059 UA_AsyncOperation *ao = (UA_AsyncOperation*)UA_calloc(1, sizeof(UA_AsyncOperation));
35060 if(!ao) {
35061 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
35062 "UA_Server_SetNextAsyncMethod: Mem alloc failed.");
35063 return UA_STATUSCODE_BADOUTOFMEMORY;
35064 }
35065
35066 UA_StatusCode result = UA_CallMethodRequest_copy(opRequest, &ao->request);
35067 if(result != UA_STATUSCODE_GOOD) {
35068 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
35069 "UA_Server_SetAsyncMethodResult: UA_CallMethodRequest_copy failed.");
35070 UA_free(ao);
35071 return result;
35072 }
35073
35074 UA_CallMethodResult_init(&ao->response);
35075 ao->index = opIndex;
35076 ao->parent = ar;
35077
35078 UA_LOCK(&am->queueLock);
35079 TAILQ_INSERT_TAIL(&am->newQueue, ao, pointers);
35080 am->opsCount++;
35081 ar->opCountdown++;
35082 UA_UNLOCK(&am->queueLock);
35083
35084 if(server->config.asyncOperationNotifyCallback)
35085 server->config.asyncOperationNotifyCallback(server);
35086
35087 return UA_STATUSCODE_GOOD;
35088}
35089
35090/* Get and remove next Method Call Request */
35091UA_Boolean
35092UA_Server_getAsyncOperationNonBlocking(UA_Server *server, UA_AsyncOperationType *type,
35093 const UA_AsyncOperationRequest **request,
35094 void **context, UA_DateTime *timeout) {
35095 UA_AsyncManager *am = &server->asyncManager;
35096
35097 UA_Boolean bRV = false;
35098 *type = UA_ASYNCOPERATIONTYPE_INVALID;
35099 UA_LOCK(&am->queueLock);
35100 UA_AsyncOperation *ao = TAILQ_FIRST(&am->newQueue);
35101 if(ao) {
35102 TAILQ_REMOVE(&am->newQueue, ao, pointers);
35103 TAILQ_INSERT_TAIL(&am->dispatchedQueue, ao, pointers);
35104 *type = UA_ASYNCOPERATIONTYPE_CALL;
35105 *request = (UA_AsyncOperationRequest*)&ao->request;
35106 *context = (void*)ao;
35107 if(timeout)
35108 *timeout = ao->parent->timeout;
35109 bRV = true;
35110 }
35111 UA_UNLOCK(&am->queueLock);
35112
35113 return bRV;
35114}
35115
35116/* Worker submits Method Call Response */
35117void
35118UA_Server_setAsyncOperationResult(UA_Server *server,
35119 const UA_AsyncOperationResponse *response,
35120 void *context) {
35121 UA_AsyncManager *am = &server->asyncManager;
35122
35123 UA_AsyncOperation *ao = (UA_AsyncOperation*)context;
35124 if(!ao) {
35125 /* Something went wrong. Not a good AsyncOp. */
35126 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_SERVER,
35127 "UA_Server_SetAsyncMethodResult: Invalid context");
35128 return;
35129 }
35130
35131 UA_LOCK(&am->queueLock);
35132
35133 /* See if the operation is still in the dispatched queue. Otherwise it has
35134 * been removed due to a timeout.
35135 *
35136 * TODO: Add a tree-structure for the dispatch queue. The linear lookup does
35137 * not scale. */
35138 UA_Boolean found = false;
35139 UA_AsyncOperation *op = NULL;
35140 TAILQ_FOREACH(op, &am->dispatchedQueue, pointers) {
35141 if(op == ao) {
35142 found = true;
35143 break;
35144 }
35145 }
35146
35147 if(!found) {
35148 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_SERVER,
35149 "UA_Server_SetAsyncMethodResult: The operation has timed out");
35150 UA_UNLOCK(&am->queueLock);
35151 return;
35152 }
35153
35154 /* Copy the result into the internal AsyncOperation */
35155 UA_StatusCode result =
35156 UA_CallMethodResult_copy(&response->callMethodResult, &ao->response);
35157 if(result != UA_STATUSCODE_GOOD) {
35158 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_SERVER,
35159 "UA_Server_SetAsyncMethodResult: UA_CallMethodResult_copy failed.");
35160 ao->response.statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
35161 }
35162
35163 /* Move to the result queue */
35164 TAILQ_REMOVE(&am->dispatchedQueue, ao, pointers);
35165 TAILQ_INSERT_TAIL(&am->resultQueue, ao, pointers);
35166
35167 UA_UNLOCK(&am->queueLock);
35168
35169 UA_LOG_DEBUG(server->config.logging, UA_LOGCATEGORY_SERVER,
35170 "Set the result from the worker thread");
35171}
35172
35173/******************/
35174/* Server Methods */
35175/******************/
35176
35177static UA_StatusCode
35178setMethodNodeAsync(UA_Server *server, UA_Session *session,
35179 UA_Node *node, UA_Boolean *isAsync) {
35180 if(node->head.nodeClass != UA_NODECLASS_METHOD)
35181 return UA_STATUSCODE_BADNODECLASSINVALID;
35182 node->methodNode.async = *isAsync;
35183 return UA_STATUSCODE_GOOD;
35184}
35185
35186UA_StatusCode
35187UA_Server_setMethodNodeAsync(UA_Server *server, const UA_NodeId id,
35188 UA_Boolean isAsync) {
35189 lockServer(server);
35190 UA_StatusCode res =
35191 UA_Server_editNode(server, &server->adminSession, &id,
35192 (UA_EditNodeCallback)setMethodNodeAsync, &isAsync);
35193 unlockServer(server);
35194 return res;
35195}
35196
35197UA_StatusCode
35198UA_Server_processServiceOperationsAsync(UA_Server *server, UA_Session *session,
35199 UA_UInt32 requestId, UA_UInt32 requestHandle,
35200 UA_AsyncServiceOperation operationCallback,
35201 const size_t *requestOperations,
35202 const UA_DataType *requestOperationsType,
35203 size_t *responseOperations,
35204 const UA_DataType *responseOperationsType,
35205 UA_AsyncResponse **ar) {
35206 size_t ops = *requestOperations;
35207 if(ops == 0)
35208 return UA_STATUSCODE_BADNOTHINGTODO;
35209
35210 /* Allocate the response array. No padding after size_t */
35211 void **respPos = (void**)((uintptr_t)responseOperations + sizeof(size_t));
35212 *respPos = UA_Array_new(ops, responseOperationsType);
35213 if(!*respPos)
35214 return UA_STATUSCODE_BADOUTOFMEMORY;
35215 *responseOperations = ops;
35216
35217 /* Finish / dispatch the operations. This may allocate a new AsyncResponse internally */
35218 uintptr_t respOp = (uintptr_t)*respPos;
35219 uintptr_t reqOp = *(uintptr_t*)((uintptr_t)requestOperations + sizeof(size_t));
35220 for(size_t i = 0; i < ops; i++) {
35221 operationCallback(server, session, requestId, requestHandle,
35222 i, (void*)reqOp, (void*)respOp, ar);
35223 reqOp += requestOperationsType->memSize;
35224 respOp += responseOperationsType->memSize;
35225 }
35226
35227 return UA_STATUSCODE_GOOD;
35228}
35229
35230UA_UInt32
35231UA_AsyncManager_cancel(UA_Server *server, UA_Session *session, UA_UInt32 requestHandle) {
35232 UA_LOCK_ASSERT(&server->serviceMutex, 1);
35233 UA_AsyncManager *am = &server->asyncManager;
35234
35235 UA_LOCK(&am->queueLock);
35236
35237 /* Loop over the queue of dispatched ops */
35238 UA_AsyncOperation *op = NULL, *op_tmp = NULL;
35239 TAILQ_FOREACH_SAFE(op, &am->dispatchedQueue, pointers, op_tmp) {
35240 if(op->parent->requestHandle != requestHandle ||
35241 !UA_NodeId_equal(&session->sessionId, &op->parent->sessionId))
35242 continue;
35243
35244 /* Set status and put it into the result queue */
35245 op->response.statusCode = UA_STATUSCODE_BADREQUESTCANCELLEDBYCLIENT;
35246 TAILQ_REMOVE(&am->dispatchedQueue, op, pointers);
35247 TAILQ_INSERT_TAIL(&am->resultQueue, op, pointers);
35248
35249 /* Also set the status of the overall response */
35250 op->parent->response.callResponse.responseHeader.
35251 serviceResult = UA_STATUSCODE_BADREQUESTCANCELLEDBYCLIENT;
35252 }
35253
35254 /* Idem for waiting ops */
35255 TAILQ_FOREACH_SAFE(op, &am->newQueue, pointers, op_tmp) {
35256 if(op->parent->requestHandle != requestHandle ||
35257 !UA_NodeId_equal(&session->sessionId, &op->parent->sessionId))
35258 continue;
35259
35260 /* Mark as timed out and put it into the result queue */
35261 op->response.statusCode = UA_STATUSCODE_BADREQUESTCANCELLEDBYCLIENT;
35262 TAILQ_REMOVE(&am->newQueue, op, pointers);
35263 TAILQ_INSERT_TAIL(&am->resultQueue, op, pointers);
35264
35265 op->parent->response.callResponse.responseHeader.
35266 serviceResult = UA_STATUSCODE_BADREQUESTCANCELLEDBYCLIENT;
35267 }
35268
35269 UA_UNLOCK(&am->queueLock);
35270
35271 /* Process messages that have all ops completed */
35272 return processAsyncResults(server);
35273}
35274
35275#endif
35276
35277/**** amalgamated original file "/src/server/ua_services_view.c" ****/
35278
35279/* This Source Code Form is subject to the terms of the Mozilla Public
35280 * License, v. 2.0. If a copy of the MPL was not distributed with this
35281 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
35282 *
35283 * Copyright 2014-2019 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
35284 * Copyright 2014-2017 (c) Florian Palm
35285 * Copyright 2015-2016 (c) Sten Grüner
35286 * Copyright 2015 (c) LEvertz
35287 * Copyright 2015 (c) Chris Iatrou
35288 * Copyright 2015 (c) Ecosmos
35289 * Copyright 2015-2016 (c) Oleksiy Vasylyev
35290 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
35291 * Copyright 2016 (c) Lorenz Haas
35292 * Copyright 2017 (c) pschoppe
35293 * Copyright 2017 (c) Julian Grothoff
35294 * Copyright 2017 (c) Henrik Norrman
35295 */
35296
35297
35298#define UA_MAX_TREE_RECURSE 50 /* How deep up/down the tree do we recurse at most? */
35299
35300static UA_UInt32
35301resultMask2AttributesMask(UA_UInt32 resultMask) {
35302 UA_UInt32 result = 0;
35303 if(resultMask & UA_BROWSERESULTMASK_NODECLASS)
35304 result |= UA_NODEATTRIBUTESMASK_NODECLASS;
35305 if(resultMask & UA_BROWSERESULTMASK_BROWSENAME)
35306 result |= UA_NODEATTRIBUTESMASK_BROWSENAME;
35307 if(resultMask & UA_BROWSERESULTMASK_DISPLAYNAME)
35308 result |= UA_NODEATTRIBUTESMASK_DISPLAYNAME;
35309 return result;
35310}
35311
35312UA_StatusCode
35313referenceTypeIndices(UA_Server *server, const UA_NodeId *refType,
35314 UA_ReferenceTypeSet *indices, UA_Boolean includeSubtypes) {
35315 if(UA_NodeId_isNull(p: refType)) {
35316 *indices = UA_REFERENCETYPESET_ALL;
35317 return UA_STATUSCODE_GOOD;
35318 }
35319
35320 UA_ReferenceTypeSet_init(set: indices);
35321
35322 /* Get the node with only the NodeClass attribute. If it is a
35323 * ReferenceTypeNode, then the indices are always included, as this is an
35324 * open62541 specific field (not selectable via the attribute id). */
35325 const UA_Node *refNode =
35326 UA_NODESTORE_GET_SELECTIVE(server, refType,
35327 UA_NODEATTRIBUTESMASK_NODECLASS,
35328 UA_REFERENCETYPESET_NONE,
35329 UA_BROWSEDIRECTION_INVALID);
35330
35331 if(!refNode)
35332 return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
35333
35334 if(refNode->head.nodeClass != UA_NODECLASS_REFERENCETYPE) {
35335 UA_NODESTORE_RELEASE(server, refNode);
35336 return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
35337 }
35338
35339 if(!includeSubtypes)
35340 *indices = UA_REFTYPESET(index: refNode->referenceTypeNode.referenceTypeIndex);
35341 else
35342 *indices = refNode->referenceTypeNode.subTypes;
35343
35344 UA_NODESTORE_RELEASE(server, refNode);
35345 return UA_STATUSCODE_GOOD;
35346}
35347
35348static UA_Boolean
35349matchClassMask(const UA_Node *node, UA_UInt32 nodeClassMask) {
35350 if(nodeClassMask != UA_NODECLASS_UNSPECIFIED &&
35351 (node->head.nodeClass & nodeClassMask) == 0)
35352 return false;
35353 return true;
35354}
35355
35356/****************/
35357/* IsNodeInTree */
35358/****************/
35359
35360/* Internal method to check if a node is already upwards from a leaf node */
35361
35362static enum ZIP_CMP
35363cmpRefTarget(const void *a, const void *b) {
35364 const UA_ReferenceTarget *aa = (const UA_ReferenceTarget*)a;
35365 const UA_ReferenceTarget *bb = (const UA_ReferenceTarget*)b;
35366 return (enum ZIP_CMP)UA_NodePointer_order(p1: aa->targetId, p2: bb->targetId);
35367}
35368
35369typedef ZIP_HEAD(UA_ParentRefsTree, UA_ReferenceTargetTreeElem) UA_ParentRefsTree;
35370ZIP_FUNCTIONS(UA_ParentRefsTree, UA_ReferenceTargetTreeElem, idTreeEntry,
35371 UA_NodePointer, target, cmpRefTarget)
35372
35373struct IsNodeInTreeContext {
35374 UA_Server *server;
35375 UA_NodePointer nodeToFind;
35376 UA_ParentRefsTree parents;
35377 UA_ReferenceTypeSet relevantRefs;
35378 UA_UInt16 depth;
35379};
35380
35381static void *
35382isNodeInTreeIterateCallback(void *context, UA_ReferenceTarget *t) {
35383 struct IsNodeInTreeContext *tc =
35384 (struct IsNodeInTreeContext*)context;
35385
35386 /* Don't follow remote targets */
35387 if(!UA_NodePointer_isLocal(np: t->targetId))
35388 return NULL;
35389
35390 /* Found the node? -> return non-NULL */
35391 if(UA_NodePointer_equal(p1: tc->nodeToFind, p2: t->targetId))
35392 return (void*)0x01;
35393
35394 /* Prevent endless loop */
35395 if(ZIP_FIND(UA_ParentRefsTree, &tc->parents, &t->targetId))
35396 return NULL;
35397
35398 /* Prevent pathological recursion depth */
35399 if(tc->depth >= UA_MAX_TREE_RECURSE)
35400 return NULL;
35401
35402 /* Get the node without attributes (if the NodeStore supports it) and only
35403 * the relevant references in inverse direction */
35404 const UA_Node *node =
35405 UA_NODESTORE_GETFROMREF_SELECTIVE(tc->server, t->targetId,
35406 UA_NODEATTRIBUTESMASK_NONE,
35407 tc->relevantRefs,
35408 UA_BROWSEDIRECTION_INVERSE);
35409 if(!node)
35410 return NULL;
35411
35412 /* Add current NodeId to parents tree */
35413 UA_ReferenceTargetTreeElem stackElem;
35414 stackElem.target = *t;
35415 ZIP_INSERT(UA_ParentRefsTree, &tc->parents, &stackElem);
35416
35417 /* Recurse into appropriate references starting from this tree */
35418 tc->depth++;
35419 void *res = NULL;
35420 for(size_t i = 0; i < node->head.referencesSize && !res; i++) {
35421 UA_NodeReferenceKind *rk = &node->head.references[i];
35422 /* Search upwards in the tree */
35423 if(!rk->isInverse)
35424 continue;
35425
35426 /* Consider only the indicated reference types */
35427 if(!UA_ReferenceTypeSet_contains(set: &tc->relevantRefs, index: rk->referenceTypeIndex))
35428 continue;
35429
35430 res = UA_NodeReferenceKind_iterate(rk, callback: isNodeInTreeIterateCallback, context: tc);
35431 }
35432 tc->depth--;
35433
35434 /* Clean up */
35435 UA_NODESTORE_RELEASE(tc->server, node);
35436 ZIP_REMOVE(UA_ParentRefsTree, &tc->parents, &stackElem);
35437 return res;
35438}
35439
35440UA_Boolean
35441isNodeInTree(UA_Server *server, const UA_NodeId *leafNode,
35442 const UA_NodeId *nodeToFind,
35443 const UA_ReferenceTypeSet *relevantRefs) {
35444 struct IsNodeInTreeContext ctx;
35445 memset(s: &ctx, c: 0, n: sizeof(struct IsNodeInTreeContext));
35446 ctx.server = server;
35447 ctx.nodeToFind = UA_NodePointer_fromNodeId(id: nodeToFind);
35448 ctx.relevantRefs = *relevantRefs;
35449 UA_ReferenceTarget tmpTarget;
35450 memset(s: &tmpTarget, c: 0, n: sizeof(UA_ReferenceTarget));
35451 tmpTarget.targetId = UA_NodePointer_fromNodeId(id: leafNode);
35452 return (isNodeInTreeIterateCallback(context: &ctx, t: &tmpTarget) != NULL);
35453}
35454
35455UA_Boolean
35456isNodeInTree_singleRef(UA_Server *server, const UA_NodeId *leafNode,
35457 const UA_NodeId *nodeToFind, const UA_Byte relevantRefTypeIndex) {
35458 UA_ReferenceTypeSet reftypes = UA_REFTYPESET(index: relevantRefTypeIndex);
35459 return isNodeInTree(server, leafNode, nodeToFind, relevantRefs: &reftypes);
35460}
35461
35462static enum ZIP_CMP
35463cmpTarget(const void *a, const void *b) {
35464 const RefEntry *aa = (const RefEntry*)a;
35465 const RefEntry *bb = (const RefEntry*)b;
35466 if(aa->targetHash < bb->targetHash)
35467 return ZIP_CMP_LESS;
35468 if(aa->targetHash > bb->targetHash)
35469 return ZIP_CMP_MORE;
35470 return (enum ZIP_CMP)UA_ExpandedNodeId_order(n1: aa->target, n2: bb->target);
35471}
35472
35473ZIP_FUNCTIONS(RefHead, RefEntry, zipfields, RefEntry, zipfields, cmpTarget)
35474
35475UA_StatusCode
35476RefTree_init(RefTree *rt) {
35477 rt->size = 0;
35478 rt->capacity = 0;
35479 ZIP_INIT(&rt->head);
35480 size_t space = (sizeof(UA_ExpandedNodeId) + sizeof(RefEntry)) * UA_REFTREE_INITIAL_SIZE;
35481 rt->targets = (UA_ExpandedNodeId*)UA_malloc(size: space);
35482 if(!rt->targets)
35483 return UA_STATUSCODE_BADOUTOFMEMORY;
35484 rt->capacity = UA_REFTREE_INITIAL_SIZE;
35485 return UA_STATUSCODE_GOOD;
35486}
35487
35488void
35489RefTree_clear(RefTree *rt) {
35490 for(size_t i = 0; i < rt->size; i++)
35491 UA_ExpandedNodeId_clear(p: &rt->targets[i]);
35492 if(rt->targets)
35493 UA_free(ptr: rt->targets);
35494}
35495
35496/* Double the capacity of the reftree */
35497static UA_StatusCode UA_FUNC_ATTR_WARN_UNUSED_RESULT
35498RefTree_double(RefTree *rt) {
35499 size_t capacity = rt->capacity * 2;
35500 UA_assert(capacity > 0);
35501 size_t space = (sizeof(UA_ExpandedNodeId) + sizeof(RefEntry)) * capacity;
35502 UA_ExpandedNodeId *newTargets = (UA_ExpandedNodeId*)UA_realloc(ptr: rt->targets, size: space);
35503 if(!newTargets)
35504 return UA_STATUSCODE_BADOUTOFMEMORY;
35505
35506 /* Move the entries to the new location */
35507 RefEntry *reArray = (RefEntry*)
35508 ((uintptr_t)newTargets + (capacity * sizeof(UA_ExpandedNodeId)));
35509 RefEntry *oldReArray = (RefEntry*)
35510 ((uintptr_t)newTargets + (rt->capacity * sizeof(UA_ExpandedNodeId)));
35511 memmove(dest: reArray, src: oldReArray, n: rt->size * sizeof(RefEntry));
35512
35513 /* Reinsert all entries into the tree. The new pointer location has changed
35514 * their ziptree rank. */
35515 rt->head.root = NULL;
35516 for(size_t i = 0; i < rt->size; i++) {
35517 reArray[i].target = &newTargets[i];
35518 ZIP_INSERT(RefHead, &rt->head, &reArray[i]);
35519 }
35520
35521 rt->capacity = capacity;
35522 rt->targets = newTargets;
35523 return UA_STATUSCODE_GOOD;
35524}
35525
35526static UA_StatusCode
35527RefTree_add(RefTree *rt, UA_NodePointer target, UA_Boolean *duplicate) {
35528 UA_ExpandedNodeId en = UA_NodePointer_toExpandedNodeId(np: target);
35529
35530 /* Is the target already in the tree? */
35531 RefEntry dummy;
35532 memset(s: &dummy, c: 0, n: sizeof(RefEntry));
35533 dummy.target = &en;
35534 dummy.targetHash = UA_ExpandedNodeId_hash(n: &en);
35535 if(ZIP_FIND(RefHead, &rt->head, &dummy)) {
35536 if(duplicate)
35537 *duplicate = true;
35538 return UA_STATUSCODE_GOOD;
35539 }
35540
35541 UA_StatusCode s = UA_STATUSCODE_GOOD;
35542 if(rt->capacity <= rt->size) {
35543 s = RefTree_double(rt);
35544 if(s != UA_STATUSCODE_GOOD)
35545 return s;
35546 }
35547 s = UA_ExpandedNodeId_copy(src: &en, dst: &rt->targets[rt->size]);
35548 if(s != UA_STATUSCODE_GOOD)
35549 return s;
35550 RefEntry *re = (RefEntry*)((uintptr_t)rt->targets +
35551 (sizeof(UA_ExpandedNodeId) * rt->capacity) +
35552 (sizeof(RefEntry) * rt->size));
35553 re->target = &rt->targets[rt->size];
35554 re->targetHash = dummy.targetHash;
35555 ZIP_INSERT(RefHead, &rt->head, re);
35556 rt->size++;
35557 return UA_STATUSCODE_GOOD;
35558}
35559
35560UA_StatusCode
35561RefTree_addNodeId(RefTree *rt, const UA_NodeId *target,
35562 UA_Boolean *duplicate) {
35563 return RefTree_add(rt, target: UA_NodePointer_fromNodeId(id: target), duplicate);
35564}
35565
35566UA_Boolean
35567RefTree_contains(RefTree *rt, const UA_ExpandedNodeId *target) {
35568 RefEntry dummy;
35569 dummy.target = target;
35570 dummy.targetHash = UA_ExpandedNodeId_hash(n: target);
35571 return !!ZIP_FIND(RefHead, &rt->head, &dummy);
35572}
35573
35574UA_Boolean
35575RefTree_containsNodeId(RefTree *rt, const UA_NodeId *target) {
35576 UA_ExpandedNodeId en;
35577 en.nodeId = *target;
35578 en.namespaceUri = UA_STRING_NULL;
35579 en.serverIndex = 0;
35580 return RefTree_contains(rt, target: &en);
35581}
35582
35583/********************/
35584/* Browse Recursive */
35585/********************/
35586
35587struct BrowseRecursiveContext {
35588 UA_Server *server;
35589 RefTree *rt;
35590 UA_UInt16 depth;
35591 UA_BrowseDirection browseDirection;
35592 UA_ReferenceTypeSet refTypes;
35593 UA_UInt32 nodeClassMask;
35594 UA_StatusCode status;
35595 UA_Boolean includeStartNodes;
35596};
35597
35598static void *
35599browseRecursiveCallback(void *context, UA_ReferenceTarget *t) {
35600 struct BrowseRecursiveContext *brc =
35601 (struct BrowseRecursiveContext*)context;
35602
35603 /* Have we reached the max recursion depth? */
35604 if(brc->depth >= UA_MAX_TREE_RECURSE)
35605 return NULL;
35606
35607 /* Is this a non-local reference? If yes include it in the returned set. */
35608 if(!UA_NodePointer_isLocal(np: t->targetId)) {
35609 brc->status = RefTree_add(rt: brc->rt, target: t->targetId, NULL);
35610 return (brc->status == UA_STATUSCODE_GOOD) ? NULL : (void*)0x01;
35611 }
35612
35613 /* We only look at the NodeClass attribute and a subset of the references.
35614 * Get a node with only these elements if the NodeStore supports that. */
35615 const UA_Node *node =
35616 UA_NODESTORE_GETFROMREF_SELECTIVE(brc->server, t->targetId,
35617 UA_NODEATTRIBUTESMASK_NODECLASS,
35618 brc->refTypes, brc->browseDirection);
35619 if(!node)
35620 return NULL;
35621
35622 /* Add the current node if we don't want to skip it as a start node and it
35623 * matches the nodeClassMask filter Recurse into the children in any
35624 * case. */
35625 const UA_NodeHead *head = &node->head;
35626 if((brc->includeStartNodes || brc->depth > 0) &&
35627 matchClassMask(node, nodeClassMask: brc->nodeClassMask)) {
35628 UA_Boolean duplicate = false;
35629 brc->status = RefTree_addNodeId(rt: brc->rt, target: &head->nodeId, duplicate: &duplicate);
35630 if(duplicate || brc->status != UA_STATUSCODE_GOOD)
35631 goto cleanup;
35632 }
35633
35634 /* Recurse */
35635 brc->depth++;
35636 void *res = NULL;
35637 for(size_t i = 0; i < head->referencesSize && !res; i++) {
35638 UA_NodeReferenceKind *rk = &head->references[i];
35639
35640 /* Reference in the right direction? */
35641 if(rk->isInverse && brc->browseDirection == UA_BROWSEDIRECTION_FORWARD)
35642 continue;
35643 if(!rk->isInverse && brc->browseDirection == UA_BROWSEDIRECTION_INVERSE)
35644 continue;
35645
35646 /* Is the reference part of the hierarchy of references we look for? */
35647 if(!UA_ReferenceTypeSet_contains(set: &brc->refTypes, index: rk->referenceTypeIndex))
35648 continue;
35649
35650 res = UA_NodeReferenceKind_iterate(rk, callback: browseRecursiveCallback, context: brc);
35651 }
35652 brc->depth--;
35653
35654 cleanup:
35655 UA_NODESTORE_RELEASE(brc->server, node);
35656 return (brc->status == UA_STATUSCODE_GOOD) ? NULL : (void*)0x01;
35657}
35658
35659UA_StatusCode
35660browseRecursive(UA_Server *server, size_t startNodesSize, const UA_NodeId *startNodes,
35661 UA_BrowseDirection browseDirection, const UA_ReferenceTypeSet *refTypes,
35662 UA_UInt32 nodeClassMask, UA_Boolean includeStartNodes,
35663 size_t *resultsSize, UA_ExpandedNodeId **results) {
35664 RefTree rt;
35665 UA_StatusCode retval = RefTree_init(rt: &rt);
35666 if(retval != UA_STATUSCODE_GOOD)
35667 return retval;
35668
35669 struct BrowseRecursiveContext brc;
35670 brc.server = server;
35671 brc.rt = &rt;
35672 brc.depth = 0;
35673 brc.refTypes = *refTypes;
35674 brc.nodeClassMask = nodeClassMask;
35675 brc.status = UA_STATUSCODE_GOOD;
35676 brc.includeStartNodes = includeStartNodes;
35677
35678 for(size_t i = 0; i < startNodesSize && brc.status == UA_STATUSCODE_GOOD; i++) {
35679 UA_ReferenceTarget target;
35680 target.targetId = UA_NodePointer_fromNodeId(id: &startNodes[i]);
35681
35682 /* Call the inner recursive browse separately for the search direction.
35683 * Otherwise we might take one step up and another step down in the
35684 * search tree. */
35685 if(browseDirection == UA_BROWSEDIRECTION_FORWARD ||
35686 browseDirection == UA_BROWSEDIRECTION_BOTH) {
35687 brc.browseDirection = UA_BROWSEDIRECTION_FORWARD;
35688 browseRecursiveCallback(context: &brc, t: &target);
35689 }
35690
35691 if(browseDirection == UA_BROWSEDIRECTION_INVERSE ||
35692 browseDirection == UA_BROWSEDIRECTION_BOTH) {
35693 brc.browseDirection = UA_BROWSEDIRECTION_INVERSE;
35694 browseRecursiveCallback(context: &brc, t: &target);
35695 }
35696 }
35697
35698 if(rt.size > 0 && brc.status == UA_STATUSCODE_GOOD) {
35699 *results = rt.targets;
35700 *resultsSize = rt.size;
35701 } else {
35702 RefTree_clear(rt: &rt);
35703 }
35704 return brc.status;
35705}
35706
35707UA_StatusCode
35708UA_Server_browseRecursive(UA_Server *server, const UA_BrowseDescription *bd,
35709 size_t *resultsSize, UA_ExpandedNodeId **results) {
35710 lockServer(server);
35711
35712 /* Set the list of relevant reference types */
35713 UA_ReferenceTypeSet refTypes;
35714 UA_StatusCode retval = referenceTypeIndices(server, refType: &bd->referenceTypeId,
35715 indices: &refTypes, includeSubtypes: bd->includeSubtypes);
35716 if(retval != UA_STATUSCODE_GOOD) {
35717 unlockServer(server);
35718 return retval;
35719 }
35720
35721 /* Browse */
35722 retval = browseRecursive(server, startNodesSize: 1, startNodes: &bd->nodeId, browseDirection: bd->browseDirection,
35723 refTypes: &refTypes, nodeClassMask: bd->nodeClassMask, false, resultsSize, results);
35724
35725 unlockServer(server);
35726 return retval;
35727}
35728
35729/**********/
35730/* Browse */
35731/**********/
35732
35733typedef struct {
35734 size_t size;
35735 size_t capacity;
35736 UA_ReferenceDescription *descr;
35737} RefResult;
35738
35739static UA_StatusCode UA_FUNC_ATTR_WARN_UNUSED_RESULT
35740RefResult_init(RefResult *rr) {
35741 memset(s: rr, c: 0, n: sizeof(RefResult));
35742 rr->descr = (UA_ReferenceDescription*)
35743 UA_Array_new(UA_REFTREE_INITIAL_SIZE, type: &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION]);
35744 if(!rr->descr)
35745 return UA_STATUSCODE_BADOUTOFMEMORY;
35746 rr->capacity = UA_REFTREE_INITIAL_SIZE;
35747 rr->size = 0;
35748 return UA_STATUSCODE_GOOD;
35749}
35750
35751static UA_StatusCode UA_FUNC_ATTR_WARN_UNUSED_RESULT
35752RefResult_double(RefResult *rr) {
35753 size_t newSize = rr->capacity * 2;
35754 UA_ReferenceDescription *rd = (UA_ReferenceDescription*)
35755 UA_realloc(ptr: rr->descr, size: newSize * sizeof(UA_ReferenceDescription));
35756 if(!rd)
35757 return UA_STATUSCODE_BADOUTOFMEMORY;
35758 memset(s: &rd[rr->size], c: 0, n: sizeof(UA_ReferenceDescription) * (newSize - rr->size));
35759 rr->descr = rd;
35760 rr->capacity = newSize;
35761 return UA_STATUSCODE_GOOD;
35762}
35763
35764static void
35765RefResult_clear(RefResult *rr) {
35766 UA_assert(rr->descr != NULL);
35767 for(size_t i = 0; i < rr->size; i++)
35768 UA_ReferenceDescription_clear(p: &rr->descr[i]);
35769 UA_free(ptr: rr->descr);
35770}
35771
35772struct ContinuationPoint {
35773 ContinuationPoint *next;
35774 UA_ByteString identifier;
35775
35776 /* Parameters of the Browse Request */
35777 UA_BrowseDescription browseDescription;
35778 UA_UInt32 maxReferences;
35779 UA_ReferenceTypeSet relevantReferences;
35780
35781 /* The last reference target that was transmitted to the client. The results
35782 * list may be incomplete if the last target is removed or references added
35783 * between the calls to Browse/BrowseNext. */
35784 UA_NodePointer lastTarget;
35785 UA_Byte lastRefKindIndex;
35786 UA_Boolean lastRefInverse;
35787};
35788
35789ContinuationPoint *
35790ContinuationPoint_clear(ContinuationPoint *cp) {
35791 UA_ByteString_clear(p: &cp->identifier);
35792 UA_BrowseDescription_clear(p: &cp->browseDescription);
35793 UA_NodePointer_clear(np: &cp->lastTarget);
35794 return cp->next;
35795}
35796
35797struct BrowseContext {
35798 /* Context */
35799 ContinuationPoint *cp;
35800 UA_Server *server;
35801 UA_Session *session;
35802 UA_NodeReferenceKind *rk;
35803 UA_ReferenceTypeSet resultRefs; /* With additional references for type
35804 * lookups */
35805 UA_Boolean activeCP; /* true during "forwarding" to the position of the last
35806 * reference target */
35807
35808 /* Results */
35809 RefResult rr;
35810 UA_StatusCode status;
35811 UA_Boolean done;
35812};
35813
35814/* Target node on top of the stack */
35815static UA_StatusCode
35816addReferenceDescription(struct BrowseContext *bc, UA_NodePointer nodeP,
35817 const UA_Node *curr) {
35818 UA_assert(curr);
35819 UA_BrowseDescription *bd = &bc->cp->browseDescription;
35820
35821 /* Ensure capacity is left */
35822 UA_StatusCode res = UA_STATUSCODE_GOOD;
35823 if(bc->rr.size >= bc->rr.capacity) {
35824 res = RefResult_double(rr: &bc->rr);
35825 if(res != UA_STATUSCODE_GOOD)
35826 return res;
35827 }
35828
35829 UA_ReferenceDescription *descr = &bc->rr.descr[bc->rr.size];
35830
35831 /* Fields without access to the actual node */
35832 UA_ExpandedNodeId en = UA_NodePointer_toExpandedNodeId(np: nodeP);
35833 res = UA_ExpandedNodeId_copy(src: &en, dst: &descr->nodeId);
35834 if(bd->resultMask & UA_BROWSERESULTMASK_REFERENCETYPEID) {
35835 const UA_NodeId *refTypeId =
35836 UA_NODESTORE_GETREFERENCETYPEID(bc->server, bc->rk->referenceTypeIndex);
35837 res |= UA_NodeId_copy(src: refTypeId, dst: &descr->referenceTypeId);
35838 }
35839 if(bd->resultMask & UA_BROWSERESULTMASK_ISFORWARD)
35840 descr->isForward = !bc->rk->isInverse;
35841
35842 /* Create fields that require access to the actual node */
35843 if(bd->resultMask & UA_BROWSERESULTMASK_NODECLASS)
35844 descr->nodeClass = curr->head.nodeClass;
35845
35846 if(bd->resultMask & UA_BROWSERESULTMASK_BROWSENAME)
35847 res |= UA_QualifiedName_copy(src: &curr->head.browseName,
35848 dst: &descr->browseName);
35849
35850 if(bd->resultMask & UA_BROWSERESULTMASK_DISPLAYNAME) {
35851 UA_LocalizedText displayname =
35852 UA_Session_getNodeDisplayName(session: bc->session, head: &curr->head);
35853 res |= UA_LocalizedText_copy(src: &displayname, dst: &descr->displayName);
35854 }
35855
35856 if(bd->resultMask & UA_BROWSERESULTMASK_TYPEDEFINITION) {
35857 if(curr->head.nodeClass == UA_NODECLASS_OBJECT ||
35858 curr->head.nodeClass == UA_NODECLASS_VARIABLE) {
35859 const UA_Node *type = getNodeType(server: bc->server, head: &curr->head);
35860 if(type) {
35861 res |= UA_NodeId_copy(src: &type->head.nodeId,
35862 dst: &descr->typeDefinition.nodeId);
35863 UA_NODESTORE_RELEASE(bc->server, type);
35864 }
35865 }
35866 }
35867
35868 /* Clean up and return */
35869 if(res != UA_STATUSCODE_GOOD) {
35870 UA_ReferenceDescription_clear(p: descr);
35871 return res;
35872 }
35873 bc->rr.size++;
35874 return UA_STATUSCODE_GOOD;
35875}
35876
35877static void *
35878browseReferencTargetCallback(void *context, UA_ReferenceTarget *t) {
35879 struct BrowseContext *bc = (struct BrowseContext*)context;
35880 const UA_BrowseDescription *bd = &bc->cp->browseDescription;
35881 ContinuationPoint *cp = bc->cp;
35882
35883 /* Remote references are ignored */
35884 if(!UA_NodePointer_isLocal(np: t->targetId))
35885 return NULL;
35886
35887 /* Get the node. Include only the ReferenceTypes we are interested in,
35888 * including those for figuring out the TypeDefinition (if that was
35889 * requested). */
35890 const UA_Node *target =
35891 UA_NODESTORE_GETFROMREF_SELECTIVE(bc->server, t->targetId,
35892 resultMask2AttributesMask(bd->resultMask),
35893 bc->resultRefs, bd->browseDirection);
35894 if(!target)
35895 return NULL;
35896
35897 /* The node class has to match */
35898 if(!matchClassMask(node: target, nodeClassMask: bd->nodeClassMask)) {
35899 UA_NODESTORE_RELEASE(bc->server, target);
35900 return NULL;
35901 }
35902
35903 /* Reached maxrefs. Return the "abort" signal. */
35904 if(bc->rr.size >= cp->maxReferences) {
35905 UA_NODESTORE_RELEASE(bc->server, target);
35906 return (void*)0x01;
35907 }
35908
35909 /* Create the reference description */
35910 bc->status = addReferenceDescription(bc, nodeP: t->targetId, curr: target);
35911
35912 /* Release the node */
35913 UA_NODESTORE_RELEASE(bc->server, target);
35914
35915 /* Store as last target. The itarget-id is a shallow copy for now. */
35916 cp->lastTarget = t->targetId;
35917 cp->lastRefKindIndex = bc->rk->referenceTypeIndex;
35918 cp->lastRefInverse = bc->rk->isInverse;
35919
35920 /* Abort if the status is not good. Also doesn't make a deep-copy of
35921 * cp->lastTarget after returning from here. */
35922 if(bc->status != UA_STATUSCODE_GOOD) {
35923 UA_NodePointer_init(np: &cp->lastTarget);
35924 return (void*)0x01;
35925 }
35926 return NULL;
35927}
35928
35929/* Returns whether the node / continuationpoint is done */
35930static void
35931browseWithNode(struct BrowseContext *bc, const UA_NodeHead *head ) {
35932 ContinuationPoint *cp = bc->cp;
35933 const UA_BrowseDescription *bd = &cp->browseDescription;
35934
35935 /* Loop over the ReferenceKinds */
35936 for(size_t i = 0; i < head->referencesSize && bc->status == UA_STATUSCODE_GOOD; ++i) {
35937 UA_NodeReferenceKind *rk = &head->references[i];
35938
35939 /* If the continuation point was previously used, skip forward to the
35940 * last ReferenceType that was transmitted */
35941 if(bc->activeCP && rk->referenceTypeIndex != cp->lastRefKindIndex)
35942 continue;
35943 if(bc->activeCP && rk->isInverse != cp->lastRefInverse)
35944 continue;
35945
35946 /* Reference in the right direction? */
35947 if(rk->isInverse && bd->browseDirection == UA_BROWSEDIRECTION_FORWARD)
35948 continue;
35949 if(!rk->isInverse && bd->browseDirection == UA_BROWSEDIRECTION_INVERSE)
35950 continue;
35951
35952 /* Is the reference part of the hierarchy of references we look for? */
35953 if(!UA_ReferenceTypeSet_contains(set: &cp->relevantReferences, index: rk->referenceTypeIndex))
35954 continue;
35955
35956 /* We have a matching ReferenceKind */
35957
35958 /* Skip ahead to the target where the last continuation point stopped.
35959 * This temporarily modifies rk. */
35960 UA_ReferenceIdTree left = {NULL}, right = {NULL};
35961 size_t nextTargetIndex = 0;
35962 if(bc->activeCP) {
35963 if(rk->hasRefTree) {
35964 /* Unzip the tree until the continuation point. All NodeIds
35965 * larger than the last target are guaranteed to sit on the
35966 * right-hand side. */
35967 UA_ExpandedNodeId lastEn =
35968 UA_NodePointer_toExpandedNodeId(np: cp->lastTarget);
35969 UA_ReferenceTargetTreeElem key;
35970 key.target.targetId = cp->lastTarget;
35971 key.targetIdHash = UA_ExpandedNodeId_hash(n: &lastEn);
35972 ZIP_UNZIP(UA_ReferenceIdTree,
35973 (UA_ReferenceIdTree*)&rk->targets.tree.idRoot,
35974 &key, &left, &right);
35975 rk->targets.tree.idRoot = right.root;
35976 } else {
35977 /* Iterate over the array to find the match */
35978 for(; nextTargetIndex < rk->targetsSize; nextTargetIndex++) {
35979 UA_ReferenceTarget *t = &rk->targets.array[nextTargetIndex];
35980 if(UA_NodePointer_equal(p1: cp->lastTarget, p2: t->targetId))
35981 break;
35982 }
35983 if(nextTargetIndex == rk->targetsSize) {
35984 /* Not found - assume that this reference kind is done */
35985 bc->activeCP = false;
35986 continue;
35987 }
35988 nextTargetIndex++; /* From the last index to the next index */
35989 rk->targets.array = &rk->targets.array[nextTargetIndex];
35990 rk->targetsSize -= nextTargetIndex;
35991 }
35992
35993 /* Clear cp->lastTarget before it gets overwritten in the following
35994 * browse steps. */
35995 UA_NodePointer_clear(np: &cp->lastTarget);
35996 }
35997
35998 /* Iterate over all reference targets */
35999 bc->rk = rk;
36000 void *res = UA_NodeReferenceKind_iterate(rk, callback: browseReferencTargetCallback, context: bc);
36001
36002 /* Undo the "skipping ahead" for the continuation point */
36003 if(bc->activeCP) {
36004 if(rk->hasRefTree) {
36005 rk->targets.tree.idRoot =
36006 ZIP_ZIP(UA_ReferenceIdTree, left.root, right.root);
36007 } else {
36008 /* rk->targets.array = rk->targets.array[-nextTargetIndex]; */
36009 rk->targets.array = rk->targets.array - nextTargetIndex;
36010 rk->targetsSize += nextTargetIndex;
36011 UA_assert(rk->targetsSize > 0);
36012 }
36013 bc->activeCP = false;
36014 }
36015
36016 /* The iteration was aborted */
36017 if(res != NULL) {
36018 /* Aborted with status code good -> the maximum number of browse
36019 * results was reached. Make a deep copy of the last target for the
36020 * continuation point. */
36021 if(bc->status == UA_STATUSCODE_GOOD)
36022 bc->status = UA_NodePointer_copy(in: cp->lastTarget, out: &cp->lastTarget);
36023 return;
36024 }
36025 }
36026
36027 /* Reset last-target to prevent clearing it up */
36028 UA_NodePointer_init(np: &cp->lastTarget);
36029
36030 /* Browsing the node is done */
36031 bc->done = true;
36032}
36033
36034/* Results for a single browsedescription. This is the inner loop for both
36035 * Browse and BrowseNext. The ContinuationPoint contains all the data used.
36036 * Including the BrowseDescription. Returns whether there are remaining
36037 * references. */
36038static void
36039browse(struct BrowseContext *bc) {
36040 /* Is the browsedirection valid? */
36041 struct ContinuationPoint *cp = bc->cp;
36042 const UA_BrowseDescription *descr = &cp->browseDescription;
36043 if(descr->browseDirection != UA_BROWSEDIRECTION_BOTH &&
36044 descr->browseDirection != UA_BROWSEDIRECTION_FORWARD &&
36045 descr->browseDirection != UA_BROWSEDIRECTION_INVERSE) {
36046 bc->status = UA_STATUSCODE_BADBROWSEDIRECTIONINVALID;
36047 return;
36048 }
36049
36050 /* Get node with only the selected references and attributes */
36051 const UA_Node *node =
36052 UA_NODESTORE_GET_SELECTIVE(bc->server, &descr->nodeId,
36053 resultMask2AttributesMask(descr->resultMask),
36054 bc->resultRefs, descr->browseDirection);
36055 if(!node) {
36056 bc->status = UA_STATUSCODE_BADNODEIDUNKNOWN;
36057 return;
36058 }
36059
36060 /* Check AccessControl rights */
36061 if(bc->session != &bc->server->adminSession) {
36062 UA_LOCK_ASSERT(&bc->server->serviceMutex, 1);
36063 if(!bc->server->config.accessControl.
36064 allowBrowseNode(bc->server, &bc->server->config.accessControl,
36065 &bc->session->sessionId, bc->session->sessionHandle,
36066 &descr->nodeId, node->head.context)) {
36067 UA_NODESTORE_RELEASE(bc->server, node);
36068 bc->status = UA_STATUSCODE_BADUSERACCESSDENIED;
36069 return;
36070 }
36071 }
36072
36073 /* Browse the node */
36074 browseWithNode(bc, head: &node->head);
36075 UA_NODESTORE_RELEASE(bc->server, node);
36076
36077 /* Is the reference type valid? This is very infrequent. So we only test
36078 * this if browsing came up empty. If the node has references of that type,
36079 * we know the reftype to be good. */
36080 if(bc->rr.size == 0 && !UA_NodeId_isNull(p: &descr->referenceTypeId)) {
36081 const UA_Node *reftype =
36082 UA_NODESTORE_GET_SELECTIVE(bc->server, &descr->referenceTypeId,
36083 UA_NODEATTRIBUTESMASK_NODECLASS,
36084 UA_REFERENCETYPESET_NONE,
36085 UA_BROWSEDIRECTION_INVALID);
36086 if(!reftype) {
36087 bc->status = UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
36088 return;
36089 }
36090
36091 UA_Boolean isRef = (reftype->head.nodeClass == UA_NODECLASS_REFERENCETYPE);
36092 UA_NODESTORE_RELEASE(bc->server, reftype);
36093
36094 if(!isRef) {
36095 bc->status = UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
36096 return;
36097 }
36098 }
36099}
36100
36101/* Start to browse with no previous cp */
36102void
36103Operation_Browse(UA_Server *server, UA_Session *session, const UA_UInt32 *maxrefs,
36104 const UA_BrowseDescription *descr, UA_BrowseResult *result) {
36105 /* Stack-allocate a temporary cp */
36106 ContinuationPoint cp;
36107 memset(s: &cp, c: 0, n: sizeof(ContinuationPoint));
36108 cp.maxReferences = *maxrefs;
36109 cp.browseDescription = *descr; /* Shallow copy. Deep-copy later if we persist the cp. */
36110
36111 /* How many references can we return at most? */
36112 if(cp.maxReferences == 0) {
36113 if(server->config.maxReferencesPerNode != 0) {
36114 cp.maxReferences = server->config.maxReferencesPerNode;
36115 } else {
36116 cp.maxReferences = UA_INT32_MAX;
36117 }
36118 } else {
36119 if(server->config.maxReferencesPerNode != 0 &&
36120 cp.maxReferences > server->config.maxReferencesPerNode) {
36121 cp.maxReferences= server->config.maxReferencesPerNode;
36122 }
36123 }
36124
36125 /* Get the list of relevant reference types */
36126 result->statusCode =
36127 referenceTypeIndices(server, refType: &descr->referenceTypeId,
36128 indices: &cp.relevantReferences, includeSubtypes: descr->includeSubtypes);
36129 if(result->statusCode != UA_STATUSCODE_GOOD)
36130 return;
36131
36132 /* Prepare the context */
36133 struct BrowseContext bc;
36134 bc.cp = &cp;
36135 bc.server = server;
36136 bc.session = session;
36137 bc.status = UA_STATUSCODE_GOOD;
36138 bc.done = false;
36139 bc.activeCP = false;
36140 bc.resultRefs = cp.relevantReferences;
36141 if(cp.browseDescription.resultMask & UA_BROWSERESULTMASK_TYPEDEFINITION) {
36142 /* Get the node with additional reference types if we need to lookup the
36143 * TypeDefinition */
36144 bc.resultRefs = UA_ReferenceTypeSet_union(setA: bc.resultRefs,
36145 setB: UA_ReferenceTypeSet_union(setA: UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASTYPEDEFINITION),
36146 setB: UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASSUBTYPE)));
36147 }
36148 result->statusCode = RefResult_init(rr: &bc.rr);
36149 if(result->statusCode != UA_STATUSCODE_GOOD)
36150 return;
36151
36152 /* Perform the browse */
36153 browse(bc: &bc);
36154
36155 if(bc.status != UA_STATUSCODE_GOOD || bc.rr.size == 0) {
36156 /* No relevant references, return array of length zero */
36157 RefResult_clear(rr: &bc.rr);
36158 result->references = (UA_ReferenceDescription*)UA_EMPTY_ARRAY_SENTINEL;
36159 result->statusCode = bc.status;
36160 return;
36161 }
36162
36163 /* Move results */
36164 result->references = bc.rr.descr;
36165 result->referencesSize = bc.rr.size;
36166
36167 /* Exit early if done */
36168 if(bc.done)
36169 return;
36170
36171 /* Persist the continuation point */
36172
36173 ContinuationPoint *cp2 = NULL;
36174 UA_Guid *ident = NULL;
36175 UA_StatusCode retval = UA_STATUSCODE_GOOD;
36176
36177 /* Enough space for the continuation point? */
36178 if(session->availableContinuationPoints == 0) {
36179 retval = UA_STATUSCODE_BADNOCONTINUATIONPOINTS;
36180 goto cleanup;
36181 }
36182
36183 /* Allocate and fill the data structure */
36184 cp2 = (ContinuationPoint*)UA_calloc(nmemb: 1, size: sizeof(ContinuationPoint));
36185 if(!cp2) {
36186 retval = UA_STATUSCODE_BADOUTOFMEMORY;
36187 goto cleanup;
36188 }
36189
36190 /* The BrowseDescription is only a shallow copy so far */
36191 retval = UA_BrowseDescription_copy(src: descr, dst: &cp2->browseDescription);
36192 if(retval != UA_STATUSCODE_GOOD)
36193 goto cleanup;
36194 cp2->maxReferences = cp.maxReferences;
36195 cp2->relevantReferences = cp.relevantReferences;
36196 cp2->lastTarget = cp.lastTarget; /* Move the (deep) copy */
36197 UA_NodePointer_init(np: &cp.lastTarget); /* No longer clear below (cleanup) */
36198 cp2->lastRefKindIndex = cp.lastRefKindIndex;
36199 cp2->lastRefInverse = cp.lastRefInverse;
36200
36201 /* Create a random bytestring via a Guid */
36202 ident = UA_Guid_new();
36203 if(!ident) {
36204 retval = UA_STATUSCODE_BADOUTOFMEMORY;
36205 goto cleanup;
36206 }
36207 *ident = UA_Guid_random();
36208 cp2->identifier.data = (UA_Byte*)ident;
36209 cp2->identifier.length = sizeof(UA_Guid);
36210
36211 /* Return the cp identifier */
36212 retval = UA_ByteString_copy(src: &cp2->identifier, dst: &result->continuationPoint);
36213 if(retval != UA_STATUSCODE_GOOD)
36214 goto cleanup;
36215
36216 /* Attach the cp to the session */
36217 cp2->next = session->continuationPoints;
36218 session->continuationPoints = cp2;
36219 --session->availableContinuationPoints;
36220 return;
36221
36222 cleanup:
36223 if(cp2) {
36224 ContinuationPoint_clear(cp: cp2);
36225 UA_free(ptr: cp2);
36226 }
36227 UA_NodePointer_clear(np: &cp.lastTarget);
36228 UA_BrowseResult_clear(p: result);
36229 result->statusCode = retval;
36230}
36231
36232void Service_Browse(UA_Server *server, UA_Session *session,
36233 const UA_BrowseRequest *request, UA_BrowseResponse *response) {
36234 UA_LOG_DEBUG_SESSION(server->config.logging, session, "Processing BrowseRequest");
36235 UA_LOCK_ASSERT(&server->serviceMutex, 1);
36236
36237 /* Test the number of operations in the request */
36238 if(server->config.maxNodesPerBrowse != 0 &&
36239 request->nodesToBrowseSize > server->config.maxNodesPerBrowse) {
36240 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
36241 return;
36242 }
36243
36244 /* No views supported at the moment */
36245 if(!UA_NodeId_isNull(p: &request->view.viewId)) {
36246 response->responseHeader.serviceResult = UA_STATUSCODE_BADVIEWIDUNKNOWN;
36247 return;
36248 }
36249
36250 response->responseHeader.serviceResult =
36251 UA_Server_processServiceOperations(server, session,
36252 operationCallback: (UA_ServiceOperation)Operation_Browse,
36253 context: &request->requestedMaxReferencesPerNode,
36254 requestOperations: &request->nodesToBrowseSize,
36255 requestOperationsType: &UA_TYPES[UA_TYPES_BROWSEDESCRIPTION],
36256 responseOperations: &response->resultsSize,
36257 responseOperationsType: &UA_TYPES[UA_TYPES_BROWSERESULT]);
36258}
36259
36260UA_BrowseResult
36261UA_Server_browse(UA_Server *server, UA_UInt32 maxReferences,
36262 const UA_BrowseDescription *bd) {
36263 UA_BrowseResult result;
36264 UA_BrowseResult_init(p: &result);
36265 lockServer(server);
36266 Operation_Browse(server, session: &server->adminSession, maxrefs: &maxReferences, descr: bd, result: &result);
36267 unlockServer(server);
36268 return result;
36269}
36270
36271static void
36272Operation_BrowseNext(UA_Server *server, UA_Session *session,
36273 const UA_Boolean *releaseContinuationPoints,
36274 const UA_ByteString *continuationPoint, UA_BrowseResult *result) {
36275 /* Find the continuation point */
36276 ContinuationPoint **prev = &session->continuationPoints;
36277 ContinuationPoint *cp;
36278 while((cp = *prev)) {
36279 if(UA_ByteString_equal(p1: &cp->identifier, p2: continuationPoint))
36280 break;
36281 prev = &cp->next;
36282 }
36283 if(!cp) {
36284 result->statusCode = UA_STATUSCODE_BADCONTINUATIONPOINTINVALID;
36285 return;
36286 }
36287
36288 /* Remove the cp */
36289 if(*releaseContinuationPoints) {
36290 *prev = ContinuationPoint_clear(cp);
36291 UA_free(ptr: cp);
36292 ++session->availableContinuationPoints;
36293 return;
36294 }
36295
36296 /* Prepare the context */
36297 struct BrowseContext bc;
36298 bc.cp = cp;
36299 bc.server = server;
36300 bc.session = session;
36301 bc.status = UA_STATUSCODE_GOOD;
36302 bc.done = false;
36303 bc.activeCP = true;
36304 bc.resultRefs = cp->relevantReferences;
36305 if(cp->browseDescription.resultMask & UA_BROWSERESULTMASK_TYPEDEFINITION) {
36306 /* Get the node with additional reference types if we need to lookup the
36307 * TypeDefinition */
36308 bc.resultRefs = UA_ReferenceTypeSet_union(setA: bc.resultRefs,
36309 setB: UA_ReferenceTypeSet_union(setA: UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASTYPEDEFINITION),
36310 setB: UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASSUBTYPE)));
36311 }
36312 result->statusCode = RefResult_init(rr: &bc.rr);
36313 if(result->statusCode != UA_STATUSCODE_GOOD)
36314 return;
36315
36316 /* Continue browsing */
36317 browse(bc: &bc);
36318
36319 if(bc.status != UA_STATUSCODE_GOOD || bc.rr.size == 0) {
36320 /* No relevant references, return array of length zero */
36321 RefResult_clear(rr: &bc.rr);
36322 result->references = (UA_ReferenceDescription*)UA_EMPTY_ARRAY_SENTINEL;
36323 result->statusCode = bc.status;
36324 goto remove_cp;
36325 }
36326
36327 /* Move results */
36328 result->references = bc.rr.descr;
36329 result->referencesSize = bc.rr.size;
36330
36331 if(bc.done)
36332 goto remove_cp;
36333
36334 /* Return the cp identifier to signal that there are references left */
36335 bc.status = UA_ByteString_copy(src: &cp->identifier, dst: &result->continuationPoint);
36336 if(bc.status != UA_STATUSCODE_GOOD) {
36337 UA_BrowseResult_clear(p: result);
36338 result->statusCode = bc.status;
36339 }
36340 return;
36341
36342 remove_cp:
36343 /* Remove the cp */
36344 *prev = ContinuationPoint_clear(cp);
36345 UA_free(ptr: cp);
36346 ++session->availableContinuationPoints;
36347}
36348
36349void
36350Service_BrowseNext(UA_Server *server, UA_Session *session,
36351 const UA_BrowseNextRequest *request,
36352 UA_BrowseNextResponse *response) {
36353 UA_LOG_DEBUG_SESSION(server->config.logging, session,
36354 "Processing BrowseNextRequest");
36355 UA_LOCK_ASSERT(&server->serviceMutex, 1);
36356
36357 UA_Boolean releaseContinuationPoints =
36358 request->releaseContinuationPoints; /* request is const */
36359 response->responseHeader.serviceResult =
36360 UA_Server_processServiceOperations(server, session,
36361 operationCallback: (UA_ServiceOperation)Operation_BrowseNext,
36362 context: &releaseContinuationPoints,
36363 requestOperations: &request->continuationPointsSize,
36364 requestOperationsType: &UA_TYPES[UA_TYPES_BYTESTRING],
36365 responseOperations: &response->resultsSize,
36366 responseOperationsType: &UA_TYPES[UA_TYPES_BROWSERESULT]);
36367}
36368
36369UA_BrowseResult
36370UA_Server_browseNext(UA_Server *server, UA_Boolean releaseContinuationPoint,
36371 const UA_ByteString *continuationPoint) {
36372 UA_BrowseResult result;
36373 UA_BrowseResult_init(p: &result);
36374 lockServer(server);
36375 Operation_BrowseNext(server, session: &server->adminSession, releaseContinuationPoints: &releaseContinuationPoint,
36376 continuationPoint, result: &result);
36377 unlockServer(server);
36378 return result;
36379}
36380
36381/***********************/
36382/* TranslateBrowsePath */
36383/***********************/
36384
36385/* Add all entries for the hash. There are possible duplicates due to hash
36386 * collisions. The full browsename is checked afterwards. */
36387static void *
36388addBrowseHashTarget(void *context, UA_ReferenceTargetTreeElem *elem) {
36389 RefTree *next = (RefTree*)context;
36390 return (void*)(uintptr_t)RefTree_add(rt: next, target: elem->target.targetId, NULL);
36391}
36392
36393static UA_StatusCode
36394walkBrowsePathElement(UA_Server *server, UA_Session *session,
36395 const UA_RelativePath *path, const size_t pathIndex,
36396 UA_UInt32 nodeClassMask, const UA_QualifiedName *lastBrowseName,
36397 UA_BrowsePathResult *result, RefTree *current, RefTree *next) {
36398 /* For the next level. Note the difference from lastBrowseName */
36399 const UA_RelativePathElement *elem = &path->elements[pathIndex];
36400 UA_UInt32 browseNameHash = UA_QualifiedName_hash(q: &elem->targetName);
36401
36402 /* Get the relevant ReferenceTypes */
36403 UA_ReferenceTypeSet refTypes;
36404 UA_StatusCode res =
36405 referenceTypeIndices(server, refType: &elem->referenceTypeId,
36406 indices: &refTypes, includeSubtypes: elem->includeSubtypes);
36407 if(res != UA_STATUSCODE_GOOD)
36408 return UA_STATUSCODE_BADNOMATCH;
36409
36410 /* Loop over all Nodes in the current depth level */
36411 for(size_t i = 0; i < current->size; i++) {
36412 /* Remote Node. Immediately add to the results with the
36413 * RemainingPathIndex set. */
36414 if(!UA_ExpandedNodeId_isLocal(n: &current->targets[i])) {
36415 /* Increase the size of the results array */
36416 UA_BrowsePathTarget *tmpResults = (UA_BrowsePathTarget*)
36417 UA_realloc(ptr: result->targets, size: sizeof(UA_BrowsePathTarget) *
36418 (result->targetsSize + 1));
36419 if(!tmpResults)
36420 return UA_STATUSCODE_BADOUTOFMEMORY;
36421 result->targets = tmpResults;
36422
36423 /* Copy over the result */
36424 res = UA_ExpandedNodeId_copy(src: &current->targets[i],
36425 dst: &result->targets[result->targetsSize].targetId);
36426 result->targets[result->targetsSize].remainingPathIndex = (UA_UInt32)pathIndex;
36427 result->targetsSize++;
36428 if(res != UA_STATUSCODE_GOOD)
36429 break;
36430 continue;
36431 }
36432
36433 /* Local Node. Add to the tree of results at the next depth. Get only
36434 * the NodeClass + BrowseName attribute and the selected ReferenceTypes
36435 * if the nodestore supports that. */
36436 const UA_Node *node =
36437 UA_NODESTORE_GET_SELECTIVE(server, &current->targets[i].nodeId,
36438 UA_NODEATTRIBUTESMASK_NODECLASS |
36439 UA_NODEATTRIBUTESMASK_BROWSENAME,
36440 refTypes,
36441 elem->isInverse ? UA_BROWSEDIRECTION_INVERSE :
36442 UA_BROWSEDIRECTION_FORWARD);
36443 if(!node)
36444 continue;
36445
36446 /* Test whether the node fits the class mask */
36447 UA_Boolean skip = !matchClassMask(node, nodeClassMask);
36448
36449 /* Does the BrowseName match for the current node (not the references
36450 * going out here) */
36451 skip |= (lastBrowseName &&
36452 !UA_QualifiedName_equal(p1: lastBrowseName, p2: &node->head.browseName));
36453
36454 if(skip) {
36455 UA_NODESTORE_RELEASE(server, node);
36456 continue;
36457 }
36458
36459 /* Loop over the ReferenceKinds */
36460 UA_ReferenceTarget targetHashKey;
36461 targetHashKey.targetNameHash = browseNameHash;
36462 for(size_t j = 0; j < node->head.referencesSize; j++) {
36463 UA_NodeReferenceKind *rk = &node->head.references[j];
36464
36465 /* Does the direction of the reference match? */
36466 if(rk->isInverse != elem->isInverse)
36467 continue;
36468
36469 /* Does the reference type match? */
36470 if(!UA_ReferenceTypeSet_contains(set: &refTypes, index: rk->referenceTypeIndex))
36471 continue;
36472
36473 /* Retrieve by BrowseName hash. We might have several nodes where
36474 * the hash matches. The exact BrowseName will be verified in the
36475 * next iteration of the outer loop. So we only have to retrieve
36476 * every node just once. */
36477
36478 if(rk->hasRefTree) {
36479 res = (UA_StatusCode)(uintptr_t)
36480 ZIP_ITER_KEY(UA_ReferenceNameTree,
36481 (UA_ReferenceNameTree*)&rk->targets.tree.nameRoot,
36482 &targetHashKey, addBrowseHashTarget, next);
36483 if(res != UA_STATUSCODE_GOOD)
36484 break;
36485 } else {
36486 /* The array entries don't have a BrowseName hash. Add all of
36487 * them at this level to be checked with a full string
36488 * comparison. */
36489 for(size_t k = 0; k < rk->targetsSize; k++) {
36490 if(rk->targets.array[k].targetNameHash != browseNameHash)
36491 continue;
36492 res = RefTree_add(rt: next, target: rk->targets.array[k].targetId, NULL);
36493 if(res != UA_STATUSCODE_GOOD)
36494 break;
36495 }
36496 if(res != UA_STATUSCODE_GOOD)
36497 break;
36498 }
36499 }
36500
36501 UA_NODESTORE_RELEASE(server, node);
36502 }
36503 return res;
36504}
36505
36506static void
36507Operation_TranslateBrowsePathToNodeIds(UA_Server *server, UA_Session *session,
36508 const UA_UInt32 *nodeClassMask,
36509 const UA_BrowsePath *path,
36510 UA_BrowsePathResult *result) {
36511 UA_LOCK_ASSERT(&server->serviceMutex, 1);
36512
36513 if(path->relativePath.elementsSize == 0) {
36514 result->statusCode = UA_STATUSCODE_BADNOTHINGTODO;
36515 return;
36516 }
36517
36518 /* RelativePath elements must not have an empty targetName */
36519 for(size_t i = 0; i < path->relativePath.elementsSize; ++i) {
36520 if(UA_QualifiedName_isNull(q: &path->relativePath.elements[i].targetName)) {
36521 result->statusCode = UA_STATUSCODE_BADBROWSENAMEINVALID;
36522 return;
36523 }
36524 }
36525
36526 /* Check if the starting node exists */
36527 const UA_Node *startingNode =
36528 UA_NODESTORE_GET_SELECTIVE(server, &path->startingNode,
36529 UA_NODEATTRIBUTESMASK_NONE,
36530 UA_REFERENCETYPESET_NONE,
36531 UA_BROWSEDIRECTION_INVALID);
36532 if(!startingNode) {
36533 result->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN;
36534 return;
36535 }
36536 UA_NODESTORE_RELEASE(server, startingNode);
36537
36538 /* Create two RefTrees that are alternated between path elements */
36539 RefTree rt1;
36540 RefTree rt2;
36541 RefTree *current = &rt1;
36542 RefTree *next = &rt2;
36543 RefTree *tmp;
36544 result->statusCode |= RefTree_init(rt: &rt1);
36545 result->statusCode |= RefTree_init(rt: &rt2);
36546 UA_BrowsePathTarget *tmpResults = NULL;
36547 UA_QualifiedName *browseNameFilter = NULL;
36548 if(result->statusCode != UA_STATUSCODE_GOOD)
36549 goto cleanup;
36550
36551 /* Copy the starting node into next */
36552 result->statusCode = RefTree_addNodeId(rt: next, target: &path->startingNode, NULL);
36553 if(result->statusCode != UA_STATUSCODE_GOOD)
36554 goto cleanup;
36555
36556 /* Walk the path elements. Retrieve the nodes only once from the NodeStore.
36557 * Hence the BrowseName is checked with one element "delay". */
36558 for(size_t i = 0; i < path->relativePath.elementsSize; i++) {
36559 /* Switch the trees */
36560 tmp = current;
36561 current = next;
36562 next = tmp;
36563
36564 /* Clear up current, keep the capacity */
36565 for(size_t j = 0; j < next->size; j++)
36566 UA_ExpandedNodeId_clear(p: &next->targets[j]);
36567 next->size = 0;
36568 ZIP_INIT(&next->head);
36569
36570 /* Do this check after next->size has been set to zero */
36571 if(current->size == 0)
36572 break;
36573
36574 /* Walk element for all NodeIds in the "current" tree.
36575 * Puts new results in the "next" tree. */
36576 result->statusCode =
36577 walkBrowsePathElement(server, session, path: &path->relativePath, pathIndex: i,
36578 nodeClassMask: *nodeClassMask, lastBrowseName: browseNameFilter, result, current, next);
36579 if(result->statusCode != UA_STATUSCODE_GOOD)
36580 goto cleanup;
36581
36582 browseNameFilter = &path->relativePath.elements[i].targetName;
36583 }
36584
36585 /* Allocate space for the results array */
36586 tmpResults = (UA_BrowsePathTarget*)
36587 UA_realloc(ptr: result->targets, size: sizeof(UA_BrowsePathTarget) *
36588 (result->targetsSize + next->size));
36589 if(!tmpResults && next->size > 0) {
36590 result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
36591 goto cleanup;
36592 }
36593 result->targets = tmpResults;
36594
36595 for(size_t k = 0; k < next->size; k++) {
36596 /* Check the BrowseName. It has been filtered only via its hash so far.
36597 * Get only the BrowseName attribute if the nodestore supports that. */
36598 const UA_Node *node =
36599 UA_NODESTORE_GET_SELECTIVE(server, &next->targets[k].nodeId,
36600 UA_NODEATTRIBUTESMASK_BROWSENAME,
36601 UA_REFERENCETYPESET_NONE,
36602 UA_BROWSEDIRECTION_INVALID);
36603 if(!node)
36604 continue;
36605 UA_Boolean match = UA_QualifiedName_equal(p1: browseNameFilter, p2: &node->head.browseName);
36606 UA_NODESTORE_RELEASE(server, node);
36607 if(!match)
36608 continue;
36609
36610 /* Move to the target to the results array */
36611 result->targets[result->targetsSize].targetId = next->targets[k];
36612 result->targets[result->targetsSize].remainingPathIndex = UA_UINT32_MAX;
36613 UA_ExpandedNodeId_init(p: &next->targets[k]);
36614 result->targetsSize++;
36615 }
36616
36617 /* No results => BadNoMatch status code */
36618 if(result->targetsSize == 0 && result->statusCode == UA_STATUSCODE_GOOD)
36619 result->statusCode = UA_STATUSCODE_BADNOMATCH;
36620
36621 /* Clean up the temporary arrays and the targets */
36622 cleanup:
36623 RefTree_clear(rt: &rt1);
36624 RefTree_clear(rt: &rt2);
36625 if(result->statusCode != UA_STATUSCODE_GOOD) {
36626 for(size_t i = 0; i < result->targetsSize; ++i)
36627 UA_BrowsePathTarget_clear(p: &result->targets[i]);
36628 if(result->targets)
36629 UA_free(ptr: result->targets);
36630 result->targets = NULL;
36631 result->targetsSize = 0;
36632 }
36633}
36634
36635UA_BrowsePathResult
36636translateBrowsePathToNodeIds(UA_Server *server,
36637 const UA_BrowsePath *browsePath) {
36638 UA_LOCK_ASSERT(&server->serviceMutex, 1);
36639 UA_BrowsePathResult result;
36640 UA_BrowsePathResult_init(p: &result);
36641 UA_UInt32 nodeClassMask = 0; /* All node classes */
36642 Operation_TranslateBrowsePathToNodeIds(server, session: &server->adminSession, nodeClassMask: &nodeClassMask,
36643 path: browsePath, result: &result);
36644 return result;
36645}
36646
36647UA_BrowsePathResult
36648UA_Server_translateBrowsePathToNodeIds(UA_Server *server,
36649 const UA_BrowsePath *browsePath) {
36650 lockServer(server);
36651 UA_BrowsePathResult result = translateBrowsePathToNodeIds(server, browsePath);
36652 unlockServer(server);
36653 return result;
36654}
36655
36656void
36657Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *session,
36658 const UA_TranslateBrowsePathsToNodeIdsRequest *request,
36659 UA_TranslateBrowsePathsToNodeIdsResponse *response) {
36660 UA_LOG_DEBUG_SESSION(server->config.logging, session,
36661 "Processing TranslateBrowsePathsToNodeIdsRequest");
36662 UA_LOCK_ASSERT(&server->serviceMutex, 1);
36663
36664 /* Test the number of operations in the request */
36665 if(server->config.maxNodesPerTranslateBrowsePathsToNodeIds != 0 &&
36666 request->browsePathsSize > server->config.maxNodesPerTranslateBrowsePathsToNodeIds) {
36667 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
36668 return;
36669 }
36670
36671 UA_UInt32 nodeClassMask = 0; /* All node classes */
36672 response->responseHeader.serviceResult =
36673 UA_Server_processServiceOperations(server, session,
36674 operationCallback: (UA_ServiceOperation)Operation_TranslateBrowsePathToNodeIds,
36675 context: &nodeClassMask,
36676 requestOperations: &request->browsePathsSize, requestOperationsType: &UA_TYPES[UA_TYPES_BROWSEPATH],
36677 responseOperations: &response->resultsSize, responseOperationsType: &UA_TYPES[UA_TYPES_BROWSEPATHRESULT]);
36678}
36679
36680UA_BrowsePathResult
36681browseSimplifiedBrowsePath(UA_Server *server, const UA_NodeId origin,
36682 size_t browsePathSize, const UA_QualifiedName *browsePath) {
36683 UA_LOCK_ASSERT(&server->serviceMutex, 1);
36684
36685 UA_BrowsePathResult bpr;
36686 UA_BrowsePathResult_init(p: &bpr);
36687 if(browsePathSize > UA_MAX_TREE_RECURSE) {
36688 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
36689 msg: "Simplified Browse Path too long");
36690 bpr.statusCode = UA_STATUSCODE_BADINTERNALERROR;
36691 return bpr;
36692 }
36693
36694 /* Construct the BrowsePath */
36695 UA_BrowsePath bp;
36696 UA_BrowsePath_init(p: &bp);
36697 bp.startingNode = origin;
36698
36699 UA_RelativePathElement rpe[UA_MAX_TREE_RECURSE];
36700 memset(s: rpe, c: 0, n: sizeof(UA_RelativePathElement) * browsePathSize);
36701 for(size_t j = 0; j < browsePathSize; j++) {
36702 rpe[j].referenceTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HIERARCHICALREFERENCES);
36703 rpe[j].includeSubtypes = true;
36704 rpe[j].targetName = browsePath[j];
36705 }
36706 bp.relativePath.elements = rpe;
36707 bp.relativePath.elementsSize = browsePathSize;
36708
36709 /* Browse */
36710 UA_UInt32 nodeClassMask = UA_NODECLASS_OBJECT | UA_NODECLASS_VARIABLE | UA_NODECLASS_OBJECTTYPE;
36711
36712 Operation_TranslateBrowsePathToNodeIds(server, session: &server->adminSession, nodeClassMask: &nodeClassMask, path: &bp, result: &bpr);
36713 return bpr;
36714}
36715
36716UA_BrowsePathResult
36717UA_Server_browseSimplifiedBrowsePath(UA_Server *server, const UA_NodeId origin,
36718 size_t browsePathSize, const UA_QualifiedName *browsePath) {
36719 lockServer(server);
36720 UA_BrowsePathResult bpr = browseSimplifiedBrowsePath(server, origin, browsePathSize, browsePath);
36721 unlockServer(server);
36722 return bpr;
36723}
36724
36725/************/
36726/* Register */
36727/************/
36728
36729void Service_RegisterNodes(UA_Server *server, UA_Session *session,
36730 const UA_RegisterNodesRequest *request,
36731 UA_RegisterNodesResponse *response) {
36732 UA_LOG_DEBUG_SESSION(server->config.logging, session,
36733 "Processing RegisterNodesRequest");
36734 UA_LOCK_ASSERT(&server->serviceMutex, 1);
36735
36736 //TODO: hang the nodeids to the session if really needed
36737 if(request->nodesToRegisterSize == 0) {
36738 response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
36739 return;
36740 }
36741
36742 /* Test the number of operations in the request */
36743 if(server->config.maxNodesPerRegisterNodes != 0 &&
36744 request->nodesToRegisterSize > server->config.maxNodesPerRegisterNodes) {
36745 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
36746 return;
36747 }
36748
36749 response->responseHeader.serviceResult =
36750 UA_Array_copy(src: request->nodesToRegister, size: request->nodesToRegisterSize,
36751 dst: (void**)&response->registeredNodeIds, type: &UA_TYPES[UA_TYPES_NODEID]);
36752 if(response->responseHeader.serviceResult == UA_STATUSCODE_GOOD)
36753 response->registeredNodeIdsSize = request->nodesToRegisterSize;
36754}
36755
36756void Service_UnregisterNodes(UA_Server *server, UA_Session *session,
36757 const UA_UnregisterNodesRequest *request,
36758 UA_UnregisterNodesResponse *response) {
36759 UA_LOG_DEBUG_SESSION(server->config.logging, session,
36760 "Processing UnRegisterNodesRequest");
36761 UA_LOCK_ASSERT(&server->serviceMutex, 1);
36762
36763 //TODO: remove the nodeids from the session if really needed
36764 if(request->nodesToUnregisterSize == 0)
36765 response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
36766
36767 /* Test the number of operations in the request */
36768 if(server->config.maxNodesPerRegisterNodes != 0 &&
36769 request->nodesToUnregisterSize > server->config.maxNodesPerRegisterNodes) {
36770 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
36771 return;
36772 }
36773}
36774
36775/**** amalgamated original file "/src/server/ua_services_method.c" ****/
36776
36777/* This Source Code Form is subject to the terms of the Mozilla Public
36778 * License, v. 2.0. If a copy of the MPL was not distributed with this
36779 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
36780 *
36781 * Copyright 2015 (c) Chris Iatrou
36782 * Copyright 2015-2017 (c) Florian Palm
36783 * Copyright 2015-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
36784 * Copyright 2015-2016 (c) Sten Grüner
36785 * Copyright 2015 (c) Oleksiy Vasylyev
36786 * Copyright 2016 (c) LEvertz
36787 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
36788 * Copyright 2017 (c) Julian Grothoff
36789 * Copyright 2020 (c) Hilscher Gesellschaft für Systemautomation mbH (Author: Martin Lang)
36790 */
36791
36792
36793#ifdef UA_ENABLE_METHODCALLS /* conditional compilation */
36794
36795#define UA_MAX_METHOD_ARGUMENTS 64
36796
36797struct GetArgumentsNodeContext {
36798 UA_Server *server;
36799 UA_String withBrowseName;
36800};
36801
36802static void *
36803getArgumentsNodeCallback(void *context, UA_ReferenceTarget *t) {
36804 struct GetArgumentsNodeContext *ctx = (struct GetArgumentsNodeContext*)context;
36805 const UA_Node *refTarget =
36806 UA_NODESTORE_GETFROMREF_SELECTIVE(ctx->server, t->targetId,
36807 UA_NODEATTRIBUTESMASK_NODECLASS |
36808 UA_NODEATTRIBUTESMASK_VALUE,
36809 UA_REFERENCETYPESET_NONE,
36810 UA_BROWSEDIRECTION_INVALID);
36811 if(!refTarget)
36812 return NULL;
36813 if(refTarget->head.nodeClass == UA_NODECLASS_VARIABLE &&
36814 refTarget->head.browseName.namespaceIndex == 0 &&
36815 UA_String_equal(p1: &ctx->withBrowseName, p2: &refTarget->head.browseName.name)) {
36816 return (void*)(uintptr_t)&refTarget->variableNode;
36817 }
36818 UA_NODESTORE_RELEASE(ctx->server, refTarget);
36819 return NULL;
36820}
36821
36822static const UA_VariableNode *
36823getArgumentsVariableNode(UA_Server *server, const UA_NodeHead *head,
36824 UA_String withBrowseName) {
36825 for(size_t i = 0; i < head->referencesSize; ++i) {
36826 UA_NodeReferenceKind *rk = &head->references[i];
36827 if(rk->isInverse)
36828 continue;
36829 if(rk->referenceTypeIndex != UA_REFERENCETYPEINDEX_HASPROPERTY)
36830 continue;
36831 struct GetArgumentsNodeContext ctx;
36832 ctx.server = server;
36833 ctx.withBrowseName = withBrowseName;
36834 return (const UA_VariableNode*)
36835 UA_NodeReferenceKind_iterate(rk, callback: getArgumentsNodeCallback, context: &ctx);
36836 }
36837 return NULL;
36838}
36839
36840/* inputArgumentResults has the length request->inputArgumentsSize */
36841static UA_StatusCode
36842checkAdjustArguments(UA_Server *server, UA_Session *session,
36843 const UA_VariableNode *argRequirements, size_t argsSize,
36844 UA_Variant *args, UA_StatusCode *inputArgumentResults) {
36845 /* Verify that we have a Variant containing UA_Argument (scalar or array) in
36846 * the "InputArguments" node */
36847 if(argRequirements->valueSource != UA_VALUESOURCE_DATA)
36848 return UA_STATUSCODE_BADINTERNALERROR;
36849 if(!argRequirements->value.data.value.hasValue)
36850 return UA_STATUSCODE_BADINTERNALERROR;
36851 if(argRequirements->value.data.value.value.type != &UA_TYPES[UA_TYPES_ARGUMENT])
36852 return UA_STATUSCODE_BADINTERNALERROR;
36853
36854 /* Verify the number of arguments. A scalar argument value is interpreted as
36855 * an array of length 1. */
36856 size_t argReqsSize = argRequirements->value.data.value.value.arrayLength;
36857 if(UA_Variant_isScalar(v: &argRequirements->value.data.value.value))
36858 argReqsSize = 1;
36859 if(argReqsSize > argsSize)
36860 return UA_STATUSCODE_BADARGUMENTSMISSING;
36861 if(argReqsSize < argsSize)
36862 return UA_STATUSCODE_BADTOOMANYARGUMENTS;
36863
36864 /* Type-check every argument against the definition */
36865 UA_StatusCode retval = UA_STATUSCODE_GOOD;
36866 UA_Argument *argReqs = (UA_Argument*)argRequirements->value.data.value.value.data;
36867 const char *reason;
36868 for(size_t i = 0; i < argReqsSize; ++i) {
36869 /* Incompatible value. Try to correct the type if possible. */
36870 adjustValueType(server, value: &args[i], targetDataTypeId: &argReqs[i].dataType);
36871
36872 /* Check */
36873 if(!compatibleValue(server, session, targetDataTypeId: &argReqs[i].dataType, targetValueRank: argReqs[i].valueRank,
36874 targetArrayDimensionsSize: argReqs[i].arrayDimensionsSize, targetArrayDimensions: argReqs[i].arrayDimensions,
36875 value: &args[i], NULL, reason: &reason)) {
36876 inputArgumentResults[i] = UA_STATUSCODE_BADTYPEMISMATCH;
36877 retval = UA_STATUSCODE_BADINVALIDARGUMENT;
36878 }
36879 }
36880 return retval;
36881}
36882
36883static const UA_NodeId hasComponentNodeId = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASCOMPONENT}};
36884static const UA_NodeId organizedByNodeId = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_ORGANIZES}};
36885static const UA_String namespaceDiModel = UA_STRING_STATIC("http://opcfoundation.org/UA/DI/");
36886static const UA_NodeId hasTypeDefinitionNodeId = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASTYPEDEFINITION}};
36887// ns=0 will be replace dynamically. DI-Spec. 1.01: <UAObjectType NodeId="ns=1;i=1005" BrowseName="1:FunctionalGroupType">
36888static UA_NodeId functionGroupNodeId = {0, UA_NODEIDTYPE_NUMERIC, {1005}};
36889
36890static UA_Boolean
36891checkMethodReference(const UA_NodeHead *h, UA_ReferenceTypeSet refs,
36892 const UA_ExpandedNodeId *methodId) {
36893 for(size_t i = 0; i < h->referencesSize; i++) {
36894 const UA_NodeReferenceKind *rk = &h->references[i];
36895 if(rk->isInverse)
36896 continue;
36897 if(!UA_ReferenceTypeSet_contains(set: &refs, index: rk->referenceTypeIndex))
36898 continue;
36899 if(UA_NodeReferenceKind_findTarget(rk, targetId: methodId))
36900 return true;
36901 }
36902 return false;
36903}
36904
36905static void *
36906iterateFunctionGroupSearch(void *context, UA_ReferenceTarget *t) {
36907 UA_Server *server = (UA_Server*)context;
36908 if(!UA_NodePointer_isLocal(np: t->targetId))
36909 return NULL;
36910
36911 UA_NodeId tmpId = UA_NodePointer_toNodeId(np: t->targetId);
36912 if(isNodeInTree_singleRef(server, leafNode: &tmpId, nodeToFind: &functionGroupNodeId,
36913 UA_REFERENCETYPEINDEX_HASSUBTYPE))
36914 return (void*)0x01;
36915 return NULL;
36916}
36917
36918static UA_StatusCode
36919checkFunctionalGroupMethodReference(UA_Server *server, const UA_NodeHead *h,
36920 const UA_ExpandedNodeId *methodId,
36921 UA_Boolean *found) {
36922 /* Check whether the DI namespace is available */
36923 size_t foundNamespace = 0;
36924 UA_StatusCode res = getNamespaceByName(server, namespaceUri: namespaceDiModel, foundIndex: &foundNamespace);
36925 UA_CHECK_STATUS(res, return UA_STATUSCODE_BADMETHODINVALID);
36926 functionGroupNodeId.namespaceIndex = (UA_UInt16)foundNamespace;
36927
36928 UA_ReferenceTypeSet hasTypeDefinitionRefs;
36929 res = referenceTypeIndices(server, refType: &hasTypeDefinitionNodeId,
36930 indices: &hasTypeDefinitionRefs, true);
36931 UA_CHECK_STATUS(res, return res);
36932
36933 /* Search for a HasTypeDefinition (or sub-) reference to the FunctionGroupType */
36934 UA_Boolean isFunctionGroup = false;
36935 for(size_t i = 0; i < h->referencesSize && !isFunctionGroup; ++i) {
36936 UA_NodeReferenceKind *rk = &h->references[i];
36937 if(rk->isInverse)
36938 continue;
36939
36940 /* Are these HasTypeDefinition references */
36941 if(!UA_ReferenceTypeSet_contains(set: &hasTypeDefinitionRefs, index: rk->referenceTypeIndex))
36942 continue;
36943
36944 /* Reference points to FunctionGroupType (or sub-type) from the DI
36945 * model? */
36946 isFunctionGroup =
36947 (UA_NodeReferenceKind_iterate(rk, callback: iterateFunctionGroupSearch,
36948 context: server) != NULL);
36949 if(isFunctionGroup)
36950 break;
36951 }
36952 if(!isFunctionGroup)
36953 return UA_STATUSCODE_GOOD;
36954
36955 /* Search for the called method with reference Organize (or sub-type) from
36956 * the parent object */
36957 UA_ReferenceTypeSet organizesRefs;
36958 res = referenceTypeIndices(server, refType: &organizedByNodeId, indices: &organizesRefs, true);
36959 UA_CHECK_STATUS(res, return res);
36960 for(size_t k = 0; k < h->referencesSize; ++k) {
36961 const UA_NodeReferenceKind *rk = &h->references[k];
36962 if(rk->isInverse)
36963 continue;
36964 if(!UA_ReferenceTypeSet_contains(set: &organizesRefs, index: rk->referenceTypeIndex))
36965 continue;
36966 if(UA_NodeReferenceKind_findTarget(rk, targetId: methodId)) {
36967 *found = true;
36968 break;
36969 }
36970 }
36971 return UA_STATUSCODE_GOOD;
36972}
36973
36974static void
36975callWithMethodAndObject(UA_Server *server, UA_Session *session,
36976 const UA_CallMethodRequest *request, UA_CallMethodResult *result,
36977 const UA_MethodNode *method, const UA_ObjectNode *object) {
36978 UA_LOCK_ASSERT(&server->serviceMutex, 1);
36979
36980 /* Verify the object's NodeClass */
36981 if(object->head.nodeClass != UA_NODECLASS_OBJECT &&
36982 object->head.nodeClass != UA_NODECLASS_OBJECTTYPE) {
36983 result->statusCode = UA_STATUSCODE_BADNODECLASSINVALID;
36984 return;
36985 }
36986
36987 /* Verify the method's NodeClass */
36988 if(method->head.nodeClass != UA_NODECLASS_METHOD) {
36989 result->statusCode = UA_STATUSCODE_BADNODECLASSINVALID;
36990 return;
36991 }
36992
36993 /* Is there a method to execute? */
36994 if(!method->method) {
36995 result->statusCode = UA_STATUSCODE_BADINTERNALERROR;
36996 return;
36997 }
36998
36999 /* Verify method/object relations. Object must have a hasComponent or a
37000 * subtype of hasComponent reference to the method node. Therefore, check
37001 * every reference between the parent object and the method node if there is
37002 * a hasComponent (or subtype) reference */
37003 UA_ExpandedNodeId methodId = UA_EXPANDEDNODEID_NODEID(nodeId: request->methodId);
37004 UA_ReferenceTypeSet hasComponentRefs;
37005 result->statusCode = referenceTypeIndices(server, refType: &hasComponentNodeId,
37006 indices: &hasComponentRefs, true);
37007 UA_CHECK_STATUS(result->statusCode, return);
37008 UA_Boolean found = checkMethodReference(h: &object->head, refs: hasComponentRefs, methodId: &methodId);
37009
37010 if(!found) {
37011 /* If the object doesn't have a hasComponent reference to the method node,
37012 * check its objectType (and its supertypes). Invoked method can be a component
37013 * of objectType and be invoked on this objectType's instance (or on a instance
37014 * of one of its subtypes). */
37015 const UA_Node *objectType = getNodeType(server, head: &object->head);
37016 if(objectType) {
37017 found = checkMethodReference(h: &objectType->head, refs: hasComponentRefs, methodId: &methodId);
37018 UA_NODESTORE_RELEASE(server, objectType);
37019 }
37020 }
37021
37022 if(!found) {
37023 /* The following ParentObject evaluation is a workaround only to fulfill
37024 * the OPC UA Spec. Part 100 - Devices requirements regarding functional
37025 * groups. Compare OPC UA Spec. Part 100 - Devices, Release 1.02
37026 * - 5.4 FunctionalGroupType
37027 * - B.1 Functional Group Usages
37028 * A functional group is a sub-type of the FolderType and is used to
37029 * organize the Parameters and Methods from the complete set (named
37030 * ParameterSet and MethodSet) in (Functional) groups for instance
37031 * Configuration or Identification. The same Property, Parameter or
37032 * Method can be referenced from more than one FunctionalGroup. */
37033 result->statusCode =
37034 checkFunctionalGroupMethodReference(server, h: &object->head, methodId: &methodId, found: &found);
37035 if(!found && result->statusCode == UA_STATUSCODE_GOOD)
37036 result->statusCode = UA_STATUSCODE_BADMETHODINVALID;
37037 UA_CHECK_STATUS(result->statusCode, return);
37038 }
37039
37040 /* Verify access rights */
37041 UA_Boolean executable = method->executable;
37042 if(session != &server->adminSession) {
37043 executable = executable && server->config.accessControl.
37044 getUserExecutableOnObject(server, &server->config.accessControl,
37045 &session->sessionId, session->sessionHandle,
37046 &request->methodId, method->head.context,
37047 &request->objectId, object->head.context);
37048 }
37049
37050 if(!executable) {
37051 result->statusCode = UA_STATUSCODE_BADNOTEXECUTABLE;
37052 return;
37053 }
37054
37055 /* The input arguments are const and not changed. We move the input
37056 * arguments to a secondary array that is mutable. This is used for small
37057 * adjustments on the type level during the type checking. But it has to be
37058 * ensured that the original array can still by _clear'ed after the methods
37059 * call. */
37060 if(request->inputArgumentsSize > UA_MAX_METHOD_ARGUMENTS) {
37061 result->statusCode = UA_STATUSCODE_BADTOOMANYARGUMENTS;
37062 return;
37063 }
37064 UA_Variant mutableInputArgs[UA_MAX_METHOD_ARGUMENTS];
37065 memcpy(dest: mutableInputArgs, src: request->inputArguments,
37066 n: sizeof(UA_Variant) * request->inputArgumentsSize);
37067
37068 /* Allocate the inputArgumentResults array */
37069 result->inputArgumentResults = (UA_StatusCode*)
37070 UA_Array_new(size: request->inputArgumentsSize, type: &UA_TYPES[UA_TYPES_STATUSCODE]);
37071 if(!result->inputArgumentResults) {
37072 result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
37073 return;
37074 }
37075 result->inputArgumentResultsSize = request->inputArgumentsSize;
37076
37077 /* Type-check the input arguments */
37078 const UA_VariableNode *inputArguments =
37079 getArgumentsVariableNode(server, head: &method->head, withBrowseName: UA_STRING(chars: "InputArguments"));
37080 if(inputArguments) {
37081 result->statusCode =
37082 checkAdjustArguments(server, session, argRequirements: inputArguments, argsSize: request->inputArgumentsSize,
37083 args: mutableInputArgs, inputArgumentResults: result->inputArgumentResults);
37084 UA_NODESTORE_RELEASE(server, (const UA_Node*)inputArguments);
37085 } else {
37086 if(request->inputArgumentsSize > 0) {
37087 result->statusCode = UA_STATUSCODE_BADTOOMANYARGUMENTS;
37088 return;
37089 }
37090 }
37091
37092 /* Return inputArgumentResults only for BADINVALIDARGUMENT */
37093 if(result->statusCode != UA_STATUSCODE_BADINVALIDARGUMENT) {
37094 UA_Array_delete(p: result->inputArgumentResults, size: result->inputArgumentResultsSize,
37095 type: &UA_TYPES[UA_TYPES_STATUSCODE]);
37096 result->inputArgumentResults = NULL;
37097 result->inputArgumentResultsSize = 0;
37098 }
37099
37100 /* Error during type-checking? */
37101 if(result->statusCode != UA_STATUSCODE_GOOD)
37102 return;
37103
37104 /* Get the output arguments node */
37105 const UA_VariableNode *outputArguments =
37106 getArgumentsVariableNode(server, head: &method->head, withBrowseName: UA_STRING(chars: "OutputArguments"));
37107
37108 /* Allocate the output arguments array */
37109 size_t outputArgsSize = 0;
37110 if(outputArguments)
37111 outputArgsSize = outputArguments->value.data.value.value.arrayLength;
37112 result->outputArguments = (UA_Variant*)
37113 UA_Array_new(size: outputArgsSize, type: &UA_TYPES[UA_TYPES_VARIANT]);
37114 if(!result->outputArguments) {
37115 result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
37116 return;
37117 }
37118 result->outputArgumentsSize = outputArgsSize;
37119
37120 /* Release the output arguments node */
37121 UA_NODESTORE_RELEASE(server, (const UA_Node*)outputArguments);
37122
37123 /* Call the method. If this is an async method, unlock the server lock for
37124 * the duration of the (long-running) call. */
37125#if UA_MULTITHREADING >= 100
37126 if(method->async)
37127 unlockServer(server);
37128#endif
37129 result->statusCode = method->method(server, &session->sessionId, session->sessionHandle,
37130 &method->head.nodeId, method->head.context,
37131 &object->head.nodeId, object->head.context,
37132 request->inputArgumentsSize, mutableInputArgs,
37133 result->outputArgumentsSize, result->outputArguments);
37134#if UA_MULTITHREADING >= 100
37135 if(method->async)
37136 lockServer(server);
37137#endif
37138
37139 /* TODO: Verify Output matches the argument definition */
37140}
37141
37142#if UA_MULTITHREADING >= 100
37143
37144static void
37145Operation_CallMethodAsync(UA_Server *server, UA_Session *session, UA_UInt32 requestId,
37146 UA_UInt32 requestHandle, size_t opIndex,
37147 UA_CallMethodRequest *opRequest, UA_CallMethodResult *opResult,
37148 UA_AsyncResponse **ar) {
37149 /* Get the method node. We only need the nodeClass and executable attribute.
37150 * Take all forward hasProperty references to get the input/output argument
37151 * definition variables. */
37152 const UA_Node *method =
37153 UA_NODESTORE_GET_SELECTIVE(server, &opRequest->methodId,
37154 UA_NODEATTRIBUTESMASK_NODECLASS |
37155 UA_NODEATTRIBUTESMASK_EXECUTABLE,
37156 UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASPROPERTY),
37157 UA_BROWSEDIRECTION_FORWARD);
37158 if(!method) {
37159 opResult->statusCode = UA_STATUSCODE_BADMETHODINVALID;
37160 return;
37161 }
37162
37163 /* Get the object node. We only need the NodeClass attribute. But take all
37164 * references for now.
37165 *
37166 * TODO: Which references do we need actually? */
37167 const UA_Node *object =
37168 UA_NODESTORE_GET_SELECTIVE(server, &opRequest->objectId,
37169 UA_NODEATTRIBUTESMASK_NODECLASS,
37170 UA_REFERENCETYPESET_ALL,
37171 UA_BROWSEDIRECTION_BOTH);
37172 if(!object) {
37173 opResult->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN;
37174 UA_NODESTORE_RELEASE(server, method);
37175 return;
37176 }
37177
37178 /* Synchronous execution */
37179 if(!method->methodNode.async) {
37180 callWithMethodAndObject(server, session, opRequest, opResult,
37181 &method->methodNode, &object->objectNode);
37182 goto cleanup;
37183 }
37184
37185 /* <-- Async method call --> */
37186
37187 /* No AsyncResponse allocated so far */
37188 if(!*ar) {
37189 opResult->statusCode =
37190 UA_AsyncManager_createAsyncResponse(&server->asyncManager, server,
37191 &session->sessionId, requestId, requestHandle,
37192 UA_ASYNCOPERATIONTYPE_CALL, ar);
37193 if(opResult->statusCode != UA_STATUSCODE_GOOD)
37194 goto cleanup;
37195 }
37196
37197 /* Create the Async Request to be taken by workers */
37198 opResult->statusCode =
37199 UA_AsyncManager_createAsyncOp(&server->asyncManager,
37200 server, *ar, opIndex, opRequest);
37201
37202 cleanup:
37203 /* Release the method and object node */
37204 UA_NODESTORE_RELEASE(server, method);
37205 UA_NODESTORE_RELEASE(server, object);
37206}
37207
37208void
37209Service_CallAsync(UA_Server *server, UA_Session *session, UA_UInt32 requestId,
37210 const UA_CallRequest *request, UA_CallResponse *response,
37211 UA_Boolean *finished) {
37212 UA_LOG_DEBUG_SESSION(server->config.logging, session, "Processing CallRequestAsync");
37213 if(server->config.maxNodesPerMethodCall != 0 &&
37214 request->methodsToCallSize > server->config.maxNodesPerMethodCall) {
37215 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
37216 return;
37217 }
37218
37219 UA_AsyncResponse *ar = NULL;
37220 response->responseHeader.serviceResult =
37221 UA_Server_processServiceOperationsAsync(server, session, requestId,
37222 request->requestHeader.requestHandle,
37223 (UA_AsyncServiceOperation)Operation_CallMethodAsync,
37224 &request->methodsToCallSize, &UA_TYPES[UA_TYPES_CALLMETHODREQUEST],
37225 &response->resultsSize, &UA_TYPES[UA_TYPES_CALLMETHODRESULT], &ar);
37226
37227 if(ar) {
37228 if(ar->opCountdown > 0) {
37229 /* Move all results to the AsyncResponse. The async operation
37230 * results will be overwritten when the workers return results. */
37231 ar->response.callResponse = *response;
37232 UA_CallResponse_init(response);
37233 *finished = false;
37234 } else {
37235 /* If there is a new AsyncResponse, ensure it has at least one
37236 * pending operation */
37237 UA_AsyncManager_removeAsyncResponse(&server->asyncManager, ar);
37238 }
37239 }
37240}
37241#endif
37242
37243static void
37244Operation_CallMethod(UA_Server *server, UA_Session *session, void *context,
37245 const UA_CallMethodRequest *request, UA_CallMethodResult *result) {
37246 /* Get the method node. We only need the nodeClass and executable attribute.
37247 * Take all forward hasProperty references to get the input/output argument
37248 * definition variables. */
37249 const UA_Node *method =
37250 UA_NODESTORE_GET_SELECTIVE(server, &request->methodId,
37251 UA_NODEATTRIBUTESMASK_NODECLASS |
37252 UA_NODEATTRIBUTESMASK_EXECUTABLE,
37253 UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASPROPERTY),
37254 UA_BROWSEDIRECTION_FORWARD);
37255 if(!method) {
37256 result->statusCode = UA_STATUSCODE_BADMETHODINVALID;
37257 return;
37258 }
37259
37260 /* Get the object node. We only need the NodeClass attribute. But take all
37261 * references for now.
37262 *
37263 * TODO: Which references do we need actually? */
37264 const UA_Node *object =
37265 UA_NODESTORE_GET_SELECTIVE(server, &request->objectId,
37266 UA_NODEATTRIBUTESMASK_NODECLASS,
37267 UA_REFERENCETYPESET_ALL,
37268 UA_BROWSEDIRECTION_BOTH);
37269 if(!object) {
37270 result->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN;
37271 UA_NODESTORE_RELEASE(server, method);
37272 return;
37273 }
37274
37275 /* Continue with method and object as context */
37276 callWithMethodAndObject(server, session, request, result,
37277 method: &method->methodNode, object: &object->objectNode);
37278
37279 /* Release the method and object node */
37280 UA_NODESTORE_RELEASE(server, method);
37281 UA_NODESTORE_RELEASE(server, object);
37282}
37283
37284void Service_Call(UA_Server *server, UA_Session *session,
37285 const UA_CallRequest *request, UA_CallResponse *response) {
37286 UA_LOG_DEBUG_SESSION(server->config.logging, session, "Processing CallRequest");
37287 UA_LOCK_ASSERT(&server->serviceMutex, 1);
37288
37289 if(server->config.maxNodesPerMethodCall != 0 &&
37290 request->methodsToCallSize > server->config.maxNodesPerMethodCall) {
37291 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
37292 return;
37293 }
37294
37295 response->responseHeader.serviceResult =
37296 UA_Server_processServiceOperations(server, session,
37297 operationCallback: (UA_ServiceOperation)Operation_CallMethod, NULL,
37298 requestOperations: &request->methodsToCallSize, requestOperationsType: &UA_TYPES[UA_TYPES_CALLMETHODREQUEST],
37299 responseOperations: &response->resultsSize, responseOperationsType: &UA_TYPES[UA_TYPES_CALLMETHODRESULT]);
37300}
37301
37302UA_CallMethodResult
37303UA_Server_call(UA_Server *server, const UA_CallMethodRequest *request) {
37304 UA_CallMethodResult result;
37305 UA_CallMethodResult_init(p: &result);
37306 lockServer(server);
37307 Operation_CallMethod(server, session: &server->adminSession, NULL, request, result: &result);
37308 unlockServer(server);
37309 return result;
37310}
37311
37312#endif /* UA_ENABLE_METHODCALLS */
37313
37314/**** amalgamated original file "/src/server/ua_services_session.c" ****/
37315
37316/* This Source Code Form is subject to the terms of the Mozilla Public
37317 * License, v. 2.0. If a copy of the MPL was not distributed with this
37318 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
37319 *
37320 * Copyright 2014-2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
37321 * Copyright 2014-2017 (c) Florian Palm
37322 * Copyright 2014-2016 (c) Sten Grüner
37323 * Copyright 2015 (c) Chris Iatrou
37324 * Copyright 2015 (c) Oleksiy Vasylyev
37325 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
37326 * Copyright 2017-2018 (c) Mark Giraud, Fraunhofer IOSB
37327 * Copyright 2019 (c) Kalycito Infotech Private Limited
37328 * Copyright 2018-2020 (c) HMS Industrial Networks AB (Author: Jonas Green)
37329 */
37330
37331
37332/* Delayed callback to free the session memory */
37333static void
37334removeSessionCallback(UA_Server *server, session_list_entry *entry) {
37335 lockServer(server);
37336 UA_Session_clear(session: &entry->session, server);
37337 unlockServer(server);
37338 UA_free(ptr: entry);
37339}
37340
37341void
37342UA_Server_removeSession(UA_Server *server, session_list_entry *sentry,
37343 UA_ShutdownReason shutdownReason) {
37344 UA_Session *session = &sentry->session;
37345
37346 UA_LOCK_ASSERT(&server->serviceMutex, 1);
37347
37348 /* Remove the Subscriptions */
37349#ifdef UA_ENABLE_SUBSCRIPTIONS
37350 UA_Subscription *sub, *tempsub;
37351 TAILQ_FOREACH_SAFE(sub, &session->subscriptions, sessionListEntry, tempsub) {
37352 UA_Subscription_delete(server, sub);
37353 }
37354
37355 UA_PublishResponseEntry *entry;
37356 while((entry = UA_Session_dequeuePublishReq(session))) {
37357 UA_PublishResponse_clear(p: &entry->response);
37358 UA_free(ptr: entry);
37359 }
37360#endif
37361
37362 /* Callback into userland access control */
37363 if(server->config.accessControl.closeSession) {
37364 server->config.accessControl.
37365 closeSession(server, &server->config.accessControl,
37366 &session->sessionId, session->sessionHandle);
37367 }
37368
37369 /* Detach the Session from the SecureChannel */
37370 UA_Session_detachFromSecureChannel(session);
37371
37372 /* Deactivate the session */
37373 if(sentry->session.activated) {
37374 sentry->session.activated = false;
37375 server->activeSessionCount--;
37376 }
37377
37378 /* Detach the session from the session manager and make the capacity
37379 * available */
37380 LIST_REMOVE(sentry, pointers);
37381 server->sessionCount--;
37382
37383 switch(shutdownReason) {
37384 case UA_SHUTDOWNREASON_CLOSE:
37385 case UA_SHUTDOWNREASON_PURGE:
37386 break;
37387 case UA_SHUTDOWNREASON_TIMEOUT:
37388 server->serverDiagnosticsSummary.sessionTimeoutCount++;
37389 break;
37390 case UA_SHUTDOWNREASON_REJECT:
37391 server->serverDiagnosticsSummary.rejectedSessionCount++;
37392 break;
37393 case UA_SHUTDOWNREASON_SECURITYREJECT:
37394 server->serverDiagnosticsSummary.securityRejectedSessionCount++;
37395 break;
37396 case UA_SHUTDOWNREASON_ABORT:
37397 server->serverDiagnosticsSummary.sessionAbortCount++;
37398 break;
37399 default:
37400 UA_assert(false);
37401 break;
37402 }
37403
37404 /* Add a delayed callback to remove the session when the currently
37405 * scheduled jobs have completed */
37406 sentry->cleanupCallback.callback = (UA_Callback)removeSessionCallback;
37407 sentry->cleanupCallback.application = server;
37408 sentry->cleanupCallback.context = sentry;
37409 UA_EventLoop *el = server->config.eventLoop;
37410 el->addDelayedCallback(el, &sentry->cleanupCallback);
37411}
37412
37413UA_StatusCode
37414UA_Server_removeSessionByToken(UA_Server *server, const UA_NodeId *token,
37415 UA_ShutdownReason shutdownReason) {
37416 UA_LOCK_ASSERT(&server->serviceMutex, 1);
37417 session_list_entry *entry;
37418 LIST_FOREACH(entry, &server->sessions, pointers) {
37419 if(UA_NodeId_equal(p1: &entry->session.header.authenticationToken, p2: token)) {
37420 UA_Server_removeSession(server, sentry: entry, shutdownReason);
37421 return UA_STATUSCODE_GOOD;
37422 }
37423 }
37424 return UA_STATUSCODE_BADSESSIONIDINVALID;
37425}
37426
37427void
37428UA_Server_cleanupSessions(UA_Server *server, UA_DateTime nowMonotonic) {
37429 UA_LOCK_ASSERT(&server->serviceMutex, 1);
37430 session_list_entry *sentry, *temp;
37431 LIST_FOREACH_SAFE(sentry, &server->sessions, pointers, temp) {
37432 /* Session has timed out? */
37433 if(sentry->session.validTill >= nowMonotonic)
37434 continue;
37435 UA_LOG_INFO_SESSION(server->config.logging, &sentry->session,
37436 "Session has timed out");
37437 UA_Server_removeSession(server, sentry, shutdownReason: UA_SHUTDOWNREASON_TIMEOUT);
37438 }
37439}
37440
37441/************/
37442/* Services */
37443/************/
37444
37445UA_Session *
37446getSessionByToken(UA_Server *server, const UA_NodeId *token) {
37447 UA_LOCK_ASSERT(&server->serviceMutex, 1);
37448
37449 session_list_entry *current = NULL;
37450 LIST_FOREACH(current, &server->sessions, pointers) {
37451 /* Token does not match */
37452 if(!UA_NodeId_equal(p1: &current->session.header.authenticationToken, p2: token))
37453 continue;
37454
37455 /* Session has timed out */
37456 if(UA_DateTime_nowMonotonic() > current->session.validTill) {
37457 UA_LOG_INFO_SESSION(server->config.logging, &current->session,
37458 "Client tries to use a session that has timed out");
37459 return NULL;
37460 }
37461
37462 return &current->session;
37463 }
37464
37465 return NULL;
37466}
37467
37468UA_Session *
37469getSessionById(UA_Server *server, const UA_NodeId *sessionId) {
37470 UA_LOCK_ASSERT(&server->serviceMutex, 1);
37471
37472 session_list_entry *current = NULL;
37473 LIST_FOREACH(current, &server->sessions, pointers) {
37474 /* Token does not match */
37475 if(!UA_NodeId_equal(p1: &current->session.sessionId, p2: sessionId))
37476 continue;
37477
37478 /* Session has timed out */
37479 if(UA_DateTime_nowMonotonic() > current->session.validTill) {
37480 UA_LOG_INFO_SESSION(server->config.logging, &current->session,
37481 "Client tries to use a session that has timed out");
37482 return NULL;
37483 }
37484
37485 return &current->session;
37486 }
37487
37488 if(UA_NodeId_equal(p1: sessionId, p2: &server->adminSession.sessionId))
37489 return &server->adminSession;
37490
37491 return NULL;
37492}
37493
37494static UA_StatusCode
37495signCreateSessionResponse(UA_Server *server, UA_SecureChannel *channel,
37496 const UA_CreateSessionRequest *request,
37497 UA_CreateSessionResponse *response) {
37498 if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN &&
37499 channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
37500 return UA_STATUSCODE_GOOD;
37501
37502 const UA_SecurityPolicy *securityPolicy = channel->securityPolicy;
37503 UA_SignatureData *signatureData = &response->serverSignature;
37504
37505 /* Prepare the signature */
37506 const UA_SecurityPolicySignatureAlgorithm *signAlg =
37507 &securityPolicy->asymmetricModule.cryptoModule.signatureAlgorithm;
37508 size_t signatureSize = signAlg->getLocalSignatureSize(channel->channelContext);
37509 UA_StatusCode retval = UA_String_copy(src: &signAlg->uri, dst: &signatureData->algorithm);
37510 retval |= UA_ByteString_allocBuffer(bs: &signatureData->signature, length: signatureSize);
37511 if(retval != UA_STATUSCODE_GOOD)
37512 return retval;
37513
37514 /* Allocate a temp buffer */
37515 size_t dataToSignSize =
37516 request->clientCertificate.length + request->clientNonce.length;
37517 UA_ByteString dataToSign;
37518 retval = UA_ByteString_allocBuffer(bs: &dataToSign, length: dataToSignSize);
37519 if(retval != UA_STATUSCODE_GOOD)
37520 return retval; /* signatureData->signature is cleaned up with the response */
37521
37522 /* Sign the signature */
37523 memcpy(dest: dataToSign.data, src: request->clientCertificate.data,
37524 n: request->clientCertificate.length);
37525 memcpy(dest: dataToSign.data + request->clientCertificate.length,
37526 src: request->clientNonce.data, n: request->clientNonce.length);
37527 retval = securityPolicy->asymmetricModule.cryptoModule.signatureAlgorithm.
37528 sign(channel->channelContext, &dataToSign, &signatureData->signature);
37529
37530 /* Clean up */
37531 UA_ByteString_clear(p: &dataToSign);
37532 return retval;
37533}
37534
37535/* Creates and adds a session. But it is not yet attached to a secure channel. */
37536UA_StatusCode
37537UA_Server_createSession(UA_Server *server, UA_SecureChannel *channel,
37538 const UA_CreateSessionRequest *request, UA_Session **session) {
37539 UA_LOCK_ASSERT(&server->serviceMutex, 1);
37540
37541 if(server->sessionCount >= server->config.maxSessions) {
37542 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
37543 "Could not create a Session - Server limits reached");
37544 return UA_STATUSCODE_BADTOOMANYSESSIONS;
37545 }
37546
37547 session_list_entry *newentry = (session_list_entry*)
37548 UA_malloc(size: sizeof(session_list_entry));
37549 if(!newentry)
37550 return UA_STATUSCODE_BADOUTOFMEMORY;
37551
37552 /* Initialize the Session */
37553 UA_Session_init(session: &newentry->session);
37554 newentry->session.sessionId = UA_NODEID_GUID(nsIndex: 1, guid: UA_Guid_random());
37555 newentry->session.header.authenticationToken = UA_NODEID_GUID(nsIndex: 1, guid: UA_Guid_random());
37556
37557 newentry->session.timeout = server->config.maxSessionTimeout;
37558 if(request->requestedSessionTimeout <= server->config.maxSessionTimeout &&
37559 request->requestedSessionTimeout > 0)
37560 newentry->session.timeout = request->requestedSessionTimeout;
37561
37562 /* Attach the session to the channel. But don't activate for now. */
37563 if(channel)
37564 UA_Session_attachToSecureChannel(session: &newentry->session, channel);
37565 UA_Session_updateLifetime(session: &newentry->session);
37566
37567 /* Add to the server */
37568 LIST_INSERT_HEAD(&server->sessions, newentry, pointers);
37569 server->sessionCount++;
37570
37571 *session = &newentry->session;
37572 return UA_STATUSCODE_GOOD;
37573}
37574
37575void
37576Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
37577 const UA_CreateSessionRequest *request,
37578 UA_CreateSessionResponse *response) {
37579 UA_LOCK_ASSERT(&server->serviceMutex, 1);
37580 UA_LOG_DEBUG_CHANNEL(server->config.logging, channel, "Trying to create session");
37581
37582 if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
37583 channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
37584 /* Compare the clientCertificate with the remoteCertificate of the channel.
37585 * Both the clientCertificate of this request and the remoteCertificate
37586 * of the channel may contain a partial or a complete certificate chain.
37587 * The compareCertificate function of the channelModule will compare the
37588 * first certificate of each chain. The end certificate shall be located
37589 * first in the chain according to the OPC UA specification Part 6 (1.04),
37590 * chapter 6.2.3.*/
37591 UA_StatusCode retval = channel->securityPolicy->channelModule.
37592 compareCertificate(channel->channelContext, &request->clientCertificate);
37593 if(retval != UA_STATUSCODE_GOOD) {
37594 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
37595 "The client certificate did not validate");
37596 response->responseHeader.serviceResult = UA_STATUSCODE_BADCERTIFICATEINVALID;
37597 return;
37598 }
37599 }
37600
37601 UA_assert(channel->securityToken.channelId != 0);
37602
37603 if(!UA_ByteString_equal(p1: &channel->securityPolicy->policyUri,
37604 p2: &UA_SECURITY_POLICY_NONE_URI) &&
37605 request->clientNonce.length < 32) {
37606 response->responseHeader.serviceResult = UA_STATUSCODE_BADNONCEINVALID;
37607 return;
37608 }
37609
37610 if(request->clientCertificate.length > 0) {
37611 UA_CertificateVerification *cv = &server->config.sessionPKI;
37612 response->responseHeader.serviceResult =
37613 cv->verifyApplicationURI(cv, &request->clientCertificate,
37614 &request->clientDescription.applicationUri);
37615 if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
37616 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
37617 "The client's ApplicationURI did not match the certificate");
37618 server->serverDiagnosticsSummary.securityRejectedSessionCount++;
37619 server->serverDiagnosticsSummary.rejectedSessionCount++;
37620 return;
37621 }
37622 }
37623
37624 /* Create the Session */
37625 UA_Session *newSession = NULL;
37626 response->responseHeader.serviceResult =
37627 UA_Server_createSession(server, channel, request, session: &newSession);
37628 if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
37629 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
37630 "Processing CreateSessionRequest failed");
37631 server->serverDiagnosticsSummary.rejectedSessionCount++;
37632 return;
37633 }
37634
37635 /* If the session name is empty, use the generated SessionId */
37636 response->responseHeader.serviceResult |=
37637 UA_String_copy(src: &request->sessionName, dst: &newSession->sessionName);
37638 if(newSession->sessionName.length == 0)
37639 response->responseHeader.serviceResult |=
37640 UA_NodeId_print(id: &newSession->sessionId, output: &newSession->sessionName);
37641
37642 response->responseHeader.serviceResult |= UA_Session_generateNonce(session: newSession);
37643 newSession->maxResponseMessageSize = request->maxResponseMessageSize;
37644 newSession->maxRequestMessageSize = channel->config.localMaxMessageSize;
37645 response->responseHeader.serviceResult |=
37646 UA_ApplicationDescription_copy(src: &request->clientDescription,
37647 dst: &newSession->clientDescription);
37648
37649#ifdef UA_ENABLE_DIAGNOSTICS
37650 response->responseHeader.serviceResult |=
37651 UA_String_copy(src: &request->serverUri, dst: &newSession->diagnostics.serverUri);
37652 response->responseHeader.serviceResult |=
37653 UA_String_copy(src: &request->endpointUrl, dst: &newSession->diagnostics.endpointUrl);
37654#endif
37655
37656 /* Prepare the response */
37657 response->sessionId = newSession->sessionId;
37658 response->revisedSessionTimeout = (UA_Double)newSession->timeout;
37659 response->authenticationToken = newSession->header.authenticationToken;
37660 response->responseHeader.serviceResult |=
37661 UA_ByteString_copy(src: &newSession->serverNonce, dst: &response->serverNonce);
37662
37663 /* Copy the server's endpointdescriptions into the response */
37664 response->responseHeader.serviceResult =
37665 setCurrentEndPointsArray(server, endpointURL: request->endpointUrl, NULL, profileUrisSize: 0,
37666 arr: &response->serverEndpoints,
37667 arrSize: &response->serverEndpointsSize);
37668 if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
37669 UA_Server_removeSessionByToken(server, token: &newSession->header.authenticationToken,
37670 shutdownReason: UA_SHUTDOWNREASON_REJECT);
37671 return;
37672 }
37673
37674 /* Return the server certificate from the SecurityPolicy of the current
37675 * channel. Or, if the channel is unencrypted, return the standard policy
37676 * used for usertoken encryption. */
37677 const UA_SecurityPolicy *sp = channel->securityPolicy;
37678 if(UA_String_equal(p1: &UA_SECURITY_POLICY_NONE_URI, p2: &sp->policyUri) ||
37679 sp->localCertificate.length == 0)
37680 sp = getDefaultEncryptedSecurityPolicy(server);
37681 if(sp)
37682 response->responseHeader.serviceResult |=
37683 UA_ByteString_copy(src: &sp->localCertificate, dst: &response->serverCertificate);
37684
37685 /* Sign the signature */
37686 response->responseHeader.serviceResult |=
37687 signCreateSessionResponse(server, channel, request, response);
37688
37689 /* Failure -> remove the session */
37690 if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
37691 UA_Server_removeSessionByToken(server, token: &newSession->header.authenticationToken,
37692 shutdownReason: UA_SHUTDOWNREASON_REJECT);
37693 return;
37694 }
37695
37696#ifdef UA_ENABLE_DIAGNOSTICS
37697 newSession->diagnostics.clientConnectionTime = UA_DateTime_now();
37698 newSession->diagnostics.clientLastContactTime =
37699 newSession->diagnostics.clientConnectionTime;
37700
37701 /* Create the object in the information model */
37702 createSessionObject(server, session: newSession);
37703#endif
37704
37705 UA_LOG_INFO_SESSION(server->config.logging, newSession, "Session created");
37706}
37707
37708static UA_StatusCode
37709checkCertificateSignature(const UA_Server *server, const UA_SecurityPolicy *securityPolicy,
37710 void *channelContext, const UA_ByteString *serverNonce,
37711 const UA_SignatureData *signature,
37712 const bool isUserTokenSignature) {
37713 /* Check for zero signature length */
37714 if(signature->signature.length == 0) {
37715 if(isUserTokenSignature)
37716 return UA_STATUSCODE_BADUSERSIGNATUREINVALID;
37717 return UA_STATUSCODE_BADAPPLICATIONSIGNATUREINVALID;
37718 }
37719
37720 if(!securityPolicy)
37721 return UA_STATUSCODE_BADINTERNALERROR;
37722
37723 /* Server certificate */
37724 const UA_ByteString *localCertificate = &securityPolicy->localCertificate;
37725 /* Data to verify is calculated by appending the serverNonce to the local certificate */
37726 UA_ByteString dataToVerify;
37727 size_t dataToVerifySize = localCertificate->length + serverNonce->length;
37728 UA_StatusCode retval = UA_ByteString_allocBuffer(bs: &dataToVerify, length: dataToVerifySize);
37729 if(retval != UA_STATUSCODE_GOOD)
37730 return retval;
37731
37732 memcpy(dest: dataToVerify.data, src: localCertificate->data, n: localCertificate->length);
37733 memcpy(dest: dataToVerify.data + localCertificate->length,
37734 src: serverNonce->data, n: serverNonce->length);
37735 retval = securityPolicy->asymmetricModule.cryptoModule.signatureAlgorithm.
37736 verify(channelContext, &dataToVerify, &signature->signature);
37737 UA_ByteString_clear(p: &dataToVerify);
37738 if(retval != UA_STATUSCODE_GOOD) {
37739 if(isUserTokenSignature)
37740 retval = UA_STATUSCODE_BADUSERSIGNATUREINVALID;
37741 else
37742 retval = UA_STATUSCODE_BADAPPLICATIONSIGNATUREINVALID;
37743 }
37744 return retval;
37745}
37746
37747static void
37748selectEndpointAndTokenPolicy(UA_Server *server, UA_SecureChannel *channel,
37749 const UA_ExtensionObject *identityToken,
37750 const UA_EndpointDescription **ed,
37751 const UA_UserTokenPolicy **utp,
37752 const UA_SecurityPolicy **tokenSp) {
37753 UA_ServerConfig *sc = &server->config;
37754 for(size_t i = 0; i < sc->endpointsSize; ++i) {
37755 const UA_EndpointDescription *desc = &sc->endpoints[i];
37756
37757 /* Match the Security Mode */
37758 if(desc->securityMode != channel->securityMode)
37759 continue;
37760
37761 /* Match the SecurityPolicy of the endpoint with the current channel */
37762 if(!UA_String_equal(p1: &desc->securityPolicyUri, p2: &channel->securityPolicy->policyUri))
37763 continue;
37764
37765 /* If no UserTokenPolicies are configured in the endpoint, then use
37766 * those of the AccessControl plugin. */
37767 size_t identPoliciesSize = desc->userIdentityTokensSize;
37768 const UA_UserTokenPolicy *identPolicies = desc->userIdentityTokens;
37769 if(identPoliciesSize == 0) {
37770 identPoliciesSize = sc->accessControl.userTokenPoliciesSize;
37771 identPolicies = sc->accessControl.userTokenPolicies;
37772 }
37773
37774 /* Match the UserTokenType */
37775 const UA_DataType *tokenDataType = identityToken->content.decoded.type;
37776 for(size_t j = 0; j < identPoliciesSize ; j++) {
37777 const UA_UserTokenPolicy *pol = &identPolicies[j];
37778
37779 /* Part 4, Section 5.6.3.2, Table 17: A NULL or empty
37780 * UserIdentityToken should be treated as Anonymous */
37781 if(identityToken->encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY &&
37782 pol->tokenType == UA_USERTOKENTYPE_ANONYMOUS) {
37783 *ed = desc;
37784 *utp = pol;
37785 return;
37786 }
37787
37788 /* Expect decoded content if not anonymous */
37789 if(!tokenDataType)
37790 continue;
37791
37792 if(pol->tokenType == UA_USERTOKENTYPE_ANONYMOUS) {
37793 if(tokenDataType != &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN])
37794 continue;
37795 } else if(pol->tokenType == UA_USERTOKENTYPE_USERNAME) {
37796 if(tokenDataType != &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN])
37797 continue;
37798 } else if(pol->tokenType == UA_USERTOKENTYPE_CERTIFICATE) {
37799 if(tokenDataType != &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN])
37800 continue;
37801 } else if(pol->tokenType == UA_USERTOKENTYPE_ISSUEDTOKEN) {
37802 if(tokenDataType != &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN])
37803 continue;
37804 } else {
37805 continue;
37806 }
37807
37808 /* All valid token data types start with a string policyId */
37809 UA_AnonymousIdentityToken *token = (UA_AnonymousIdentityToken*)
37810 identityToken->content.decoded.data;
37811
37812 /* Select the SecurityPolicy used to encrypt the token.
37813 * The default is to use the SecurityPolicy of the SecureChannel. */
37814 *tokenSp = channel->securityPolicy;
37815#ifdef UA_ENABLE_ENCRYPTION
37816 if(identPolicies == sc->accessControl.userTokenPolicies) {
37817 /* If the standard UserTokenPolicies from the AccessControl
37818 * plugin are used, use the same logic as in
37819 * updateEndpointUserIdentityToken (ua_services_discovery.c). */
37820 if(pol->tokenType != UA_USERTOKENTYPE_ANONYMOUS &&
37821 !(sc->allowNonePolicyPassword && pol->tokenType == UA_USERTOKENTYPE_USERNAME) &&
37822 UA_String_equal(p1: &channel->securityPolicy->policyUri, p2: &UA_SECURITY_POLICY_NONE_URI))
37823 *tokenSp = getDefaultEncryptedSecurityPolicy(server);
37824 } else if(pol->securityPolicyUri.length > 0) {
37825 /* Manually defined UserTokenPolicy. Lookup by URI */
37826 *tokenSp = getSecurityPolicyByUri(server, securityPolicyUri: &pol->securityPolicyUri);
37827 }
37828 if(!*tokenSp)
37829 continue;
37830
37831 /* Anonymous tokens don't need encryption. All other tokens require
37832 * encryption with the exception of Username/Password if also the
37833 * allowNonePolicyPassword option has been set. */
37834 if(pol->tokenType != UA_USERTOKENTYPE_ANONYMOUS &&
37835 !(sc->allowNonePolicyPassword && pol->tokenType == UA_USERTOKENTYPE_USERNAME) &&
37836 UA_String_equal(p1: &UA_SECURITY_POLICY_NONE_URI, p2: &(*tokenSp)->policyUri))
37837 continue;
37838#endif
37839
37840 /* In setCurrentEndPointsArray we prepend the PolicyId with the
37841 * SecurityMode of the endpoint and the postfix of the
37842 * SecurityPolicyUri to make it unique. Check the SecurityPolicyUri
37843 * postfix. */
37844 if(pol->policyId.length > token->policyId.length)
37845 continue;
37846 UA_String policyPrefix = token->policyId;
37847 policyPrefix.length = pol->policyId.length;
37848 if(!UA_String_equal(p1: &policyPrefix, p2: &pol->policyId))
37849 continue;
37850
37851 UA_String secPolPostfix = securityPolicyUriPostfix(uri: (*tokenSp)->policyUri);
37852 UA_String utPolPostfix = securityPolicyUriPostfix(uri: token->policyId);
37853 if(!UA_String_equal(p1: &secPolPostfix, p2: &utPolPostfix))
37854 continue;
37855
37856 /* Match found */
37857 *ed = desc;
37858 *utp = pol;
37859 return;
37860 }
37861 }
37862}
37863
37864#ifdef UA_ENABLE_ENCRYPTION
37865static UA_StatusCode
37866decryptUserToken(UA_Server *server, UA_Session *session,
37867 UA_SecureChannel *channel, const UA_SecurityPolicy *sp,
37868 const UA_String encryptionAlgorithm, UA_String *encrypted) {
37869 /* If SecurityPolicy is None there shall be no EncryptionAlgorithm */
37870 if(UA_String_equal(p1: &sp->policyUri, p2: &UA_SECURITY_POLICY_NONE_URI)) {
37871 if(encryptionAlgorithm.length > 0)
37872 return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
37873 if(channel->securityMode == UA_MESSAGESECURITYMODE_NONE) {
37874 UA_LOG_WARNING_SESSION(server->config.logging, session, "ActivateSession: "
37875 "Received an unencrypted UserToken. "
37876 "Is the server misconfigured to allow that?");
37877 }
37878 return UA_STATUSCODE_GOOD;
37879 }
37880
37881 /* Test if the correct encryption algorithm is used */
37882 if(!UA_String_equal(p1: &encryptionAlgorithm,
37883 p2: &sp->asymmetricModule.cryptoModule.encryptionAlgorithm.uri))
37884 return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
37885
37886 /* Encrypted password -- Create a temporary channel context.
37887 * TODO: We should not need a ChannelContext at all for asymmetric
37888 * decryption where the remote certificate is not used. */
37889 void *tempChannelContext = NULL;
37890 UA_StatusCode res = sp->channelModule.newContext(sp, &sp->localCertificate, &tempChannelContext);
37891 if(res != UA_STATUSCODE_GOOD) {
37892 UA_LOG_WARNING_SESSION(server->config.logging, session,
37893 "ActivateSession: Failed to create a "
37894 "context for the SecurityPolicy %.*s",
37895 (int)sp->policyUri.length,
37896 sp->policyUri.data);
37897 return res;
37898 }
37899
37900 UA_UInt32 secretLen = 0;
37901 UA_ByteString secret, tokenNonce;
37902 size_t tokenpos = 0;
37903 size_t offset = 0;
37904 UA_ByteString *sn = &session->serverNonce;
37905 const UA_SecurityPolicyEncryptionAlgorithm *asymEnc =
37906 &sp->asymmetricModule.cryptoModule.encryptionAlgorithm;
37907
37908 res = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
37909
37910 /* Decrypt the secret */
37911 if(UA_ByteString_copy(src: encrypted, dst: &secret) != UA_STATUSCODE_GOOD ||
37912 asymEnc->decrypt(tempChannelContext, &secret) != UA_STATUSCODE_GOOD)
37913 goto cleanup;
37914
37915 /* The secret starts with a UInt32 length for the content */
37916 if(UA_UInt32_decodeBinary(src: &secret, offset: &offset, dst: &secretLen) != UA_STATUSCODE_GOOD)
37917 goto cleanup;
37918
37919 /* The decrypted data must be large enough to include the Encrypted Token
37920 * Secret Format and the length field must indicate enough data to include
37921 * the server nonce. */
37922 if(secret.length < sizeof(UA_UInt32) + sn->length ||
37923 secret.length < sizeof(UA_UInt32) + secretLen ||
37924 secretLen < sn->length)
37925 goto cleanup;
37926
37927 /* If the Encrypted Token Secret contains padding, the padding must be
37928 * zeroes according to the 1.04.1 specification errata, chapter 3. */
37929 for(size_t i = sizeof(UA_UInt32) + secretLen; i < secret.length; i++) {
37930 if(secret.data[i] != 0)
37931 goto cleanup;
37932 }
37933
37934 /* The server nonce must match according to the 1.04.1 specification errata,
37935 * chapter 3. */
37936 tokenpos = sizeof(UA_UInt32) + secretLen - sn->length;
37937 tokenNonce.length = sn->length;
37938 tokenNonce.data = &secret.data[tokenpos];
37939 if(!UA_ByteString_equal(p1: sn, p2: &tokenNonce))
37940 goto cleanup;
37941
37942 /* The password was decrypted successfully. Replace usertoken with the
37943 * decrypted password. The encryptionAlgorithm and policyId fields are left
37944 * in the UserToken as an indication for the AccessControl plugin that
37945 * evaluates the decrypted content. */
37946 memcpy(dest: encrypted->data,
37947 src: &secret.data[sizeof(UA_UInt32)], n: secretLen - sn->length);
37948 encrypted->length = secretLen - sn->length;
37949 res = UA_STATUSCODE_GOOD;
37950
37951 cleanup:
37952 UA_ByteString_clear(p: &secret);
37953
37954 /* Remove the temporary channel context */
37955 sp->channelModule.deleteContext(tempChannelContext);
37956
37957 if(res != UA_STATUSCODE_GOOD) {
37958 UA_LOG_WARNING_SESSION(server->config.logging, session,
37959 "ActivateSession: Failed to decrypt the "
37960 "password with the StatusCode %s",
37961 UA_StatusCode_name(res));
37962 }
37963 return res;
37964}
37965
37966static UA_StatusCode
37967checkActivateSessionX509(UA_Server *server, UA_Session *session,
37968 const UA_SecurityPolicy *sp, UA_X509IdentityToken* token,
37969 const UA_SignatureData *tokenSignature) {
37970 /* The SecurityPolicy must not be None for the signature */
37971 if(UA_String_equal(p1: &sp->policyUri, p2: &UA_SECURITY_POLICY_NONE_URI))
37972 return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
37973
37974 /* We need a channel context with the user certificate in order to reuse
37975 * the signature checking code. */
37976 void *tempChannelContext;
37977 UA_StatusCode res = sp->channelModule. newContext(sp, &token->certificateData, &tempChannelContext);
37978 if(res != UA_STATUSCODE_GOOD) {
37979 UA_LOG_WARNING_SESSION(server->config.logging, session,
37980 "ActivateSession: Failed to create a context "
37981 "for the SecurityPolicy %.*s",
37982 (int)sp->policyUri.length,
37983 sp->policyUri.data);
37984 return res;
37985 }
37986
37987 /* Check the user token signature */
37988 res = checkCertificateSignature(server, securityPolicy: sp, channelContext: tempChannelContext,
37989 serverNonce: &session->serverNonce, signature: tokenSignature, true);
37990 if(res != UA_STATUSCODE_GOOD) {
37991 UA_LOG_WARNING_SESSION(server->config.logging, session,
37992 "ActivateSession: User token signature check "
37993 "failed with StatusCode %s", UA_StatusCode_name(res));
37994 }
37995
37996 /* Delete the temporary channel context */
37997 sp->channelModule.deleteContext(tempChannelContext);
37998 return res;
37999}
38000#endif
38001
38002/* TODO: Check all of the following: The Server shall verify that the
38003 * Certificate the Client used to create the new SecureChannel is the same as
38004 * the Certificate used to create the original SecureChannel. In addition, the
38005 * Server shall verify that the Client supplied a UserIdentityToken that is
38006 * identical to the token currently associated with the Session. Once the Server
38007 * accepts the new SecureChannel it shall reject requests sent via the old
38008 * SecureChannel. */
38009
38010void
38011Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel,
38012 const UA_ActivateSessionRequest *req,
38013 UA_ActivateSessionResponse *resp) {
38014 UA_LOCK_ASSERT(&server->serviceMutex, 1);
38015 const UA_EndpointDescription *ed = NULL;
38016 const UA_UserTokenPolicy *utp = NULL;
38017 const UA_SecurityPolicy *tokenSp = NULL;
38018 UA_String *tmpLocaleIds;
38019
38020 /* Get the session */
38021 UA_Session *session = getSessionByToken(server, token: &req->requestHeader.authenticationToken);
38022 if(!session) {
38023 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
38024 "ActivateSession: Session not found");
38025 resp->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
38026 goto rejected;
38027 }
38028
38029 /* Part 4, §5.6.3: When the ActivateSession Service is called for the
38030 * first time then the Server shall reject the request if the
38031 * SecureChannel is not same as the one associated with the
38032 * CreateSession request. Subsequent calls to ActivateSession may be
38033 * associated with different SecureChannels. */
38034 if(!session->activated && session->header.channel != channel) {
38035 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
38036 "ActivateSession: The Session has to be initially activated "
38037 "on the SecureChannel that created it");
38038 resp->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
38039 goto rejected;
38040 }
38041
38042 /* Has the session timed out? */
38043 if(session->validTill < UA_DateTime_nowMonotonic()) {
38044 UA_LOG_WARNING_SESSION(server->config.logging, session,
38045 "ActivateSession: The Session has timed out");
38046 resp->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
38047 goto rejected;
38048 }
38049
38050 /* Check the client signature */
38051 if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
38052 channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
38053 resp->responseHeader.serviceResult =
38054 checkCertificateSignature(server, securityPolicy: channel->securityPolicy,
38055 channelContext: channel->channelContext,
38056 serverNonce: &session->serverNonce,
38057 signature: &req->clientSignature, false);
38058 if(resp->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
38059 UA_LOG_WARNING_SESSION(server->config.logging, session,
38060 "ActivateSession: Client signature check failed "
38061 "with StatusCode %s",
38062 UA_StatusCode_name(resp->responseHeader.serviceResult));
38063 goto securityRejected;
38064 }
38065 }
38066
38067 /* Find the matching Endpoint with UserTokenPolicy.
38068 * Also sets the SecurityPolicy used to encrypt the token. */
38069 selectEndpointAndTokenPolicy(server, channel, identityToken: &req->userIdentityToken,
38070 ed: &ed, utp: &utp, tokenSp: &tokenSp);
38071 if(!ed || !tokenSp) {
38072 resp->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
38073 goto rejected;
38074 }
38075
38076 /* Decrypt (or validate the signature) of the UserToken. The DataType of the
38077 * UserToken was already checked in selectEndpointAndTokenPolicy */
38078#ifdef UA_ENABLE_ENCRYPTION
38079 if(utp->tokenType == UA_USERTOKENTYPE_USERNAME) {
38080 /* If it is a UserNameIdentityToken, the password may be encrypted */
38081 UA_UserNameIdentityToken *userToken = (UA_UserNameIdentityToken *)
38082 req->userIdentityToken.content.decoded.data;
38083 resp->responseHeader.serviceResult =
38084 decryptUserToken(server, session, channel, sp: tokenSp,
38085 encryptionAlgorithm: userToken->encryptionAlgorithm, encrypted: &userToken->password);
38086 } else if(utp->tokenType == UA_USERTOKENTYPE_CERTIFICATE) {
38087 /* If it is a X509IdentityToken, check the userTokenSignature. Note this
38088 * only validates that the user has the corresponding private key for
38089 * the given user certificate. Checking whether the user certificate is
38090 * trusted has to be implemented in the access control plugin. The
38091 * entire token is forwarded in the call to ActivateSession. */
38092 UA_X509IdentityToken* x509token = (UA_X509IdentityToken*)
38093 req->userIdentityToken.content.decoded.data;
38094 resp->responseHeader.serviceResult =
38095 checkActivateSessionX509(server, session, sp: tokenSp,
38096 token: x509token, tokenSignature: &req->userTokenSignature);
38097 } else if(utp->tokenType == UA_USERTOKENTYPE_ISSUEDTOKEN) {
38098 /* IssuedTokens are encrypted */
38099 UA_IssuedIdentityToken *issuedToken = (UA_IssuedIdentityToken*)
38100 req->userIdentityToken.content.decoded.data;
38101 resp->responseHeader.serviceResult = decryptUserToken(
38102 server, session, channel, sp: tokenSp, encryptionAlgorithm: issuedToken->encryptionAlgorithm,
38103 encrypted: &issuedToken->tokenData);
38104 } /* else Anonymous */
38105 if(resp->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
38106 goto securityRejected;
38107#endif
38108
38109 /* Callback into userland access control */
38110 resp->responseHeader.serviceResult = server->config.accessControl.
38111 activateSession(server, &server->config.accessControl, ed,
38112 &channel->remoteCertificate, &session->sessionId,
38113 &req->userIdentityToken, &session->sessionHandle);
38114 if(resp->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
38115 UA_LOG_WARNING_SESSION(server->config.logging, session,
38116 "ActivateSession: The AccessControl "
38117 "plugin denied the activation with the StatusCode %s",
38118 UA_StatusCode_name(resp->responseHeader.serviceResult));
38119 goto securityRejected;
38120 }
38121
38122 /* Attach the session to the currently used channel if the session isn't
38123 * attached to a channel or if the session is activated on a different
38124 * channel than it is attached to. */
38125 if(!session->header.channel || session->header.channel != channel) {
38126 /* Attach the new SecureChannel, the old channel will be detached if present */
38127 UA_Session_attachToSecureChannel(session, channel);
38128 UA_LOG_INFO_SESSION(server->config.logging, session,
38129 "ActivateSession: Session attached to new channel");
38130 }
38131
38132 /* Generate a new session nonce for the next time ActivateSession is called */
38133 resp->responseHeader.serviceResult = UA_Session_generateNonce(session);
38134 resp->responseHeader.serviceResult |=
38135 UA_ByteString_copy(src: &session->serverNonce, dst: &resp->serverNonce);
38136 if(resp->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
38137 UA_Session_detachFromSecureChannel(session);
38138 UA_LOG_WARNING_SESSION(server->config.logging, session,
38139 "ActivateSession: Could not generate the server nonce");
38140 goto rejected;
38141 }
38142
38143 /* Set the Locale */
38144 if(req->localeIdsSize > 0) {
38145 /* Part 4, §5.6.3.2: This parameter only needs to be specified during
38146 * the first call to ActivateSession during a single application
38147 * Session. If it is not specified the Server shall keep using the
38148 * current localeIds for the Session. */
38149 resp->responseHeader.serviceResult |=
38150 UA_Array_copy(src: req->localeIds, size: req->localeIdsSize,
38151 dst: (void**)&tmpLocaleIds, type: &UA_TYPES[UA_TYPES_STRING]);
38152 if(resp->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
38153 UA_Session_detachFromSecureChannel(session);
38154 UA_LOG_WARNING_SESSION(server->config.logging, session,
38155 "ActivateSession: Could not store the Session LocaleIds");
38156 goto rejected;
38157 }
38158 UA_Array_delete(p: session->localeIds, size: session->localeIdsSize,
38159 type: &UA_TYPES[UA_TYPES_STRING]);
38160 session->localeIds = tmpLocaleIds;
38161 session->localeIdsSize = req->localeIdsSize;
38162 }
38163
38164 /* Update the Session lifetime */
38165 UA_Session_updateLifetime(session);
38166
38167 /* Activate the session */
38168 if(!session->activated) {
38169 session->activated = true;
38170 server->activeSessionCount++;
38171 server->serverDiagnosticsSummary.cumulatedSessionCount++;
38172 }
38173
38174 /* Store the ClientUserId. tokenType can be NULL for the anonymous user. */
38175 UA_String_clear(p: &session->clientUserIdOfSession);
38176 const UA_DataType *tokenType = req->userIdentityToken.content.decoded.type;
38177 if(tokenType == &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]) {
38178 const UA_UserNameIdentityToken *userToken = (UA_UserNameIdentityToken*)
38179 req->userIdentityToken.content.decoded.data;
38180 UA_String_copy(src: &userToken->userName, dst: &session->clientUserIdOfSession);
38181 } else if(tokenType == &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN]) {
38182 UA_X509IdentityToken* userCertToken = (UA_X509IdentityToken*)
38183 req->userIdentityToken.content.decoded.data;
38184 if(server->config.sessionPKI.getSubjectName)
38185 server->config.sessionPKI.
38186 getSubjectName(&session->clientUserIdOfSession,
38187 &userCertToken->certificateData);
38188 } else {
38189 /* TODO: Handle issued token */
38190 }
38191
38192#ifdef UA_ENABLE_DIAGNOSTICS
38193 /* Add the ClientUserId to the diagnostics history */
38194 UA_SessionSecurityDiagnosticsDataType *ssd = &session->securityDiagnostics;
38195 UA_StatusCode res =
38196 UA_Array_appendCopy(p: (void**)&ssd->clientUserIdHistory,
38197 size: &ssd->clientUserIdHistorySize,
38198 newElem: &ssd->clientUserIdOfSession,
38199 type: &UA_TYPES[UA_TYPES_STRING]);
38200 (void)res;
38201
38202 /* Store the auth mechanism */
38203 UA_String_clear(p: &ssd->authenticationMechanism);
38204 switch(utp->tokenType) {
38205 case UA_USERTOKENTYPE_ANONYMOUS:
38206 ssd->authenticationMechanism = UA_STRING_ALLOC("Anonymous"); break;
38207 case UA_USERTOKENTYPE_USERNAME:
38208 ssd->authenticationMechanism = UA_STRING_ALLOC("UserName"); break;
38209 case UA_USERTOKENTYPE_CERTIFICATE:
38210 ssd->authenticationMechanism = UA_STRING_ALLOC("Certificate"); break;
38211 case UA_USERTOKENTYPE_ISSUEDTOKEN:
38212 ssd->authenticationMechanism = UA_STRING_ALLOC("IssuedToken"); break;
38213 default: break;
38214 }
38215#endif
38216
38217 /* Log the user for which the Session was activated */
38218 UA_LOG_INFO_SESSION(server->config.logging, session,
38219 "ActivateSession: Session activated with ClientUserId \"%.*s\"",
38220 (int)session->clientUserIdOfSession.length,
38221 session->clientUserIdOfSession.data);
38222 return;
38223
38224securityRejected:
38225 server->serverDiagnosticsSummary.securityRejectedSessionCount++;
38226rejected:
38227 server->serverDiagnosticsSummary.rejectedSessionCount++;
38228}
38229
38230void
38231Service_CloseSession(UA_Server *server, UA_SecureChannel *channel,
38232 const UA_CloseSessionRequest *request,
38233 UA_CloseSessionResponse *response) {
38234 UA_LOCK_ASSERT(&server->serviceMutex, 1);
38235
38236 /* Part 4, 5.6.4: When the CloseSession Service is called before the Session
38237 * is successfully activated, the Server shall reject the request if the
38238 * SecureChannel is not the same as the one associated with the
38239 * CreateSession request.
38240 *
38241 * A non-activated Session is already bound to the SecureChannel that
38242 * created the Session. */
38243 UA_Session *session = NULL;
38244 response->responseHeader.serviceResult =
38245 getBoundSession(server, channel, token: &request->requestHeader.authenticationToken, session: &session);
38246 if(!session && response->responseHeader.serviceResult == UA_STATUSCODE_GOOD)
38247 response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
38248 if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
38249 UA_LOG_WARNING_CHANNEL(server->config.logging, channel,
38250 "CloseSession: No Session activated to the SecureChannel");
38251 return;
38252 }
38253
38254 UA_assert(session); /* Assured by the previous section */
38255 UA_LOG_INFO_SESSION(server->config.logging, session, "Closing the Session");
38256
38257#ifdef UA_ENABLE_SUBSCRIPTIONS
38258 /* If Subscriptions are not deleted, detach them from the Session */
38259 if(!request->deleteSubscriptions) {
38260 UA_Subscription *sub, *sub_tmp;
38261 TAILQ_FOREACH_SAFE(sub, &session->subscriptions, sessionListEntry, sub_tmp) {
38262 UA_LOG_INFO_SUBSCRIPTION(server->config.logging, sub,
38263 "Detaching the Subscription from the Session");
38264 UA_Session_detachSubscription(server, session, sub, true);
38265 }
38266 }
38267#endif
38268
38269 /* Remove the sesison */
38270 response->responseHeader.serviceResult =
38271 UA_Server_removeSessionByToken(server, token: &session->header.authenticationToken,
38272 shutdownReason: UA_SHUTDOWNREASON_CLOSE);
38273}
38274
38275void Service_Cancel(UA_Server *server, UA_Session *session,
38276 const UA_CancelRequest *request,
38277 UA_CancelResponse *response) {
38278 /* If multithreading is disabled, then there are no async services. If all
38279 * services are answered "right away", then there are no services that can
38280 * be cancelled. */
38281#if UA_MULTITHREADING >= 100
38282 response->cancelCount = UA_AsyncManager_cancel(server, session, request->requestHandle);
38283#endif
38284
38285 /* Publish requests for Subscriptions are stored separately */
38286#ifdef UA_ENABLE_SUBSCRIPTIONS
38287 UA_PublishResponseEntry *pre, *pre_tmp;
38288 UA_PublishResponseEntry *prev = NULL;
38289 SIMPLEQ_FOREACH_SAFE(pre, &session->responseQueue, listEntry, pre_tmp) {
38290 /* Skip entry and set as the previous entry that is kept in the list */
38291 if(pre->response.responseHeader.requestHandle != request->requestHandle) {
38292 prev = pre;
38293 continue;
38294 }
38295
38296 /* Dequeue */
38297 if(prev)
38298 SIMPLEQ_REMOVE_AFTER(&session->responseQueue, prev, listEntry);
38299 else
38300 SIMPLEQ_REMOVE_HEAD(&session->responseQueue, listEntry);
38301 session->responseQueueSize--;
38302
38303 /* Send response and clean up */
38304 response->responseHeader.serviceResult = UA_STATUSCODE_BADREQUESTCANCELLEDBYCLIENT;
38305 sendResponse(server, session, channel: session->header.channel, requestId: pre->requestId,
38306 response: (UA_Response *)response, responseType: &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]);
38307 UA_PublishResponse_clear(p: &pre->response);
38308 UA_free(ptr: pre);
38309
38310 /* Increase the CancelCount */
38311 response->cancelCount++;
38312 }
38313#endif
38314}
38315
38316/**** amalgamated original file "/src/server/ua_services_attribute.c" ****/
38317
38318/* This Source Code Form is subject to the terms of the Mozilla Public
38319 * License, v. 2.0. If a copy of the MPL was not distributed with this
38320 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
38321 *
38322 * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
38323 * Copyright 2015-2016 (c) Sten Grüner
38324 * Copyright 2014-2017 (c) Florian Palm
38325 * Copyright 2015 (c) Christian Fimmers
38326 * Copyright 2015-2016 (c) Chris Iatrou
38327 * Copyright 2015-2016 (c) Oleksiy Vasylyev
38328 * Copyright 2015 (c) wuyangtang
38329 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
38330 * Copyright 2016 (c) Lorenz Haas
38331 * Copyright 2017 (c) frax2222
38332 * Copyright 2017 (c) Thomas Bender
38333 * Copyright 2017 (c) Julian Grothoff
38334 * Copyright 2017-2020 (c) HMS Industrial Networks AB (Author: Jonas Green)
38335 * Copyright 2017 (c) Henrik Norrman
38336 * Copyright 2020 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati)
38337 */
38338
38339
38340#ifdef UA_ENABLE_HISTORIZING
38341#endif
38342
38343static const UA_NodeAttributesMask attr2mask[28] = {
38344 UA_NODEATTRIBUTESMASK_NODEID,
38345 UA_NODEATTRIBUTESMASK_NODECLASS,
38346 UA_NODEATTRIBUTESMASK_BROWSENAME,
38347 UA_NODEATTRIBUTESMASK_DISPLAYNAME,
38348 UA_NODEATTRIBUTESMASK_DESCRIPTION,
38349 UA_NODEATTRIBUTESMASK_WRITEMASK,
38350 UA_NODEATTRIBUTESMASK_USERWRITEMASK,
38351 UA_NODEATTRIBUTESMASK_ISABSTRACT,
38352 UA_NODEATTRIBUTESMASK_SYMMETRIC,
38353 UA_NODEATTRIBUTESMASK_INVERSENAME,
38354 UA_NODEATTRIBUTESMASK_CONTAINSNOLOOPS,
38355 UA_NODEATTRIBUTESMASK_EVENTNOTIFIER,
38356 UA_NODEATTRIBUTESMASK_VALUE,
38357 UA_NODEATTRIBUTESMASK_DATATYPE,
38358 UA_NODEATTRIBUTESMASK_VALUERANK,
38359 UA_NODEATTRIBUTESMASK_ARRAYDIMENSIONS,
38360 UA_NODEATTRIBUTESMASK_ACCESSLEVEL,
38361 UA_NODEATTRIBUTESMASK_USERACCESSLEVEL,
38362 UA_NODEATTRIBUTESMASK_MINIMUMSAMPLINGINTERVAL,
38363 UA_NODEATTRIBUTESMASK_HISTORIZING,
38364 UA_NODEATTRIBUTESMASK_EXECUTABLE,
38365 UA_NODEATTRIBUTESMASK_USEREXECUTABLE,
38366 UA_NODEATTRIBUTESMASK_DATATYPEDEFINITION,
38367 UA_NODEATTRIBUTESMASK_ROLEPERMISSIONS,
38368 UA_NODEATTRIBUTESMASK_ROLEPERMISSIONS,
38369 UA_NODEATTRIBUTESMASK_ACCESSRESTRICTIONS,
38370 UA_NODEATTRIBUTESMASK_ACCESSLEVEL
38371};
38372
38373static UA_UInt32
38374attributeId2AttributeMask(UA_AttributeId id) {
38375 if(UA_UNLIKELY(id > UA_ATTRIBUTEID_ACCESSLEVELEX))
38376 return UA_NODEATTRIBUTESMASK_NONE;
38377 return attr2mask[id];
38378}
38379
38380/******************/
38381/* Access Control */
38382/******************/
38383
38384/* Session for read operations can be NULL. For example for a MonitoredItem
38385 * where the underlying Subscription was detached during CloseSession. */
38386
38387static UA_UInt32
38388getUserWriteMask(UA_Server *server, const UA_Session *session,
38389 const UA_NodeHead *head) {
38390 UA_LOCK_ASSERT(&server->serviceMutex, 1);
38391 if(session == &server->adminSession)
38392 return 0xFFFFFFFF; /* the local admin user has all rights */
38393 return head->writeMask & server->config.accessControl.
38394 getUserRightsMask(server, &server->config.accessControl,
38395 session ? &session->sessionId : NULL,
38396 session ? session->sessionHandle : NULL,
38397 &head->nodeId, head->context);
38398}
38399
38400static UA_Byte
38401getAccessLevel(UA_Server *server, const UA_Session *session,
38402 const UA_VariableNode *node) {
38403 if(session == &server->adminSession)
38404 return 0xFF; /* the local admin user has all rights */
38405 return node->accessLevel;
38406}
38407
38408static UA_Byte
38409getUserAccessLevel(UA_Server *server, const UA_Session *session,
38410 const UA_VariableNode *node) {
38411 UA_LOCK_ASSERT(&server->serviceMutex, 1);
38412 if(session == &server->adminSession)
38413 return 0xFF; /* the local admin user has all rights */
38414 return node->accessLevel & server->config.accessControl.
38415 getUserAccessLevel(server, &server->config.accessControl,
38416 session ? &session->sessionId : NULL,
38417 session ? session->sessionHandle : NULL,
38418 &node->head.nodeId, node->head.context);
38419}
38420
38421static UA_Boolean
38422getUserExecutable(UA_Server *server, const UA_Session *session,
38423 const UA_MethodNode *node) {
38424 UA_LOCK_ASSERT(&server->serviceMutex, 1);
38425 if(session == &server->adminSession)
38426 return true; /* the local admin user has all rights */
38427 return node->executable & server->config.accessControl.
38428 getUserExecutable(server, &server->config.accessControl,
38429 session ? &session->sessionId : NULL,
38430 session ? session->sessionHandle : NULL,
38431 &node->head.nodeId, node->head.context);
38432}
38433
38434/****************/
38435/* Read Service */
38436/****************/
38437
38438static UA_StatusCode
38439readIsAbstractAttribute(const UA_Node *node, UA_Variant *v) {
38440 const UA_Boolean *isAbstract;
38441 switch(node->head.nodeClass) {
38442 case UA_NODECLASS_REFERENCETYPE:
38443 isAbstract = &node->referenceTypeNode.isAbstract;
38444 break;
38445 case UA_NODECLASS_OBJECTTYPE:
38446 isAbstract = &node->objectTypeNode.isAbstract;
38447 break;
38448 case UA_NODECLASS_VARIABLETYPE:
38449 isAbstract = &node->variableTypeNode.isAbstract;
38450 break;
38451 case UA_NODECLASS_DATATYPE:
38452 isAbstract = &node->dataTypeNode.isAbstract;
38453 break;
38454 default:
38455 return UA_STATUSCODE_BADATTRIBUTEIDINVALID;
38456 }
38457
38458 return UA_Variant_setScalarCopy(v, p: isAbstract, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
38459}
38460
38461static UA_StatusCode
38462readValueAttributeFromNode(UA_Server *server, UA_Session *session,
38463 const UA_VariableNode *vn, UA_DataValue *v,
38464 UA_NumericRange *rangeptr) {
38465 UA_LOCK_ASSERT(&server->serviceMutex, 1);
38466 /* Update the value by the user callback */
38467 if(vn->value.data.callback.onRead) {
38468 vn->value.data.callback.onRead(server,
38469 session ? &session->sessionId : NULL,
38470 session ? session->sessionHandle : NULL,
38471 &vn->head.nodeId, vn->head.context, rangeptr,
38472 &vn->value.data.value);
38473 vn = (const UA_VariableNode*)
38474 UA_NODESTORE_GET_SELECTIVE(server, &vn->head.nodeId,
38475 UA_NODEATTRIBUTESMASK_VALUE,
38476 UA_REFERENCETYPESET_NONE,
38477 UA_BROWSEDIRECTION_INVALID);
38478 if(!vn)
38479 return UA_STATUSCODE_BADNODEIDUNKNOWN;
38480 }
38481
38482 /* Set the result */
38483 UA_StatusCode retval;
38484 if(!rangeptr) {
38485 retval = UA_DataValue_copy(src: &vn->value.data.value, dst: v);
38486 } else {
38487 *v = vn->value.data.value; /* Copy timestamps */
38488 UA_Variant_init(p: &v->value);
38489 retval = UA_Variant_copyRange(src: &vn->value.data.value.value, dst: &v->value, range: *rangeptr);
38490 }
38491
38492 /* Clean up */
38493 if(vn->value.data.callback.onRead)
38494 UA_NODESTORE_RELEASE(server, (const UA_Node *)vn);
38495 return retval;
38496}
38497
38498static UA_StatusCode
38499readValueAttributeFromDataSource(UA_Server *server, UA_Session *session,
38500 const UA_VariableNode *vn, UA_DataValue *v,
38501 UA_TimestampsToReturn timestamps,
38502 UA_NumericRange *rangeptr) {
38503 UA_LOCK_ASSERT(&server->serviceMutex, 1);
38504 if(!vn->value.dataSource.read)
38505 return UA_STATUSCODE_BADINTERNALERROR;
38506 UA_Boolean sourceTimeStamp = (timestamps == UA_TIMESTAMPSTORETURN_SOURCE ||
38507 timestamps == UA_TIMESTAMPSTORETURN_BOTH);
38508 UA_DataValue v2;
38509 UA_DataValue_init(p: &v2);
38510 UA_StatusCode retval = vn->value.dataSource.
38511 read(server,
38512 session ? &session->sessionId : NULL,
38513 session ? session->sessionHandle : NULL,
38514 &vn->head.nodeId, vn->head.context,
38515 sourceTimeStamp, rangeptr, &v2);
38516 if(v2.hasValue && v2.value.storageType == UA_VARIANT_DATA_NODELETE) {
38517 retval = UA_DataValue_copy(src: &v2, dst: v);
38518 UA_DataValue_clear(p: &v2);
38519 } else {
38520 *v = v2;
38521 }
38522 return retval;
38523}
38524
38525static UA_StatusCode
38526readValueAttributeComplete(UA_Server *server, UA_Session *session,
38527 const UA_VariableNode *vn, UA_TimestampsToReturn timestamps,
38528 const UA_String *indexRange, UA_DataValue *v) {
38529 /* Compute the index range */
38530 UA_NumericRange range;
38531 UA_NumericRange *rangeptr = NULL;
38532 UA_StatusCode retval = UA_STATUSCODE_GOOD;
38533 if(indexRange && indexRange->length > 0) {
38534 retval = UA_NumericRange_parse(range: &range, str: *indexRange);
38535 if(retval != UA_STATUSCODE_GOOD)
38536 return retval;
38537 rangeptr = &range;
38538 }
38539
38540 switch(vn->valueBackend.backendType) {
38541 case UA_VALUEBACKENDTYPE_INTERNAL:
38542 retval = readValueAttributeFromNode(server, session, vn, v, rangeptr);
38543 //TODO change old structure to value backend
38544 break;
38545 case UA_VALUEBACKENDTYPE_DATA_SOURCE_CALLBACK:
38546 retval = readValueAttributeFromDataSource(server, session, vn, v,
38547 timestamps, rangeptr);
38548 //TODO change old structure to value backend
38549 break;
38550 case UA_VALUEBACKENDTYPE_EXTERNAL:
38551 if(!vn->valueBackend.backend.external.callback.notificationRead) {
38552 retval = UA_STATUSCODE_BADNOTREADABLE;
38553 break;
38554 }
38555 retval = vn->valueBackend.backend.external.callback.
38556 notificationRead(server,
38557 session ? &session->sessionId : NULL,
38558 session ? session->sessionHandle : NULL,
38559 &vn->head.nodeId, vn->head.context, rangeptr);
38560 if(retval != UA_STATUSCODE_GOOD)
38561 break;
38562
38563 /* Set the result */
38564 if(rangeptr)
38565 retval = UA_DataValue_copyVariantRange(
38566 src: *vn->valueBackend.backend.external.value, dst: v, range: *rangeptr);
38567 else
38568 retval = UA_DataValue_copy(src: *vn->valueBackend.backend.external.value, dst: v);
38569 break;
38570 case UA_VALUEBACKENDTYPE_NONE:
38571 /* Read the value */
38572 if(vn->valueSource == UA_VALUESOURCE_DATA)
38573 retval = readValueAttributeFromNode(server, session, vn, v, rangeptr);
38574 else
38575 retval = readValueAttributeFromDataSource(server, session, vn, v,
38576 timestamps, rangeptr);
38577 /* end lagacy */
38578 break;
38579 }
38580
38581 /* If not defined return a source timestamp of "now".
38582 * Static nodes always have the current time as source-time. */
38583 if(!v->hasSourceTimestamp) {
38584 v->sourceTimestamp = UA_DateTime_now();
38585 v->hasSourceTimestamp = true;
38586 }
38587
38588 /* Clean up */
38589 if(rangeptr)
38590 UA_free(ptr: range.dimensions);
38591 return retval;
38592}
38593
38594UA_StatusCode
38595readValueAttribute(UA_Server *server, UA_Session *session,
38596 const UA_VariableNode *vn, UA_DataValue *v) {
38597 return readValueAttributeComplete(server, session, vn,
38598 timestamps: UA_TIMESTAMPSTORETURN_NEITHER, NULL, v);
38599}
38600
38601static const UA_String binEncoding = {sizeof("Default Binary")-1, (UA_Byte*)"Default Binary"};
38602static const UA_String xmlEncoding = {sizeof("Default XML")-1, (UA_Byte*)"Default XML"};
38603static const UA_String jsonEncoding = {sizeof("Default JSON")-1, (UA_Byte*)"Default JSON"};
38604
38605#define CHECK_NODECLASS(CLASS) \
38606 if(!(node->head.nodeClass & (CLASS))) { \
38607 retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID; \
38608 break; \
38609 }
38610
38611#ifdef UA_ENABLE_TYPEDESCRIPTION
38612static const UA_DataType *
38613findDataType(const UA_Node *node, const UA_DataTypeArray *customTypes) {
38614 for(size_t i = 0; i < UA_TYPES_COUNT; ++i) {
38615 if(UA_NodeId_equal(p1: &UA_TYPES[i].typeId, p2: &node->head.nodeId)) {
38616 return &UA_TYPES[i];
38617 }
38618 }
38619
38620 // lookup custom type
38621 while(customTypes) {
38622 for(size_t i = 0; i < customTypes->typesSize; ++i) {
38623 if(UA_NodeId_equal(p1: &customTypes->types[i].typeId, p2: &node->head.nodeId))
38624 return &customTypes->types[i];
38625 }
38626 customTypes = customTypes->next;
38627 }
38628 return NULL;
38629}
38630
38631static UA_StatusCode
38632getStructureDefinition(const UA_DataType *type, UA_StructureDefinition *def) {
38633 UA_StatusCode retval =
38634 UA_NodeId_copy(src: &type->binaryEncodingId, dst: &def->defaultEncodingId);
38635 if(retval != UA_STATUSCODE_GOOD)
38636 return retval;
38637 switch(type->typeKind) {
38638 case UA_DATATYPEKIND_STRUCTURE:
38639 def->structureType = UA_STRUCTURETYPE_STRUCTURE;
38640 def->baseDataType = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_STRUCTURE);
38641 break;
38642 case UA_DATATYPEKIND_OPTSTRUCT:
38643 def->structureType = UA_STRUCTURETYPE_STRUCTUREWITHOPTIONALFIELDS;
38644 def->baseDataType = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_STRUCTURE);
38645 break;
38646 case UA_DATATYPEKIND_UNION:
38647 def->structureType = UA_STRUCTURETYPE_UNION;
38648 def->baseDataType = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_UNION);
38649 break;
38650 default:
38651 return UA_STATUSCODE_BADENCODINGERROR;
38652 }
38653 def->fieldsSize = type->membersSize;
38654 def->fields = (UA_StructureField *)
38655 UA_calloc(nmemb: def->fieldsSize, size: sizeof(UA_StructureField));
38656 if(!def->fields) {
38657 UA_NodeId_clear(p: &def->defaultEncodingId);
38658 return UA_STATUSCODE_BADOUTOFMEMORY;
38659 }
38660
38661 for(size_t cnt = 0; cnt < def->fieldsSize; cnt++) {
38662 const UA_DataTypeMember *m = &type->members[cnt];
38663 def->fields[cnt].valueRank = (m->isArray) ? UA_VALUERANK_ONE_DIMENSION : UA_VALUERANK_SCALAR;
38664 def->fields[cnt].arrayDimensions = NULL;
38665 def->fields[cnt].arrayDimensionsSize = 0;
38666 def->fields[cnt].name = UA_STRING(chars: (char *)(uintptr_t)m->memberName);
38667 def->fields[cnt].description.locale = UA_STRING_NULL;
38668 def->fields[cnt].description.text = UA_STRING_NULL;
38669 def->fields[cnt].dataType = m->memberType->typeId;
38670 def->fields[cnt].maxStringLength = 0;
38671 def->fields[cnt].isOptional = m->isOptional;
38672 }
38673 return UA_STATUSCODE_GOOD;
38674}
38675#endif
38676
38677/* Returns a datavalue that may point into the node via the
38678 * UA_VARIANT_DATA_NODELETE tag. Don't access the returned DataValue once the
38679 * node has been released! */
38680void
38681ReadWithNode(const UA_Node *node, UA_Server *server, UA_Session *session,
38682 UA_TimestampsToReturn timestampsToReturn,
38683 const UA_ReadValueId *id, UA_DataValue *v) {
38684 UA_LOG_NODEID_TRACE(&node->head.nodeId,
38685 UA_LOG_TRACE_SESSION(server->config.logging, session,
38686 "Read attribute %"PRIi32 " of Node %.*s",
38687 id->attributeId, (int)nodeIdStr.length,
38688 nodeIdStr.data));
38689
38690 /* Only Binary Encoding is supported */
38691 if(id->dataEncoding.name.length > 0 &&
38692 !UA_String_equal(p1: &binEncoding, p2: &id->dataEncoding.name)) {
38693 if(UA_String_equal(p1: &xmlEncoding, p2: &id->dataEncoding.name) ||
38694 UA_String_equal(p1: &jsonEncoding, p2: &id->dataEncoding.name))
38695 v->status = UA_STATUSCODE_BADDATAENCODINGUNSUPPORTED;
38696 else
38697 v->status = UA_STATUSCODE_BADDATAENCODINGINVALID;
38698 v->hasStatus = true;
38699 return;
38700 }
38701
38702 /* Index range for an attribute other than value */
38703 if(id->indexRange.length > 0 && id->attributeId != UA_ATTRIBUTEID_VALUE) {
38704 v->hasStatus = true;
38705 v->status = UA_STATUSCODE_BADINDEXRANGENODATA;
38706 return;
38707 }
38708
38709 /* Read the attribute */
38710 UA_StatusCode retval = UA_STATUSCODE_GOOD;
38711 switch(id->attributeId) {
38712 case UA_ATTRIBUTEID_NODEID:
38713 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->head.nodeId,
38714 type: &UA_TYPES[UA_TYPES_NODEID]);
38715 break;
38716 case UA_ATTRIBUTEID_NODECLASS:
38717 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->head.nodeClass,
38718 type: &UA_TYPES[UA_TYPES_NODECLASS]);
38719 break;
38720 case UA_ATTRIBUTEID_BROWSENAME:
38721 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->head.browseName,
38722 type: &UA_TYPES[UA_TYPES_QUALIFIEDNAME]);
38723 break;
38724 case UA_ATTRIBUTEID_DISPLAYNAME: {
38725 UA_LocalizedText lt = UA_Session_getNodeDisplayName(session, head: &node->head);
38726 retval = UA_Variant_setScalarCopy(v: &v->value, p: &lt,
38727 type: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
38728 break;
38729 }
38730 case UA_ATTRIBUTEID_DESCRIPTION: {
38731 UA_LocalizedText lt = UA_Session_getNodeDescription(session, head: &node->head);
38732 retval = UA_Variant_setScalarCopy(v: &v->value, p: &lt,
38733 type: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
38734 break;
38735 }
38736 case UA_ATTRIBUTEID_WRITEMASK:
38737 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->head.writeMask,
38738 type: &UA_TYPES[UA_TYPES_UINT32]);
38739 break;
38740 case UA_ATTRIBUTEID_USERWRITEMASK: {
38741 UA_UInt32 userWriteMask = getUserWriteMask(server, session, head: &node->head);
38742 retval = UA_Variant_setScalarCopy(v: &v->value, p: &userWriteMask,
38743 type: &UA_TYPES[UA_TYPES_UINT32]);
38744 break; }
38745 case UA_ATTRIBUTEID_ISABSTRACT:
38746 retval = readIsAbstractAttribute(node, v: &v->value);
38747 break;
38748 case UA_ATTRIBUTEID_SYMMETRIC:
38749 CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
38750 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->referenceTypeNode.symmetric,
38751 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
38752 break;
38753 case UA_ATTRIBUTEID_INVERSENAME:
38754 CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE);
38755 if(node->referenceTypeNode.symmetric) {
38756 /* Symmetric reference types don't have an inverse name */
38757 retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
38758 break;
38759 }
38760 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->referenceTypeNode.inverseName,
38761 type: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
38762 break;
38763 case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
38764 CHECK_NODECLASS(UA_NODECLASS_VIEW);
38765 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->viewNode.containsNoLoops,
38766 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
38767 break;
38768 case UA_ATTRIBUTEID_EVENTNOTIFIER:
38769 CHECK_NODECLASS(UA_NODECLASS_VIEW | UA_NODECLASS_OBJECT);
38770 if(node->head.nodeClass == UA_NODECLASS_VIEW) {
38771 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->viewNode.eventNotifier,
38772 type: &UA_TYPES[UA_TYPES_BYTE]);
38773 } else {
38774 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->objectNode.eventNotifier,
38775 type: &UA_TYPES[UA_TYPES_BYTE]);
38776 }
38777 break;
38778 case UA_ATTRIBUTEID_VALUE: {
38779 CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
38780 /* VariableTypes don't have the AccessLevel concept. Always allow
38781 * reading the value. */
38782 if(node->head.nodeClass == UA_NODECLASS_VARIABLE) {
38783 /* The access to a value variable is granted via the AccessLevel
38784 * and UserAccessLevel attributes */
38785 UA_Byte accessLevel = getAccessLevel(server, session, node: &node->variableNode);
38786 if(!(accessLevel & (UA_ACCESSLEVELMASK_READ))) {
38787 retval = UA_STATUSCODE_BADNOTREADABLE;
38788 break;
38789 }
38790 accessLevel = getUserAccessLevel(server, session, node: &node->variableNode);
38791 if(!(accessLevel & (UA_ACCESSLEVELMASK_READ))) {
38792 retval = UA_STATUSCODE_BADUSERACCESSDENIED;
38793 break;
38794 }
38795 }
38796 retval = readValueAttributeComplete(server, session, vn: &node->variableNode,
38797 timestamps: timestampsToReturn, indexRange: &id->indexRange, v);
38798 break;
38799 }
38800 case UA_ATTRIBUTEID_DATATYPE:
38801 CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
38802 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->variableTypeNode.dataType,
38803 type: &UA_TYPES[UA_TYPES_NODEID]);
38804 break;
38805 case UA_ATTRIBUTEID_VALUERANK:
38806 CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
38807 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->variableTypeNode.valueRank,
38808 type: &UA_TYPES[UA_TYPES_INT32]);
38809 break;
38810 case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
38811 CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
38812 retval = UA_Variant_setArrayCopy(v: &v->value, array: node->variableTypeNode.arrayDimensions,
38813 arraySize: node->variableTypeNode.arrayDimensionsSize,
38814 type: &UA_TYPES[UA_TYPES_UINT32]);
38815 break;
38816 case UA_ATTRIBUTEID_ACCESSLEVEL:
38817 CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
38818 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->variableNode.accessLevel,
38819 type: &UA_TYPES[UA_TYPES_BYTE]);
38820 break;
38821 case UA_ATTRIBUTEID_ACCESSLEVELEX:
38822 CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
38823 /* The normal AccessLevelEx contains the lowest 8 bits from the normal AccessLevel.
38824 * In our case, all other bits are zero. */
38825 const UA_Byte accessLevel = *((const UA_Byte*)(&node->variableNode.accessLevel));
38826 UA_UInt32 accessLevelEx = accessLevel & 0xFF;
38827 retval = UA_Variant_setScalarCopy(v: &v->value, p: &accessLevelEx,
38828 type: &UA_TYPES[UA_TYPES_UINT32]);
38829
38830 break;
38831 case UA_ATTRIBUTEID_USERACCESSLEVEL: {
38832 CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
38833 UA_Byte userAccessLevel = getUserAccessLevel(server, session, node: &node->variableNode);
38834 retval = UA_Variant_setScalarCopy(v: &v->value, p: &userAccessLevel,
38835 type: &UA_TYPES[UA_TYPES_BYTE]);
38836 break; }
38837 case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
38838 CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
38839 retval = UA_Variant_setScalarCopy(v: &v->value,
38840 p: &node->variableNode.minimumSamplingInterval,
38841 type: &UA_TYPES[UA_TYPES_DOUBLE]);
38842 break;
38843 case UA_ATTRIBUTEID_HISTORIZING:
38844 CHECK_NODECLASS(UA_NODECLASS_VARIABLE);
38845 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->variableNode.historizing,
38846 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
38847 break;
38848 case UA_ATTRIBUTEID_EXECUTABLE:
38849 CHECK_NODECLASS(UA_NODECLASS_METHOD);
38850 retval = UA_Variant_setScalarCopy(v: &v->value, p: &node->methodNode.executable,
38851 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
38852 break;
38853 case UA_ATTRIBUTEID_USEREXECUTABLE: {
38854 CHECK_NODECLASS(UA_NODECLASS_METHOD);
38855 UA_Boolean userExecutable =
38856 getUserExecutable(server, session, node: &node->methodNode);
38857 retval = UA_Variant_setScalarCopy(v: &v->value, p: &userExecutable,
38858 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
38859 break; }
38860 case UA_ATTRIBUTEID_DATATYPEDEFINITION: {
38861 CHECK_NODECLASS(UA_NODECLASS_DATATYPE);
38862
38863#ifdef UA_ENABLE_TYPEDESCRIPTION
38864 const UA_DataType *type =
38865 findDataType(node, customTypes: server->config.customDataTypes);
38866 if(!type) {
38867 retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
38868 break;
38869 }
38870
38871 if(UA_DATATYPEKIND_STRUCTURE == type->typeKind ||
38872 UA_DATATYPEKIND_OPTSTRUCT == type->typeKind ||
38873 UA_DATATYPEKIND_UNION == type->typeKind) {
38874 UA_StructureDefinition def;
38875 retval = getStructureDefinition(type, def: &def);
38876 if(UA_STATUSCODE_GOOD!=retval)
38877 break;
38878 retval = UA_Variant_setScalarCopy(v: &v->value, p: &def,
38879 type: &UA_TYPES[UA_TYPES_STRUCTUREDEFINITION]);
38880 UA_free(ptr: def.fields);
38881 break;
38882 }
38883#endif
38884 retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
38885 break; }
38886
38887 case UA_ATTRIBUTEID_ROLEPERMISSIONS:
38888 case UA_ATTRIBUTEID_USERROLEPERMISSIONS:
38889 case UA_ATTRIBUTEID_ACCESSRESTRICTIONS:
38890 /* TODO: Add support for the attributes from the 1.04 spec */
38891 retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
38892 break;
38893
38894 default:
38895 retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
38896 }
38897
38898 /* Reading has failed? */
38899 if(retval == UA_STATUSCODE_GOOD) {
38900 v->hasValue = true;
38901 } else {
38902 v->hasStatus = true;
38903 v->status = retval;
38904 }
38905
38906 /* Always use the current time as the server-timestamp */
38907 if(timestampsToReturn == UA_TIMESTAMPSTORETURN_SERVER ||
38908 timestampsToReturn == UA_TIMESTAMPSTORETURN_BOTH) {
38909 v->serverTimestamp = UA_DateTime_now();
38910 v->hasServerTimestamp = true;
38911 v->hasServerPicoseconds = false;
38912 } else {
38913 v->hasServerTimestamp = false;
38914 v->hasServerPicoseconds = false;
38915 }
38916
38917 /* Don't "invent" source timestamps. But remove them when not required. */
38918 if(timestampsToReturn == UA_TIMESTAMPSTORETURN_SERVER ||
38919 timestampsToReturn == UA_TIMESTAMPSTORETURN_NEITHER) {
38920 v->hasSourceTimestamp = false;
38921 v->hasSourcePicoseconds = false;
38922 }
38923}
38924
38925void
38926Operation_Read(UA_Server *server, UA_Session *session, UA_TimestampsToReturn *ttr,
38927 const UA_ReadValueId *rvi, UA_DataValue *dv) {
38928 /* Get the node (with only the selected attribute if the NodeStore supports that) */
38929 const UA_Node *node =
38930 UA_NODESTORE_GET_SELECTIVE(server, &rvi->nodeId,
38931 attributeId2AttributeMask((UA_AttributeId)rvi->attributeId),
38932 UA_REFERENCETYPESET_NONE,
38933 UA_BROWSEDIRECTION_INVALID);
38934 if(!node) {
38935 dv->hasStatus = true;
38936 dv->status = UA_STATUSCODE_BADNODEIDUNKNOWN;
38937 return;
38938 }
38939
38940 /* Perform the read operation */
38941 ReadWithNode(node, server, session, timestampsToReturn: *ttr, id: rvi, v: dv);
38942 UA_NODESTORE_RELEASE(server, node);
38943}
38944
38945void
38946Service_Read(UA_Server *server, UA_Session *session,
38947 const UA_ReadRequest *request, UA_ReadResponse *response) {
38948 UA_LOG_DEBUG_SESSION(server->config.logging, session, "Processing ReadRequest");
38949 UA_LOCK_ASSERT(&server->serviceMutex, 1);
38950
38951 /* Check if the timestampstoreturn is valid */
38952 if(request->timestampsToReturn > UA_TIMESTAMPSTORETURN_NEITHER) {
38953 response->responseHeader.serviceResult = UA_STATUSCODE_BADTIMESTAMPSTORETURNINVALID;
38954 return;
38955 }
38956
38957 /* Check if maxAge is valid */
38958 if(request->maxAge < 0) {
38959 response->responseHeader.serviceResult = UA_STATUSCODE_BADMAXAGEINVALID;
38960 return;
38961 }
38962
38963 /* Check if there are too many operations */
38964 if(server->config.maxNodesPerRead != 0 &&
38965 request->nodesToReadSize > server->config.maxNodesPerRead) {
38966 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
38967 return;
38968 }
38969
38970 UA_LOCK_ASSERT(&server->serviceMutex, 1);
38971
38972 response->responseHeader.serviceResult =
38973 UA_Server_processServiceOperations(server, session,
38974 operationCallback: (UA_ServiceOperation)Operation_Read,
38975 context: &request->timestampsToReturn,
38976 requestOperations: &request->nodesToReadSize,
38977 requestOperationsType: &UA_TYPES[UA_TYPES_READVALUEID],
38978 responseOperations: &response->resultsSize,
38979 responseOperationsType: &UA_TYPES[UA_TYPES_DATAVALUE]);
38980}
38981
38982UA_DataValue
38983readWithSession(UA_Server *server, UA_Session *session,
38984 const UA_ReadValueId *item,
38985 UA_TimestampsToReturn timestampsToReturn) {
38986 UA_LOCK_ASSERT(&server->serviceMutex, 1);
38987
38988 UA_DataValue dv;
38989 UA_DataValue_init(p: &dv);
38990 Operation_Read(server, session, ttr: &timestampsToReturn, rvi: item, dv: &dv);
38991 return dv;
38992}
38993
38994UA_StatusCode
38995readWithReadValue(UA_Server *server, const UA_NodeId *nodeId,
38996 const UA_AttributeId attributeId, void *v) {
38997 UA_LOCK_ASSERT(&server->serviceMutex, 1);
38998
38999 /* Call the read service */
39000 UA_ReadValueId item;
39001 UA_ReadValueId_init(p: &item);
39002 item.nodeId = *nodeId;
39003 item.attributeId = attributeId;
39004 UA_DataValue dv = readWithSession(server, session: &server->adminSession,
39005 item: &item, timestampsToReturn: UA_TIMESTAMPSTORETURN_NEITHER);
39006
39007 /* Check the return value */
39008 UA_StatusCode retval = UA_STATUSCODE_GOOD;
39009 if(dv.hasStatus)
39010 retval = dv.status;
39011 else if(!dv.hasValue)
39012 retval = UA_STATUSCODE_BADUNEXPECTEDERROR;
39013 if(retval != UA_STATUSCODE_GOOD) {
39014 UA_DataValue_clear(p: &dv);
39015 return retval;
39016 }
39017
39018 if(attributeId == UA_ATTRIBUTEID_VALUE ||
39019 attributeId == UA_ATTRIBUTEID_ARRAYDIMENSIONS) {
39020 /* Return the entire variant */
39021 memcpy(dest: v, src: &dv.value, n: sizeof(UA_Variant));
39022 } else {
39023 /* Return the variant content only */
39024 memcpy(dest: v, src: dv.value.data, n: dv.value.type->memSize);
39025 UA_free(ptr: dv.value.data);
39026 }
39027 return retval;
39028}
39029
39030/* Exposes the Read service to local users */
39031UA_DataValue
39032UA_Server_read(UA_Server *server, const UA_ReadValueId *item,
39033 UA_TimestampsToReturn timestamps) {
39034 lockServer(server);
39035 UA_DataValue dv = readWithSession(server, session: &server->adminSession, item, timestampsToReturn: timestamps);
39036 unlockServer(server);
39037 return dv;
39038}
39039
39040/* Used in inline functions exposing the Read service with more syntactic sugar
39041 * for individual attributes */
39042UA_StatusCode
39043__UA_Server_read(UA_Server *server, const UA_NodeId *nodeId,
39044 const UA_AttributeId attributeId, void *v) {
39045 lockServer(server);
39046 UA_StatusCode retval = readWithReadValue(server, nodeId, attributeId, v);
39047 unlockServer(server);
39048 return retval;
39049}
39050
39051UA_StatusCode
39052readObjectProperty(UA_Server *server, const UA_NodeId objectId,
39053 const UA_QualifiedName propertyName,
39054 UA_Variant *value) {
39055 UA_LOCK_ASSERT(&server->serviceMutex, 1);
39056
39057 /* Create a BrowsePath to get the target NodeId */
39058 UA_RelativePathElement rpe;
39059 UA_RelativePathElement_init(p: &rpe);
39060 rpe.referenceTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY);
39061 rpe.isInverse = false;
39062 rpe.includeSubtypes = false;
39063 rpe.targetName = propertyName;
39064
39065 UA_BrowsePath bp;
39066 UA_BrowsePath_init(p: &bp);
39067 bp.startingNode = objectId;
39068 bp.relativePath.elementsSize = 1;
39069 bp.relativePath.elements = &rpe;
39070
39071 UA_StatusCode retval;
39072 UA_BrowsePathResult bpr = translateBrowsePathToNodeIds(server, browsePath: &bp);
39073 if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) {
39074 retval = bpr.statusCode;
39075 UA_BrowsePathResult_clear(p: &bpr);
39076 return retval;
39077 }
39078
39079 /* Use the first result from the BrowsePath */
39080 retval = readWithReadValue(server, nodeId: &bpr.targets[0].targetId.nodeId,
39081 attributeId: UA_ATTRIBUTEID_VALUE, v: value);
39082
39083 UA_BrowsePathResult_clear(p: &bpr);
39084 return retval;
39085}
39086
39087
39088UA_StatusCode
39089UA_Server_readObjectProperty(UA_Server *server, const UA_NodeId objectId,
39090 const UA_QualifiedName propertyName,
39091 UA_Variant *value) {
39092 lockServer(server);
39093 UA_StatusCode retval = readObjectProperty(server, objectId, propertyName, value);
39094 unlockServer(server);
39095 return retval;
39096}
39097
39098/*****************/
39099/* Type Checking */
39100/*****************/
39101
39102UA_Boolean
39103compatibleValueDataType(UA_Server *server, const UA_DataType *dataType,
39104 const UA_NodeId *constraintDataType) {
39105 if(compatibleDataTypes(server, dataType: &dataType->typeId, constraintDataType))
39106 return true;
39107
39108 /* For actual values, the constraint DataType may be a subtype of the
39109 * DataType of the value -- subtyping in the wrong direction. E.g. UtcTime
39110 * is a subtype of DateTime. But we allow it to be encoded as a DateTime
39111 * value when transferred over the wire.
39112 *
39113 * We do not allow "subtyping in the "wrong direction" if the received type
39114 * is abstract. For example, ExtensionObjects (== "Structure" in the type
39115 * hierarchy) is an abstract type. But ExtensionObject could still be
39116 * transported over the network. */
39117 UA_Boolean abstract = false;
39118 UA_StatusCode res = readWithReadValue(server, nodeId: &dataType->typeId,
39119 attributeId: UA_ATTRIBUTEID_ISABSTRACT, v: &abstract);
39120 if(res != UA_STATUSCODE_GOOD || abstract)
39121 return false;
39122
39123 if(isNodeInTree_singleRef(server, leafNode: constraintDataType, nodeToFind: &dataType->typeId,
39124 UA_REFERENCETYPEINDEX_HASSUBTYPE))
39125 return true;
39126
39127 return false;
39128}
39129
39130UA_Boolean
39131compatibleDataTypes(UA_Server *server, const UA_NodeId *dataType,
39132 const UA_NodeId *constraintDataType) {
39133 /* Do not allow empty datatypes */
39134 if(UA_NodeId_isNull(p: dataType))
39135 return false;
39136
39137 /* No constraint or Variant / BaseDataType which allows any content */
39138 if(UA_NodeId_isNull(p: constraintDataType) ||
39139 UA_NodeId_equal(p1: constraintDataType, p2: &UA_TYPES[UA_TYPES_VARIANT].typeId))
39140 return true;
39141
39142 /* Same datatypes */
39143 if(UA_NodeId_equal(p1: dataType, p2: constraintDataType))
39144 return true;
39145
39146 /* Is the DataType a subtype of the constraint type? */
39147 if(isNodeInTree_singleRef(server, leafNode: dataType, nodeToFind: constraintDataType,
39148 UA_REFERENCETYPEINDEX_HASSUBTYPE))
39149 return true;
39150
39151 return false;
39152}
39153
39154/* Test whether a ValueRank and the given arraydimensions are compatible.
39155 *
39156 * 5.6.2 Variable NodeClass: If the maximum is unknown the value shall be 0. The
39157 * number of elements shall be equal to the value of the ValueRank Attribute.
39158 * This Attribute shall be null if ValueRank <= 0. */
39159UA_Boolean
39160compatibleValueRankArrayDimensions(UA_Server *server, UA_Session *session,
39161 UA_Int32 valueRank, size_t arrayDimensionsSize) {
39162 /* ValueRank invalid */
39163 if(valueRank < UA_VALUERANK_SCALAR_OR_ONE_DIMENSION) {
39164 UA_LOG_INFO_SESSION(server->config.logging, session,
39165 "The ValueRank is invalid (< -3)");
39166 return false;
39167 }
39168
39169 /* case -3, UA_VALUERANK_SCALAR_OR_ONE_DIMENSION: the value can be a scalar
39170 * or a one dimensional array
39171 * case -2, UA_VALUERANK_ANY: the value can be a scalar or an array with any
39172 * number of dimensions
39173 * case -1, UA_VALUERANK_SCALAR: the value is a scalar
39174 * case 0, UA_VALUERANK_ONE_OR_MORE_DIMENSIONS: the value is an array with
39175 * one or more dimensions */
39176 if(valueRank <= UA_VALUERANK_ONE_OR_MORE_DIMENSIONS) {
39177 if(arrayDimensionsSize > 0) {
39178 UA_LOG_INFO_SESSION(server->config.logging, session,
39179 "No ArrayDimensions can be defined for a ValueRank <= 0");
39180 return false;
39181 }
39182 return true;
39183 }
39184
39185 /* case >= 1, UA_VALUERANK_ONE_DIMENSION: the value is an array with the
39186 specified number of dimensions */
39187 if(arrayDimensionsSize != (size_t)valueRank) {
39188 UA_LOG_INFO_SESSION(server->config.logging, session,
39189 "The number of ArrayDimensions is not equal to "
39190 "the (positive) ValueRank");
39191 return false;
39192 }
39193 return true;
39194}
39195
39196UA_Boolean
39197compatibleValueRanks(UA_Int32 valueRank, UA_Int32 constraintValueRank) {
39198 /* Check if the valuerank of the variabletype allows the change. */
39199 switch(constraintValueRank) {
39200 case UA_VALUERANK_SCALAR_OR_ONE_DIMENSION: /* the value can be a scalar or a
39201 one dimensional array */
39202 if(valueRank != UA_VALUERANK_SCALAR && valueRank != UA_VALUERANK_ONE_DIMENSION)
39203 return false;
39204 break;
39205 case UA_VALUERANK_ANY: /* the value can be a scalar or an array with any
39206 number of dimensions */
39207 break;
39208 case UA_VALUERANK_SCALAR: /* the value is a scalar */
39209 if(valueRank != UA_VALUERANK_SCALAR)
39210 return false;
39211 break;
39212 case UA_VALUERANK_ONE_OR_MORE_DIMENSIONS: /* the value is an array with one
39213 or more dimensions */
39214 if(valueRank < (UA_Int32) UA_VALUERANK_ONE_OR_MORE_DIMENSIONS)
39215 return false;
39216 break;
39217 default: /* >= 1: the value is an array with the specified number of
39218 dimensions */
39219 if(valueRank != constraintValueRank)
39220 return false;
39221 break;
39222 }
39223 return true;
39224}
39225
39226/* Check if the ValueRank allows for the value dimension. This is more
39227 * permissive than checking for the ArrayDimensions attribute. Because the value
39228 * can have dimensions if the ValueRank < 0 */
39229static UA_Boolean
39230compatibleValueRankValue(UA_Int32 valueRank, const UA_Variant *value) {
39231 /* Invalid ValueRank */
39232 if(valueRank < UA_VALUERANK_SCALAR_OR_ONE_DIMENSION)
39233 return false;
39234
39235 /* Empty arrays (-1) always match */
39236 if(!value->data)
39237 return true;
39238
39239 size_t arrayDims = value->arrayDimensionsSize;
39240 if(arrayDims == 0 && !UA_Variant_isScalar(v: value))
39241 arrayDims = 1; /* array but no arraydimensions -> implicit array dimension 1 */
39242
39243 /* We cannot simply use compatibleValueRankArrayDimensions since we can have
39244 * defined ArrayDimensions for the value if the ValueRank is -2 */
39245 switch(valueRank) {
39246 case UA_VALUERANK_SCALAR_OR_ONE_DIMENSION: /* The value can be a scalar or a
39247 one dimensional array */
39248 return (arrayDims <= 1);
39249 case UA_VALUERANK_ANY: /* The value can be a scalar or an array with any
39250 number of dimensions */
39251 return true;
39252 case UA_VALUERANK_SCALAR: /* The value is a scalar */
39253 return (arrayDims == 0);
39254 case UA_VALUERANK_ONE_OR_MORE_DIMENSIONS:
39255 return (arrayDims >= 1);
39256 default:
39257 break;
39258 }
39259
39260 UA_assert(valueRank >= UA_VALUERANK_ONE_OR_MORE_DIMENSIONS);
39261
39262 /* case 0: the value is an array with one or more dimensions */
39263 return (arrayDims == (UA_UInt32)valueRank);
39264}
39265
39266UA_Boolean
39267compatibleArrayDimensions(size_t constraintArrayDimensionsSize,
39268 const UA_UInt32 *constraintArrayDimensions,
39269 size_t testArrayDimensionsSize,
39270 const UA_UInt32 *testArrayDimensions) {
39271 /* No array dimensions defined -> everything is permitted if the value rank fits */
39272 if(constraintArrayDimensionsSize == 0)
39273 return true;
39274
39275 /* Dimension count must match */
39276 if(testArrayDimensionsSize != constraintArrayDimensionsSize)
39277 return false;
39278
39279 /* Dimension lengths must not be larger than the constraint. Zero in the
39280 * constraint indicates a wildcard. */
39281 for(size_t i = 0; i < constraintArrayDimensionsSize; ++i) {
39282 if(constraintArrayDimensions[i] < testArrayDimensions[i] &&
39283 constraintArrayDimensions[i] != 0)
39284 return false;
39285 }
39286 return true;
39287}
39288
39289UA_Boolean
39290compatibleValueArrayDimensions(const UA_Variant *value, size_t targetArrayDimensionsSize,
39291 const UA_UInt32 *targetArrayDimensions) {
39292 size_t valueArrayDimensionsSize = value->arrayDimensionsSize;
39293 UA_UInt32 const *valueArrayDimensions = value->arrayDimensions;
39294 UA_UInt32 tempArrayDimensions;
39295 if(!valueArrayDimensions && !UA_Variant_isScalar(v: value)) {
39296 /* An empty array implicitly has array dimensions [0,0,...] with the
39297 * correct number of dimensions. So it always matches. */
39298 if(value->arrayLength == 0)
39299 return true;
39300
39301 /* Arrays with content and without array dimensions have one implicit dimension */
39302 valueArrayDimensionsSize = 1;
39303 tempArrayDimensions = (UA_UInt32)value->arrayLength;
39304 valueArrayDimensions = &tempArrayDimensions;
39305 }
39306 UA_assert(valueArrayDimensionsSize == 0 || valueArrayDimensions != NULL);
39307 return compatibleArrayDimensions(constraintArrayDimensionsSize: targetArrayDimensionsSize, constraintArrayDimensions: targetArrayDimensions,
39308 testArrayDimensionsSize: valueArrayDimensionsSize, testArrayDimensions: valueArrayDimensions);
39309}
39310
39311const char *reason_EmptyType = "Empty value only allowed for BaseDataType";
39312const char *reason_ValueDataType = "DataType of the value is incompatible";
39313const char *reason_ValueArrayDimensions = "ArrayDimensions of the value are incompatible";
39314const char *reason_ValueValueRank = "ValueRank of the value is incompatible";
39315
39316UA_Boolean
39317compatibleValue(UA_Server *server, UA_Session *session, const UA_NodeId *targetDataTypeId,
39318 UA_Int32 targetValueRank, size_t targetArrayDimensionsSize,
39319 const UA_UInt32 *targetArrayDimensions, const UA_Variant *value,
39320 const UA_NumericRange *range, const char **reason) {
39321 /* Empty value */
39322 if(UA_Variant_isEmpty(v: value)) {
39323 /* Empty value is allowed for BaseDataType */
39324 if(UA_NodeId_equal(p1: targetDataTypeId, p2: &UA_TYPES[UA_TYPES_VARIANT].typeId) ||
39325 UA_NodeId_equal(p1: targetDataTypeId, p2: &UA_NODEID_NULL))
39326 return true;
39327
39328 /* Ignore if that is configured */
39329 if(server->bootstrapNS0 ||
39330 server->config.allowEmptyVariables == UA_RULEHANDLING_ACCEPT)
39331 return true;
39332
39333 UA_LOG_INFO_SESSION(server->config.logging, session,
39334 "Only Variables with data type BaseDataType "
39335 "can contain an empty value");
39336
39337 /* Ignore if that is configured */
39338 if(server->config.allowEmptyVariables == UA_RULEHANDLING_WARN)
39339 return true;
39340
39341 /* Default handling is to abort */
39342 *reason = reason_EmptyType;
39343 return false;
39344 }
39345
39346 /* Empty array of ExtensionObjects */
39347 if(UA_Variant_hasArrayType(v: value, type: &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]) &&
39348 value->arrayLength == 0) {
39349 /* There is no way to check type compatibility here. Leave it for the upper layers to
39350 * decide, if empty array is okay. */
39351 return true;
39352 }
39353
39354 /* Is the datatype compatible? */
39355 if(!compatibleValueDataType(server, dataType: value->type, constraintDataType: targetDataTypeId)) {
39356 *reason = reason_ValueDataType;
39357 return false;
39358 }
39359
39360 /* Array dimensions are checked later when writing the range */
39361 if(range)
39362 return true;
39363
39364 /* See if the array dimensions match. */
39365 if(!compatibleValueArrayDimensions(value, targetArrayDimensionsSize,
39366 targetArrayDimensions)) {
39367 *reason = reason_ValueArrayDimensions;
39368 return false;
39369 }
39370
39371 /* Check if the valuerank allows for the value dimension */
39372 if(!compatibleValueRankValue(valueRank: targetValueRank, value)) {
39373 *reason = reason_ValueValueRank;
39374 return false;
39375 }
39376
39377 return true;
39378}
39379
39380/*****************/
39381/* Write Service */
39382/*****************/
39383
39384static void
39385freeWrapperArray(void *app, void *context) {
39386 UA_free(ptr: context);
39387}
39388
39389static void
39390unwrapEOArray(UA_Server *server, UA_Variant *value) {
39391 /* Only works on arrays of ExtensionObjects */
39392 if(!UA_Variant_hasArrayType(v: value, type: &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]) ||
39393 value->arrayLength == 0)
39394 return;
39395
39396 /* All eo need to be already decoded and have the same wrapped type */
39397 UA_ExtensionObject *eo = (UA_ExtensionObject*)value->data;
39398 const UA_DataType *innerType = eo[0].content.decoded.type;
39399 for(size_t i = 0; i < value->arrayLength; i++) {
39400 if(eo[i].encoding != UA_EXTENSIONOBJECT_DECODED &&
39401 eo[i].encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE)
39402 return;
39403 if(eo[i].content.decoded.type != innerType)
39404 return;
39405 }
39406
39407 /* Allocate the array for the unwrapped data. Since the adjusted value is
39408 * not cleaned up (only the original value), this memory is being cleaned up
39409 * by a delayed callback in the server after the method call has
39410 * finished. */
39411 UA_DelayedCallback *dc = (UA_DelayedCallback*)
39412 UA_malloc(size: sizeof(UA_DelayedCallback) + (value->arrayLength * innerType->memSize));
39413 if(!dc)
39414 return;
39415
39416 /* Move the content */
39417 uintptr_t pos = ((uintptr_t)dc) + sizeof(UA_DelayedCallback);
39418 void *unwrappedArray = (void*)pos;
39419 for(size_t i = 0; i < value->arrayLength; i++) {
39420 memcpy(dest: (void*)pos, src: eo[i].content.decoded.data, n: innerType->memSize);
39421 pos += innerType->memSize;
39422 }
39423
39424 /* Adjust the value */
39425 value->type = innerType;
39426 value->data = unwrappedArray;
39427
39428 /* Add the delayed callback to free the memory of the unwrapped array */
39429 dc->callback = freeWrapperArray;
39430 dc->application = NULL;
39431 dc->context = dc;
39432 UA_EventLoop *el = server->config.eventLoop;
39433 el->addDelayedCallback(el, dc);
39434}
39435
39436void
39437adjustValueType(UA_Server *server, UA_Variant *value,
39438 const UA_NodeId *targetDataTypeId) {
39439 /* If the value is empty, there is nothing we can do here */
39440 const UA_DataType *type = value->type;
39441 if(!type)
39442 return;
39443
39444 /* The target type is already achieved. No adjustment needed. */
39445 if(UA_NodeId_equal(p1: &type->typeId, p2: targetDataTypeId))
39446 return;
39447
39448 /* Unwrap ExtensionObject arrays if they all contain the same DataType */
39449 unwrapEOArray(server, value);
39450
39451 /* Find the target type */
39452 const UA_DataType *targetType =
39453 UA_findDataTypeWithCustom(typeId: targetDataTypeId, customTypes: server->config.customDataTypes);
39454 if(!targetType)
39455 return;
39456
39457 /* Use the generic functionality shared by client and server */
39458 adjustType(value, targetType);
39459}
39460
39461static UA_StatusCode
39462writeArrayDimensionsAttribute(UA_Server *server, UA_Session *session,
39463 UA_VariableNode *node, const UA_VariableTypeNode *type,
39464 size_t arrayDimensionsSize, UA_UInt32 *arrayDimensions) {
39465 UA_assert(node != NULL);
39466 UA_assert(type != NULL);
39467
39468 /* If this is a variabletype, there must be no instances or subtypes of it
39469 * when we do the change */
39470 if(node->head.nodeClass == UA_NODECLASS_VARIABLETYPE &&
39471 UA_Node_hasSubTypeOrInstances(head: &node->head)) {
39472 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
39473 msg: "Cannot change a variable type with existing instances");
39474 return UA_STATUSCODE_BADINTERNALERROR;
39475 }
39476
39477 /* Check that the array dimensions match with the valuerank */
39478 if(!compatibleValueRankArrayDimensions(server, session, valueRank: node->valueRank,
39479 arrayDimensionsSize)) {
39480 UA_LOG_DEBUG(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
39481 msg: "Cannot write the ArrayDimensions. The ValueRank does not match.");
39482 return UA_STATUSCODE_BADTYPEMISMATCH;
39483 }
39484
39485 /* Check if the array dimensions match with the wildcards in the
39486 * variabletype (dimension length 0) */
39487 if(type->arrayDimensions &&
39488 !compatibleArrayDimensions(constraintArrayDimensionsSize: type->arrayDimensionsSize, constraintArrayDimensions: type->arrayDimensions,
39489 testArrayDimensionsSize: arrayDimensionsSize, testArrayDimensions: arrayDimensions)) {
39490 UA_LOG_DEBUG(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
39491 msg: "Array dimensions in the variable type do not match");
39492 return UA_STATUSCODE_BADTYPEMISMATCH;
39493 }
39494
39495 /* Check if the current value is compatible with the array dimensions */
39496 UA_DataValue value;
39497 UA_DataValue_init(p: &value);
39498 UA_StatusCode retval = readValueAttribute(server, session, vn: node, v: &value);
39499 if(retval != UA_STATUSCODE_GOOD)
39500 return retval;
39501 if(value.hasValue) {
39502 if(!compatibleValueArrayDimensions(value: &value.value, targetArrayDimensionsSize: arrayDimensionsSize,
39503 targetArrayDimensions: arrayDimensions))
39504 retval = UA_STATUSCODE_BADTYPEMISMATCH;
39505 UA_DataValue_clear(p: &value);
39506 if(retval != UA_STATUSCODE_GOOD) {
39507 UA_LOG_DEBUG(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
39508 msg: "Array dimensions in the current value do not match");
39509 return retval;
39510 }
39511 }
39512
39513 /* Ok, apply */
39514 UA_UInt32 *oldArrayDimensions = node->arrayDimensions;
39515 size_t oldArrayDimensionsSize = node->arrayDimensionsSize;
39516 retval = UA_Array_copy(src: arrayDimensions, size: arrayDimensionsSize,
39517 dst: (void**)&node->arrayDimensions,
39518 type: &UA_TYPES[UA_TYPES_UINT32]);
39519 if(retval != UA_STATUSCODE_GOOD)
39520 return retval;
39521 UA_Array_delete(p: oldArrayDimensions, size: oldArrayDimensionsSize, type: &UA_TYPES[UA_TYPES_UINT32]);
39522 node->arrayDimensionsSize = arrayDimensionsSize;
39523 return UA_STATUSCODE_GOOD;
39524}
39525
39526/* Stack layout: ... | node | type */
39527static UA_StatusCode
39528writeValueRank(UA_Server *server, UA_Session *session,
39529 UA_VariableNode *node, const UA_VariableTypeNode *type,
39530 UA_Int32 valueRank) {
39531 UA_assert(node != NULL);
39532 UA_assert(type != NULL);
39533
39534 UA_Int32 constraintValueRank = type->valueRank;
39535
39536 /* If this is a variabletype, there must be no instances or subtypes of it
39537 * when we do the change */
39538 if(node->head.nodeClass == UA_NODECLASS_VARIABLETYPE &&
39539 UA_Node_hasSubTypeOrInstances(head: &node->head))
39540 return UA_STATUSCODE_BADINTERNALERROR;
39541
39542 /* Check if the valuerank of the variabletype allows the change. */
39543 if(!compatibleValueRanks(valueRank, constraintValueRank))
39544 return UA_STATUSCODE_BADTYPEMISMATCH;
39545
39546 /* Check if the new valuerank is compatible with the array dimensions. Use
39547 * the read service to handle data sources. */
39548 size_t arrayDims = node->arrayDimensionsSize;
39549 if(arrayDims == 0) {
39550 /* the value could be an array with no arrayDimensions defined.
39551 dimensions zero indicate a scalar for compatibleValueRankArrayDimensions. */
39552 UA_DataValue value;
39553 UA_DataValue_init(p: &value);
39554 UA_StatusCode retval = readValueAttribute(server, session, vn: node, v: &value);
39555 if(retval != UA_STATUSCODE_GOOD)
39556 return retval;
39557 if(!value.hasValue || !value.value.type) {
39558 /* no value -> apply */
39559 node->valueRank = valueRank;
39560 return UA_STATUSCODE_GOOD;
39561 }
39562 if(!UA_Variant_isScalar(v: &value.value))
39563 arrayDims = 1;
39564 UA_DataValue_clear(p: &value);
39565 }
39566 if(!compatibleValueRankArrayDimensions(server, session, valueRank, arrayDimensionsSize: arrayDims))
39567 return UA_STATUSCODE_BADTYPEMISMATCH;
39568
39569 /* All good, apply the change */
39570 node->valueRank = valueRank;
39571 return UA_STATUSCODE_GOOD;
39572}
39573
39574static UA_StatusCode
39575writeDataTypeAttribute(UA_Server *server, UA_Session *session,
39576 UA_VariableNode *node, const UA_VariableTypeNode *type,
39577 const UA_NodeId *dataType) {
39578 UA_assert(node != NULL);
39579 UA_assert(type != NULL);
39580
39581 /* If this is a variabletype, there must be no instances or subtypes of it
39582 when we do the change */
39583 if(node->head.nodeClass == UA_NODECLASS_VARIABLETYPE &&
39584 UA_Node_hasSubTypeOrInstances(head: &node->head))
39585 return UA_STATUSCODE_BADINTERNALERROR;
39586
39587 /* Does the new type match the constraints of the variabletype? */
39588 if(!compatibleDataTypes(server, dataType, constraintDataType: &type->dataType))
39589 return UA_STATUSCODE_BADTYPEMISMATCH;
39590
39591 /* Check if the current value would match the new type */
39592 UA_DataValue value;
39593 UA_DataValue_init(p: &value);
39594 UA_StatusCode retval = readValueAttribute(server, session, vn: node, v: &value);
39595 if(retval != UA_STATUSCODE_GOOD)
39596 return retval;
39597 if(value.hasValue) {
39598 const char *reason; /* temp value */
39599 if(!compatibleValue(server, session, targetDataTypeId: dataType, targetValueRank: node->valueRank,
39600 targetArrayDimensionsSize: node->arrayDimensionsSize, targetArrayDimensions: node->arrayDimensions,
39601 value: &value.value, NULL, reason: &reason))
39602 retval = UA_STATUSCODE_BADTYPEMISMATCH;
39603 UA_DataValue_clear(p: &value);
39604 if(retval != UA_STATUSCODE_GOOD) {
39605 UA_LOG_DEBUG(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
39606 msg: "The current value does not match the new data type");
39607 return retval;
39608 }
39609 }
39610
39611 /* Replace the datatype nodeid */
39612 UA_NodeId dtCopy = node->dataType;
39613 retval = UA_NodeId_copy(src: dataType, dst: &node->dataType);
39614 if(retval != UA_STATUSCODE_GOOD) {
39615 node->dataType = dtCopy;
39616 return retval;
39617 }
39618 UA_NodeId_clear(p: &dtCopy);
39619 return UA_STATUSCODE_GOOD;
39620}
39621
39622static UA_StatusCode
39623writeValueAttributeWithoutRange(UA_VariableNode *node, const UA_DataValue *value) {
39624 UA_DataValue *oldValue = &node->value.data.value;
39625 UA_DataValue tmpValue = *value;
39626
39627 /* If possible memcpy the new value over the old value without
39628 * a malloc. For this the value needs to be "pointerfree". */
39629 if(oldValue->hasValue && oldValue->value.type && oldValue->value.type->pointerFree &&
39630 value->hasValue && value->value.type && value->value.type->pointerFree &&
39631 oldValue->value.type->memSize == value->value.type->memSize) {
39632 size_t oSize = 1;
39633 size_t vSize = 1;
39634 if(!UA_Variant_isScalar(v: &oldValue->value))
39635 oSize = oldValue->value.arrayLength;
39636 if(!UA_Variant_isScalar(v: &value->value))
39637 vSize = value->value.arrayLength;
39638
39639 if(oSize == vSize &&
39640 oldValue->value.arrayDimensionsSize == value->value.arrayDimensionsSize) {
39641 /* Keep the old pointers, but adjust type and array length */
39642 tmpValue.value = oldValue->value;
39643 tmpValue.value.type = value->value.type;
39644 tmpValue.value.arrayLength = value->value.arrayLength;
39645
39646 /* Copy the data over the old memory */
39647 memcpy(dest: tmpValue.value.data, src: value->value.data,
39648 n: oSize * oldValue->value.type->memSize);
39649 memcpy(dest: tmpValue.value.arrayDimensions, src: value->value.arrayDimensions,
39650 n: sizeof(UA_UInt32) * oldValue->value.arrayDimensionsSize);
39651
39652 /* Set the value */
39653 node->value.data.value = tmpValue;
39654 return UA_STATUSCODE_GOOD;
39655 }
39656 }
39657
39658 /* Make a deep copy of the value and replace when this succeeds */
39659 UA_StatusCode retval = UA_Variant_copy(src: &value->value, dst: &tmpValue.value);
39660 if(retval != UA_STATUSCODE_GOOD)
39661 return retval;
39662 UA_DataValue_clear(p: &node->value.data.value);
39663 node->value.data.value = tmpValue;
39664 return UA_STATUSCODE_GOOD;
39665}
39666
39667static UA_StatusCode
39668writeValueAttributeWithRange(UA_VariableNode *node, const UA_DataValue *value,
39669 const UA_NumericRange *rangeptr) {
39670 /* Value on both sides? */
39671 if(value->status != node->value.data.value.status ||
39672 !value->hasValue || !node->value.data.value.hasValue)
39673 return UA_STATUSCODE_BADINDEXRANGEINVALID;
39674
39675 /* Make scalar a one-entry array for range matching */
39676 UA_Variant editableValue;
39677 const UA_Variant *v = &value->value;
39678 if(UA_Variant_isScalar(v: &value->value)) {
39679 editableValue = value->value;
39680 editableValue.arrayLength = 1;
39681 v = &editableValue;
39682 }
39683
39684 /* Check that the type is an exact match and not only "compatible" */
39685 if(!node->value.data.value.value.type || !v->type ||
39686 !UA_NodeId_equal(p1: &node->value.data.value.value.type->typeId,
39687 p2: &v->type->typeId))
39688 return UA_STATUSCODE_BADTYPEMISMATCH;
39689
39690 /* Write the value */
39691 UA_StatusCode retval =
39692 UA_Variant_setRangeCopy(v: &node->value.data.value.value,
39693 array: v->data, arraySize: v->arrayLength, range: *rangeptr);
39694 if(retval != UA_STATUSCODE_GOOD)
39695 return retval;
39696
39697 /* Write the status and timestamps */
39698 node->value.data.value.hasStatus = value->hasStatus;
39699 node->value.data.value.status = value->status;
39700 node->value.data.value.hasSourceTimestamp = value->hasSourceTimestamp;
39701 node->value.data.value.sourceTimestamp = value->sourceTimestamp;
39702 node->value.data.value.hasSourcePicoseconds = value->hasSourcePicoseconds;
39703 node->value.data.value.sourcePicoseconds = value->sourcePicoseconds;
39704 return UA_STATUSCODE_GOOD;
39705}
39706
39707static UA_StatusCode
39708writeNodeValueAttribute(UA_Server *server, UA_Session *session,
39709 UA_VariableNode *node, const UA_DataValue *value,
39710 const UA_String *indexRange) {
39711 UA_assert(node != NULL);
39712 UA_assert(session != NULL);
39713 UA_LOCK_ASSERT(&server->serviceMutex, 1);
39714
39715 /* Parse the range */
39716 UA_NumericRange range;
39717 range.dimensions = NULL;
39718 UA_NumericRange *rangeptr = NULL;
39719 UA_StatusCode retval = UA_STATUSCODE_GOOD;
39720 if(indexRange && indexRange->length > 0) {
39721 retval = UA_NumericRange_parse(range: &range, str: *indexRange);
39722 if(retval != UA_STATUSCODE_GOOD)
39723 return retval;
39724 rangeptr = &range;
39725 }
39726
39727 /* Created an editable version. The data is not touched. Only the variant
39728 * "container". */
39729 UA_DataValue adjustedValue = *value;
39730
39731 /* Type checking. May change the type of adjustedValue */
39732 const char *reason;
39733 if(value->hasValue && value->value.type) {
39734 /* Try to correct the type */
39735 adjustValueType(server, value: &adjustedValue.value, targetDataTypeId: &node->dataType);
39736
39737 /* Check the type */
39738 if(!compatibleValue(server, session, targetDataTypeId: &node->dataType, targetValueRank: node->valueRank,
39739 targetArrayDimensionsSize: node->arrayDimensionsSize, targetArrayDimensions: node->arrayDimensions,
39740 value: &adjustedValue.value, range: rangeptr, reason: &reason)) {
39741 UA_LOG_NODEID_WARNING(&node->head.nodeId,
39742 if(session == &server->adminSession) {
39743 /* If the value is written via the local API, log a warning */
39744 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_SERVER,
39745 "Writing the value of Node %.*s failed with the "
39746 "following reason: %s",
39747 (int)nodeIdStr.length, nodeIdStr.data, reason);
39748 } else {
39749 /* Don't spam the logs if writing from remote failed */
39750 UA_LOG_DEBUG_SESSION(server->config.logging, session,
39751 "Writing the value of Node %.*s failed with the "
39752 "following reason: %s",
39753 (int)nodeIdStr.length, nodeIdStr.data, reason);
39754 });
39755 if(rangeptr && rangeptr->dimensions != NULL)
39756 UA_free(ptr: rangeptr->dimensions);
39757 return UA_STATUSCODE_BADTYPEMISMATCH;
39758 }
39759 }
39760
39761 /* If no source timestamp is defined create one here.
39762 * It should be created as close to the source as possible. */
39763 if(node->head.nodeClass == UA_NODECLASS_VARIABLE && !node->isDynamic) {
39764 adjustedValue.hasSourceTimestamp = false;
39765 adjustedValue.hasSourcePicoseconds = false;
39766 }
39767
39768 /* Call into the different value storage backends.
39769 *
39770 * TODO: Clean up this mess with duplicated possibilities for external
39771 * callbacks */
39772 retval = UA_STATUSCODE_BADWRITENOTSUPPORTED; /* default */
39773 switch(node->valueBackend.backendType) {
39774 case UA_VALUEBACKENDTYPE_NONE:
39775 if(node->valueSource == UA_VALUESOURCE_DATA) {
39776 /* Write into the in-situ DataValue */
39777 if(!rangeptr)
39778 retval = writeValueAttributeWithoutRange(node, value: &adjustedValue);
39779 else
39780 retval = writeValueAttributeWithRange(node, value: &adjustedValue, rangeptr);
39781
39782 /* Callback after writing */
39783 if(retval == UA_STATUSCODE_GOOD &&
39784 node->value.data.callback.onWrite) {
39785 node->value.data.callback.
39786 onWrite(server, &session->sessionId, session->sessionHandle,
39787 &node->head.nodeId, node->head.context,
39788 rangeptr, &adjustedValue);
39789 }
39790 } else if(node->value.dataSource.write) {
39791 /* Write via the datasource callback */
39792 retval = node->value.dataSource.
39793 write(server, &session->sessionId, session->sessionHandle,
39794 &node->head.nodeId, node->head.context,
39795 rangeptr, &adjustedValue);
39796 }
39797 break;
39798
39799 case UA_VALUEBACKENDTYPE_EXTERNAL:
39800 retval = UA_STATUSCODE_GOOD;
39801 if(node->valueBackend.backend.external.callback.userWrite) {
39802 retval = node->valueBackend.backend.external.callback.
39803 userWrite(server, &session->sessionId, session->sessionHandle,
39804 &node->head.nodeId, node->head.context,
39805 rangeptr, &adjustedValue);
39806 } else {
39807 if(node->valueBackend.backend.external.value) {
39808 UA_DataValue_clear(p: *node->valueBackend.backend.external.value);
39809 retval = UA_DataValue_copy(src: &adjustedValue,
39810 dst: *node->valueBackend.backend.external.value);
39811 }
39812 }
39813 break;
39814
39815 case UA_VALUEBACKENDTYPE_INTERNAL:
39816 case UA_VALUEBACKENDTYPE_DATA_SOURCE_CALLBACK:
39817 default:
39818 break;
39819 }
39820
39821 /* Write into the historical data backend. Not that the historical data
39822 * backend can be configured to "poll" data like a MonitoredItem also. */
39823#ifdef UA_ENABLE_HISTORIZING
39824 if(retval == UA_STATUSCODE_GOOD &&
39825 node->head.nodeClass == UA_NODECLASS_VARIABLE &&
39826 server->config.historyDatabase.setValue) {
39827 server->config.historyDatabase.
39828 setValue(server, server->config.historyDatabase.context,
39829 &session->sessionId, session->sessionHandle,
39830 &node->head.nodeId, node->historizing, &adjustedValue);
39831 }
39832#endif
39833
39834 /* Clean up */
39835 if(rangeptr && rangeptr->dimensions != NULL)
39836 UA_free(ptr: rangeptr->dimensions);
39837 return retval;
39838}
39839
39840static UA_StatusCode
39841writeIsAbstract(UA_Node *node, UA_Boolean value) {
39842 switch(node->head.nodeClass) {
39843 case UA_NODECLASS_OBJECTTYPE:
39844 node->objectTypeNode.isAbstract = value;
39845 break;
39846 case UA_NODECLASS_REFERENCETYPE:
39847 node->referenceTypeNode.isAbstract = value;
39848 break;
39849 case UA_NODECLASS_VARIABLETYPE:
39850 node->variableTypeNode.isAbstract = value;
39851 break;
39852 case UA_NODECLASS_DATATYPE:
39853 node->dataTypeNode.isAbstract = value;
39854 break;
39855 default:
39856 return UA_STATUSCODE_BADNODECLASSINVALID;
39857 }
39858 return UA_STATUSCODE_GOOD;
39859}
39860
39861/*****************/
39862/* Write Service */
39863/*****************/
39864
39865#define CHECK_DATATYPE_SCALAR(EXP_DT) \
39866 if(!wvalue->value.hasValue || \
39867 &UA_TYPES[UA_TYPES_##EXP_DT] != wvalue->value.value.type || \
39868 !UA_Variant_isScalar(&wvalue->value.value)) { \
39869 retval = UA_STATUSCODE_BADTYPEMISMATCH; \
39870 break; \
39871 }
39872
39873#define CHECK_DATATYPE_ARRAY(EXP_DT) \
39874 if(!wvalue->value.hasValue || \
39875 &UA_TYPES[UA_TYPES_##EXP_DT] != wvalue->value.value.type || \
39876 UA_Variant_isScalar(&wvalue->value.value)) { \
39877 retval = UA_STATUSCODE_BADTYPEMISMATCH; \
39878 break; \
39879 }
39880
39881#define CHECK_NODECLASS_WRITE(CLASS) \
39882 if((node->head.nodeClass & (CLASS)) == 0) { \
39883 retval = UA_STATUSCODE_BADNODECLASSINVALID; \
39884 break; \
39885 }
39886
39887#define CHECK_USERWRITEMASK(mask) \
39888 if(!(userWriteMask & (mask))) { \
39889 retval = UA_STATUSCODE_BADUSERACCESSDENIED; \
39890 break; \
39891 }
39892
39893#define GET_NODETYPE \
39894 type = (const UA_VariableTypeNode*) \
39895 getNodeType(server, &node->head); \
39896 if(!type) { \
39897 retval = UA_STATUSCODE_BADTYPEMISMATCH; \
39898 break; \
39899 }
39900
39901/* Update a localized text. Don't touch the target if copying fails
39902 * (maybe due to BadOutOfMemory). */
39903static UA_StatusCode
39904updateLocalizedText(const UA_LocalizedText *source, UA_LocalizedText *target) {
39905 UA_LocalizedText tmp;
39906 UA_StatusCode retval = UA_LocalizedText_copy(src: source, dst: &tmp);
39907 if(retval != UA_STATUSCODE_GOOD)
39908 return retval;
39909 UA_LocalizedText_clear(p: target);
39910 *target = tmp;
39911 return UA_STATUSCODE_GOOD;
39912}
39913
39914/* Trigger sampling if a MonitoredItem surveils the attribute with no sampling
39915 * interval */
39916#ifdef UA_ENABLE_SUBSCRIPTIONS
39917static void
39918triggerImmediateDataChange(UA_Server *server, UA_Session *session,
39919 UA_Node *node, const UA_WriteValue *wvalue) {
39920 UA_MonitoredItem *mon = node->head.monitoredItems;
39921 for(; mon != NULL; mon = mon->sampling.nodeListNext) {
39922 if(mon->itemToMonitor.attributeId != wvalue->attributeId)
39923 continue;
39924 UA_DataValue value;
39925 UA_DataValue_init(p: &value);
39926 ReadWithNode(node, server, session, timestampsToReturn: mon->timestampsToReturn,
39927 id: &mon->itemToMonitor, v: &value);
39928 UA_MonitoredItem_processSampledValue(server, mon, value: &value);
39929 }
39930}
39931#endif
39932
39933/* This function implements the main part of the write service and operates on a
39934 copy of the node (not in single-threaded mode). */
39935static UA_StatusCode
39936copyAttributeIntoNode(UA_Server *server, UA_Session *session,
39937 UA_Node *node, const UA_WriteValue *wvalue) {
39938 UA_assert(session != NULL);
39939 const void *value = wvalue->value.value.data;
39940 UA_UInt32 userWriteMask = getUserWriteMask(server, session, head: &node->head);
39941 UA_StatusCode retval = UA_STATUSCODE_GOOD;
39942
39943 UA_LOG_NODEID_TRACE(&node->head.nodeId,
39944 UA_LOG_TRACE_SESSION(server->config.logging, session,
39945 "Write attribute %"PRIi32 " of Node %.*s",
39946 wvalue->attributeId, (int)nodeIdStr.length,
39947 nodeIdStr.data));
39948
39949 const UA_VariableTypeNode *type;
39950
39951 switch(wvalue->attributeId) {
39952 case UA_ATTRIBUTEID_NODEID:
39953 case UA_ATTRIBUTEID_NODECLASS:
39954 case UA_ATTRIBUTEID_USERWRITEMASK:
39955 case UA_ATTRIBUTEID_USERACCESSLEVEL:
39956 case UA_ATTRIBUTEID_USEREXECUTABLE:
39957 case UA_ATTRIBUTEID_BROWSENAME: /* BrowseName is tracked in a binary tree
39958 for fast lookup */
39959 retval = UA_STATUSCODE_BADWRITENOTSUPPORTED;
39960 break;
39961 case UA_ATTRIBUTEID_DISPLAYNAME:
39962 CHECK_USERWRITEMASK(UA_WRITEMASK_DISPLAYNAME);
39963 CHECK_DATATYPE_SCALAR(LOCALIZEDTEXT);
39964 retval = UA_Node_insertOrUpdateDisplayName(head: &node->head,
39965 value: (const UA_LocalizedText *)value);
39966 break;
39967 case UA_ATTRIBUTEID_DESCRIPTION:
39968 CHECK_USERWRITEMASK(UA_WRITEMASK_DESCRIPTION);
39969 CHECK_DATATYPE_SCALAR(LOCALIZEDTEXT);
39970 retval = UA_Node_insertOrUpdateDescription(head: &node->head,
39971 value: (const UA_LocalizedText *)value);
39972 break;
39973 case UA_ATTRIBUTEID_WRITEMASK:
39974 CHECK_USERWRITEMASK(UA_WRITEMASK_WRITEMASK);
39975 CHECK_DATATYPE_SCALAR(UINT32);
39976 node->head.writeMask = *(const UA_UInt32*)value;
39977 break;
39978 case UA_ATTRIBUTEID_ISABSTRACT:
39979 CHECK_USERWRITEMASK(UA_WRITEMASK_ISABSTRACT);
39980 CHECK_DATATYPE_SCALAR(BOOLEAN);
39981 retval = writeIsAbstract(node, value: *(const UA_Boolean*)value);
39982 break;
39983 case UA_ATTRIBUTEID_SYMMETRIC:
39984 CHECK_NODECLASS_WRITE(UA_NODECLASS_REFERENCETYPE);
39985 CHECK_USERWRITEMASK(UA_WRITEMASK_SYMMETRIC);
39986 CHECK_DATATYPE_SCALAR(BOOLEAN);
39987 node->referenceTypeNode.symmetric = *(const UA_Boolean*)value;
39988 break;
39989 case UA_ATTRIBUTEID_INVERSENAME:
39990 CHECK_NODECLASS_WRITE(UA_NODECLASS_REFERENCETYPE);
39991 CHECK_USERWRITEMASK(UA_WRITEMASK_INVERSENAME);
39992 CHECK_DATATYPE_SCALAR(LOCALIZEDTEXT);
39993 retval = updateLocalizedText(source: (const UA_LocalizedText *)value,
39994 target: &node->referenceTypeNode.inverseName);
39995 break;
39996 case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
39997 CHECK_NODECLASS_WRITE(UA_NODECLASS_VIEW);
39998 CHECK_USERWRITEMASK(UA_WRITEMASK_CONTAINSNOLOOPS);
39999 CHECK_DATATYPE_SCALAR(BOOLEAN);
40000 node->viewNode.containsNoLoops = *(const UA_Boolean*)value;
40001 break;
40002 case UA_ATTRIBUTEID_EVENTNOTIFIER:
40003 CHECK_NODECLASS_WRITE(UA_NODECLASS_VIEW | UA_NODECLASS_OBJECT);
40004 CHECK_USERWRITEMASK(UA_WRITEMASK_EVENTNOTIFIER);
40005 CHECK_DATATYPE_SCALAR(BYTE);
40006 if(node->head.nodeClass == UA_NODECLASS_VIEW) {
40007 node->viewNode.eventNotifier = *(const UA_Byte*)value;
40008 } else {
40009 node->objectNode.eventNotifier = *(const UA_Byte*)value;
40010 }
40011 break;
40012 case UA_ATTRIBUTEID_VALUE:
40013 CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
40014 if(node->head.nodeClass == UA_NODECLASS_VARIABLE) {
40015 /* The access to a value variable is granted via the AccessLevel
40016 * and UserAccessLevel attributes */
40017 UA_Byte accessLevel = getAccessLevel(server, session, node: &node->variableNode);
40018 if(!(accessLevel & (UA_ACCESSLEVELMASK_WRITE))) {
40019 retval = UA_STATUSCODE_BADNOTWRITABLE;
40020 break;
40021 }
40022 accessLevel = getUserAccessLevel(server, session, node: &node->variableNode);
40023 if(!(accessLevel & (UA_ACCESSLEVELMASK_WRITE))) {
40024 retval = UA_STATUSCODE_BADUSERACCESSDENIED;
40025 break;
40026 }
40027 } else { /* UA_NODECLASS_VARIABLETYPE */
40028 CHECK_USERWRITEMASK(UA_WRITEMASK_VALUEFORVARIABLETYPE);
40029 }
40030 retval = writeNodeValueAttribute(server, session, node: &node->variableNode,
40031 value: &wvalue->value, indexRange: &wvalue->indexRange);
40032 break;
40033 case UA_ATTRIBUTEID_DATATYPE:
40034 CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
40035 CHECK_USERWRITEMASK(UA_WRITEMASK_DATATYPE);
40036 CHECK_DATATYPE_SCALAR(NODEID);
40037 GET_NODETYPE;
40038 retval = writeDataTypeAttribute(server, session, node: &node->variableNode,
40039 type, dataType: (const UA_NodeId*)value);
40040 UA_NODESTORE_RELEASE(server, (const UA_Node*)type);
40041 break;
40042 case UA_ATTRIBUTEID_VALUERANK:
40043 CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
40044 CHECK_USERWRITEMASK(UA_WRITEMASK_VALUERANK);
40045 CHECK_DATATYPE_SCALAR(INT32);
40046 GET_NODETYPE;
40047 retval = writeValueRank(server, session, node: &node->variableNode,
40048 type, valueRank: *(const UA_Int32*)value);
40049 UA_NODESTORE_RELEASE(server, (const UA_Node*)type);
40050 break;
40051 case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
40052 CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
40053 CHECK_USERWRITEMASK(UA_WRITEMASK_ARRRAYDIMENSIONS);
40054 CHECK_DATATYPE_ARRAY(UINT32);
40055 GET_NODETYPE;
40056 retval = writeArrayDimensionsAttribute(server, session, node: &node->variableNode,
40057 type, arrayDimensionsSize: wvalue->value.value.arrayLength,
40058 arrayDimensions: (UA_UInt32 *)wvalue->value.value.data);
40059 UA_NODESTORE_RELEASE(server, (const UA_Node*)type);
40060 break;
40061 case UA_ATTRIBUTEID_ACCESSLEVEL:
40062 CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE);
40063 CHECK_USERWRITEMASK(UA_WRITEMASK_ACCESSLEVEL);
40064 CHECK_DATATYPE_SCALAR(BYTE);
40065 node->variableNode.accessLevel = *(const UA_Byte*)value;
40066 break;
40067 case UA_ATTRIBUTEID_ACCESSLEVELEX:
40068 CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE);
40069 CHECK_USERWRITEMASK(UA_WRITEMASK_ACCESSLEVELEX);
40070 CHECK_DATATYPE_SCALAR(UINT32);
40071 node->variableNode.accessLevel = (UA_Byte)(*(const UA_UInt32*)value & 0xFF);
40072 break;
40073 case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
40074 CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE);
40075 CHECK_USERWRITEMASK(UA_WRITEMASK_MINIMUMSAMPLINGINTERVAL);
40076 CHECK_DATATYPE_SCALAR(DOUBLE);
40077 node->variableNode.minimumSamplingInterval = *(const UA_Double*)value;
40078 break;
40079 case UA_ATTRIBUTEID_HISTORIZING:
40080 CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE);
40081 CHECK_USERWRITEMASK(UA_WRITEMASK_HISTORIZING);
40082 CHECK_DATATYPE_SCALAR(BOOLEAN);
40083 node->variableNode.historizing = *(const UA_Boolean*)value;
40084 break;
40085 case UA_ATTRIBUTEID_EXECUTABLE:
40086 CHECK_NODECLASS_WRITE(UA_NODECLASS_METHOD);
40087 CHECK_USERWRITEMASK(UA_WRITEMASK_EXECUTABLE);
40088 CHECK_DATATYPE_SCALAR(BOOLEAN);
40089 node->methodNode.executable = *(const UA_Boolean*)value;
40090 break;
40091 default:
40092 retval = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
40093 break;
40094 }
40095
40096 /* Check if writing succeeded */
40097 if(retval != UA_STATUSCODE_GOOD) {
40098 UA_LOG_INFO_SESSION(server->config.logging, session,
40099 "WriteRequest returned status code %s",
40100 UA_StatusCode_name(retval));
40101 return retval;
40102 }
40103
40104 /* Trigger MonitoredItems with no SamplingInterval */
40105#ifdef UA_ENABLE_SUBSCRIPTIONS
40106 triggerImmediateDataChange(server, session, node, wvalue);
40107#endif
40108
40109 return UA_STATUSCODE_GOOD;
40110}
40111
40112void
40113Operation_Write(UA_Server *server, UA_Session *session, void *context,
40114 const UA_WriteValue *wv, UA_StatusCode *result) {
40115 UA_assert(session != NULL);
40116 *result = UA_Server_editNode(server, session, nodeId: &wv->nodeId,
40117 callback: (UA_EditNodeCallback)copyAttributeIntoNode,
40118 data: (void*)(uintptr_t)wv);
40119}
40120
40121void
40122Service_Write(UA_Server *server, UA_Session *session,
40123 const UA_WriteRequest *request,
40124 UA_WriteResponse *response) {
40125 UA_assert(session != NULL);
40126 UA_LOG_DEBUG_SESSION(server->config.logging, session,
40127 "Processing WriteRequest");
40128 UA_LOCK_ASSERT(&server->serviceMutex, 1);
40129
40130 if(server->config.maxNodesPerWrite != 0 &&
40131 request->nodesToWriteSize > server->config.maxNodesPerWrite) {
40132 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
40133 return;
40134 }
40135
40136 response->responseHeader.serviceResult =
40137 UA_Server_processServiceOperations(server, session,
40138 operationCallback: (UA_ServiceOperation)Operation_Write, NULL,
40139 requestOperations: &request->nodesToWriteSize,
40140 requestOperationsType: &UA_TYPES[UA_TYPES_WRITEVALUE],
40141 responseOperations: &response->resultsSize,
40142 responseOperationsType: &UA_TYPES[UA_TYPES_STATUSCODE]);
40143}
40144
40145UA_StatusCode
40146UA_Server_write(UA_Server *server, const UA_WriteValue *value) {
40147 UA_StatusCode res = UA_STATUSCODE_GOOD;
40148 lockServer(server);
40149 Operation_Write(server, session: &server->adminSession, NULL, wv: value, result: &res);
40150 unlockServer(server);
40151 return res;
40152}
40153
40154/* Convenience function to be wrapped into inline functions */
40155UA_StatusCode
40156__UA_Server_write(UA_Server *server, const UA_NodeId *nodeId,
40157 const UA_AttributeId attributeId,
40158 const UA_DataType *attr_type, const void *attr) {
40159 lockServer(server);
40160 UA_StatusCode res = writeAttribute(server, session: &server->adminSession,
40161 nodeId, attributeId, attr, attr_type);
40162 unlockServer(server);
40163 return res;
40164}
40165
40166/* Internal convenience function */
40167UA_StatusCode
40168writeAttribute(UA_Server *server, UA_Session *session,
40169 const UA_NodeId *nodeId, const UA_AttributeId attributeId,
40170 const void *attr, const UA_DataType *attr_type) {
40171 UA_LOCK_ASSERT(&server->serviceMutex, 1);
40172
40173 UA_WriteValue wvalue;
40174 UA_WriteValue_init(p: &wvalue);
40175 wvalue.nodeId = *nodeId;
40176 wvalue.attributeId = attributeId;
40177 wvalue.value.hasValue = true;
40178 if(attr_type == &UA_TYPES[UA_TYPES_VARIANT]) {
40179 wvalue.value.value = *(const UA_Variant*)attr;
40180 } else if(attr_type == &UA_TYPES[UA_TYPES_DATAVALUE]) {
40181 wvalue.value = *(const UA_DataValue*)attr;
40182 } else {
40183 /* hacked cast. the target WriteValue is used as const anyway */
40184 UA_Variant_setScalar(v: &wvalue.value.value,
40185 p: (void*)(uintptr_t)attr, type: attr_type);
40186 }
40187
40188 UA_StatusCode res = UA_STATUSCODE_GOOD;
40189 Operation_Write(server, session, NULL, wv: &wvalue, result: &res);
40190 return res;
40191}
40192
40193#ifdef UA_ENABLE_HISTORIZING
40194typedef void
40195 (*UA_HistoryDatabase_readFunc)(UA_Server *server, void *hdbContext,
40196 const UA_NodeId *sessionId, void *sessionContext,
40197 const UA_RequestHeader *requestHeader,
40198 const void *historyReadDetails,
40199 UA_TimestampsToReturn timestampsToReturn,
40200 UA_Boolean releaseContinuationPoints,
40201 size_t nodesToReadSize,
40202 const UA_HistoryReadValueId *nodesToRead,
40203 UA_HistoryReadResponse *response,
40204 void * const * const historyData);
40205
40206void
40207Service_HistoryRead(UA_Server *server, UA_Session *session,
40208 const UA_HistoryReadRequest *request,
40209 UA_HistoryReadResponse *response) {
40210 UA_assert(session != NULL);
40211 UA_LOCK_ASSERT(&server->serviceMutex, 1);
40212 if(server->config.historyDatabase.context == NULL) {
40213 response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTSUPPORTED;
40214 return;
40215 }
40216
40217 if(request->historyReadDetails.encoding != UA_EXTENSIONOBJECT_DECODED) {
40218 response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTSUPPORTED;
40219 return;
40220 }
40221
40222 const UA_DataType *historyDataType = &UA_TYPES[UA_TYPES_HISTORYDATA];
40223 UA_HistoryDatabase_readFunc readHistory = NULL;
40224 if(request->historyReadDetails.content.decoded.type ==
40225 &UA_TYPES[UA_TYPES_READRAWMODIFIEDDETAILS]) {
40226 UA_ReadRawModifiedDetails *details = (UA_ReadRawModifiedDetails*)
40227 request->historyReadDetails.content.decoded.data;
40228 if(!details->isReadModified) {
40229 readHistory = (UA_HistoryDatabase_readFunc)
40230 server->config.historyDatabase.readRaw;
40231 } else {
40232 historyDataType = &UA_TYPES[UA_TYPES_HISTORYMODIFIEDDATA];
40233 readHistory = (UA_HistoryDatabase_readFunc)
40234 server->config.historyDatabase.readModified;
40235 }
40236 } else if(request->historyReadDetails.content.decoded.type ==
40237 &UA_TYPES[UA_TYPES_READEVENTDETAILS]) {
40238 historyDataType = &UA_TYPES[UA_TYPES_HISTORYEVENT];
40239 readHistory = (UA_HistoryDatabase_readFunc)
40240 server->config.historyDatabase.readEvent;
40241 } else if(request->historyReadDetails.content.decoded.type ==
40242 &UA_TYPES[UA_TYPES_READPROCESSEDDETAILS]) {
40243 readHistory = (UA_HistoryDatabase_readFunc)
40244 server->config.historyDatabase.readProcessed;
40245 } else if(request->historyReadDetails.content.decoded.type ==
40246 &UA_TYPES[UA_TYPES_READATTIMEDETAILS]) {
40247 readHistory = (UA_HistoryDatabase_readFunc)
40248 server->config.historyDatabase.readAtTime;
40249 } else {
40250 /* TODO handle more request->historyReadDetails.content.decoded.type types */
40251 response->responseHeader.serviceResult = UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED;
40252 return;
40253 }
40254
40255 /* Check if the configured History-Backend supports the requested history type */
40256 if(!readHistory) {
40257 UA_LOG_INFO_SESSION(server->config.logging, session,
40258 "The configured HistoryBackend does not support the selected history-type.");
40259 response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTSUPPORTED;
40260 return;
40261 }
40262
40263 /* Something to do? */
40264 if(request->nodesToReadSize == 0) {
40265 response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
40266 return;
40267 }
40268
40269 /* Check if there are too many operations */
40270 if(server->config.maxNodesPerRead != 0 &&
40271 request->nodesToReadSize > server->config.maxNodesPerRead) {
40272 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
40273 return;
40274 }
40275
40276 /* Allocate a temporary array to forward the result pointers to the
40277 * backend */
40278 void **historyData = (void **)
40279 UA_calloc(nmemb: request->nodesToReadSize, size: sizeof(void*));
40280 if(!historyData) {
40281 response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
40282 return;
40283 }
40284
40285 /* Allocate the results array */
40286 response->results = (UA_HistoryReadResult*)
40287 UA_Array_new(size: request->nodesToReadSize, type: &UA_TYPES[UA_TYPES_HISTORYREADRESULT]);
40288 if(!response->results) {
40289 UA_free(ptr: historyData);
40290 response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
40291 return;
40292 }
40293 response->resultsSize = request->nodesToReadSize;
40294
40295 for(size_t i = 0; i < response->resultsSize; ++i) {
40296 void * data = UA_new(type: historyDataType);
40297 UA_ExtensionObject_setValue(eo: &response->results[i].historyData,
40298 p: data, type: historyDataType);
40299 historyData[i] = data;
40300 }
40301 readHistory(server, server->config.historyDatabase.context,
40302 &session->sessionId, session->sessionHandle,
40303 &request->requestHeader,
40304 request->historyReadDetails.content.decoded.data,
40305 request->timestampsToReturn,
40306 request->releaseContinuationPoints,
40307 request->nodesToReadSize, request->nodesToRead,
40308 response, historyData);
40309 UA_free(ptr: historyData);
40310}
40311
40312void
40313Service_HistoryUpdate(UA_Server *server, UA_Session *session,
40314 const UA_HistoryUpdateRequest *request,
40315 UA_HistoryUpdateResponse *response) {
40316 UA_assert(session != NULL);
40317 UA_LOCK_ASSERT(&server->serviceMutex, 1);
40318
40319 response->resultsSize = request->historyUpdateDetailsSize;
40320 response->results = (UA_HistoryUpdateResult*)
40321 UA_Array_new(size: response->resultsSize, type: &UA_TYPES[UA_TYPES_HISTORYUPDATERESULT]);
40322 if(!response->results) {
40323 response->resultsSize = 0;
40324 response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
40325 return;
40326 }
40327
40328 for(size_t i = 0; i < request->historyUpdateDetailsSize; ++i) {
40329 UA_HistoryUpdateResult_init(p: &response->results[i]);
40330 if(request->historyUpdateDetails[i].encoding != UA_EXTENSIONOBJECT_DECODED) {
40331 response->results[i].statusCode = UA_STATUSCODE_BADNOTSUPPORTED;
40332 continue;
40333 }
40334
40335 const UA_DataType *updateDetailsType =
40336 request->historyUpdateDetails[i].content.decoded.type;
40337 void *updateDetailsData = request->historyUpdateDetails[i].content.decoded.data;
40338
40339 if(updateDetailsType == &UA_TYPES[UA_TYPES_UPDATEDATADETAILS]) {
40340 if(!server->config.historyDatabase.updateData) {
40341 response->results[i].statusCode = UA_STATUSCODE_BADNOTSUPPORTED;
40342 continue;
40343 }
40344 server->config.historyDatabase.
40345 updateData(server, server->config.historyDatabase.context,
40346 &session->sessionId, session->sessionHandle,
40347 &request->requestHeader,
40348 (UA_UpdateDataDetails*)updateDetailsData,
40349 &response->results[i]);
40350 continue;
40351 }
40352
40353 if(updateDetailsType == &UA_TYPES[UA_TYPES_DELETERAWMODIFIEDDETAILS]) {
40354 if(!server->config.historyDatabase.deleteRawModified) {
40355 response->results[i].statusCode = UA_STATUSCODE_BADNOTSUPPORTED;
40356 continue;
40357 }
40358 server->config.historyDatabase.
40359 deleteRawModified(server, server->config.historyDatabase.context,
40360 &session->sessionId, session->sessionHandle,
40361 &request->requestHeader,
40362 (UA_DeleteRawModifiedDetails*)updateDetailsData,
40363 &response->results[i]);
40364 continue;
40365 }
40366
40367 response->results[i].statusCode = UA_STATUSCODE_BADNOTSUPPORTED;
40368 }
40369}
40370
40371#endif
40372
40373UA_StatusCode
40374UA_Server_writeObjectProperty(UA_Server *server, const UA_NodeId objectId,
40375 const UA_QualifiedName propertyName,
40376 const UA_Variant value) {
40377 lockServer(server);
40378 UA_StatusCode retVal = writeObjectProperty(server, objectId, propertyName, value);
40379 unlockServer(server);
40380 return retVal;
40381}
40382
40383UA_StatusCode
40384writeObjectProperty(UA_Server *server, const UA_NodeId objectId,
40385 const UA_QualifiedName propertyName,
40386 const UA_Variant value) {
40387 UA_LOCK_ASSERT(&server->serviceMutex, 1);
40388 UA_RelativePathElement rpe;
40389 UA_RelativePathElement_init(p: &rpe);
40390 rpe.referenceTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY);
40391 rpe.isInverse = false;
40392 rpe.includeSubtypes = false;
40393 rpe.targetName = propertyName;
40394
40395 UA_BrowsePath bp;
40396 UA_BrowsePath_init(p: &bp);
40397 bp.startingNode = objectId;
40398 bp.relativePath.elementsSize = 1;
40399 bp.relativePath.elements = &rpe;
40400
40401 UA_StatusCode retval;
40402 UA_BrowsePathResult bpr = translateBrowsePathToNodeIds(server, browsePath: &bp);
40403 if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) {
40404 retval = bpr.statusCode;
40405 UA_BrowsePathResult_clear(p: &bpr);
40406 return retval;
40407 }
40408
40409 retval = writeValueAttribute(server, nodeId: bpr.targets[0].targetId.nodeId, value: &value);
40410
40411 UA_BrowsePathResult_clear(p: &bpr);
40412 return retval;
40413}
40414
40415UA_StatusCode
40416writeObjectProperty_scalar(UA_Server *server, const UA_NodeId objectId,
40417 const UA_QualifiedName propertyName,
40418 const void *value, const UA_DataType *type) {
40419 UA_Variant var;
40420 UA_Variant_init(p: &var);
40421 UA_Variant_setScalar(v: &var, p: (void*)(uintptr_t)value, type);
40422 return writeObjectProperty(server, objectId, propertyName, value: var);
40423}
40424
40425UA_StatusCode UA_EXPORT
40426UA_Server_writeObjectProperty_scalar(UA_Server *server, const UA_NodeId objectId,
40427 const UA_QualifiedName propertyName,
40428 const void *value, const UA_DataType *type) {
40429 lockServer(server);
40430 UA_StatusCode retval =
40431 writeObjectProperty_scalar(server, objectId, propertyName, value, type);
40432 unlockServer(server);
40433 return retval;
40434}
40435
40436static UA_LocalizedText
40437getLocalizedForSession(const UA_Session *session,
40438 const UA_LocalizedTextListEntry *root) {
40439 const UA_LocalizedTextListEntry *lt;
40440 UA_LocalizedText result;
40441 UA_LocalizedText_init(p: &result);
40442
40443 /* No session. Return the first */
40444 if(!session)
40445 goto not_found;
40446
40447 /* Exact match? */
40448 for(size_t i = 0; i < session->localeIdsSize; ++i) {
40449 for(lt = root; lt != NULL; lt = lt->next) {
40450 if(UA_String_equal(p1: &session->localeIds[i], p2: &lt->localizedText.locale))
40451 return lt->localizedText;
40452 }
40453 }
40454
40455 /* Partial match, e.g. de-DE instead of de-CH */
40456 for(size_t i = 0; i < session->localeIdsSize; ++i) {
40457 if(session->localeIds[i].length < 2 ||
40458 (session->localeIdsSize > 2 &&
40459 session->localeIds[i].data[2] != '-'))
40460 continue;
40461
40462 UA_String requestedPrefix;
40463 requestedPrefix.data = session->localeIds[i].data;
40464 requestedPrefix.length = 2;
40465
40466 for(lt = root; lt != NULL; lt = lt->next) {
40467 if(lt->localizedText.locale.length < 2 ||
40468 (lt->localizedText.locale.length > 2 &&
40469 lt->localizedText.locale.data[2] != '-'))
40470 continue;
40471
40472 UA_String currentPrefix;
40473 currentPrefix.data = lt->localizedText.locale.data;
40474 currentPrefix.length = 2;
40475
40476 if(UA_String_equal(p1: &requestedPrefix, p2: &currentPrefix))
40477 return lt->localizedText;
40478 }
40479 }
40480
40481 /* Not found. Return the first localized text that was added (last in the
40482 * linked list). Return an empty result if the list is empty. */
40483 not_found:
40484 if(!root)
40485 return result;
40486 while(root->next)
40487 root = root->next;
40488 return root->localizedText;
40489}
40490
40491UA_LocalizedText
40492UA_Session_getNodeDisplayName(const UA_Session *session,
40493 const UA_NodeHead *head) {
40494 return getLocalizedForSession(session, root: head->displayName);
40495}
40496
40497UA_LocalizedText
40498UA_Session_getNodeDescription(const UA_Session *session,
40499 const UA_NodeHead *head) {
40500 return getLocalizedForSession(session, root: head->description);
40501}
40502
40503/**** amalgamated original file "/src/server/ua_services_discovery.c" ****/
40504
40505/* This Source Code Form is subject to the terms of the Mozilla Public
40506 * License, v. 2.0. If a copy of the MPL was not distributed with this
40507 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
40508 *
40509 * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
40510 * Copyright 2014-2016 (c) Sten Grüner
40511 * Copyright 2014, 2017 (c) Florian Palm
40512 * Copyright 2016 (c) Oleksiy Vasylyev
40513 * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH
40514 * Copyright 2017 (c) frax2222
40515 * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB
40516 */
40517
40518
40519#ifdef UA_ENABLE_DISCOVERY
40520
40521
40522static UA_StatusCode
40523setApplicationDescriptionFromRegisteredServer(const UA_FindServersRequest *request,
40524 UA_ApplicationDescription *target,
40525 const UA_RegisteredServer *registeredServer) {
40526 UA_ApplicationDescription_init(p: target);
40527 UA_StatusCode retval =
40528 UA_String_copy(src: &registeredServer->serverUri, dst: &target->applicationUri);
40529 if(retval != UA_STATUSCODE_GOOD)
40530 return retval;
40531
40532 retval = UA_String_copy(src: &registeredServer->productUri, dst: &target->productUri);
40533 if(retval != UA_STATUSCODE_GOOD)
40534 return retval;
40535
40536 // if the client requests a specific locale, select the corresponding server name
40537 if(request->localeIdsSize) {
40538 UA_Boolean appNameFound = false;
40539 for(size_t i =0; i<request->localeIdsSize && !appNameFound; i++) {
40540 for(size_t j =0; j<registeredServer->serverNamesSize; j++) {
40541 if(UA_String_equal(p1: &request->localeIds[i],
40542 p2: &registeredServer->serverNames[j].locale)) {
40543 retval = UA_LocalizedText_copy(src: &registeredServer->serverNames[j],
40544 dst: &target->applicationName);
40545 if(retval != UA_STATUSCODE_GOOD)
40546 return retval;
40547 appNameFound = true;
40548 break;
40549 }
40550 }
40551 }
40552
40553 // server does not have the requested local, therefore we can select the
40554 // most suitable one
40555 if(!appNameFound && registeredServer->serverNamesSize) {
40556 retval = UA_LocalizedText_copy(src: &registeredServer->serverNames[0],
40557 dst: &target->applicationName);
40558 if(retval != UA_STATUSCODE_GOOD)
40559 return retval;
40560 }
40561 } else if(registeredServer->serverNamesSize) {
40562 // just take the first name
40563 retval = UA_LocalizedText_copy(src: &registeredServer->serverNames[0],
40564 dst: &target->applicationName);
40565 if(retval != UA_STATUSCODE_GOOD)
40566 return retval;
40567 }
40568
40569 target->applicationType = registeredServer->serverType;
40570 retval = UA_String_copy(src: &registeredServer->gatewayServerUri, dst: &target->gatewayServerUri);
40571 if(retval != UA_STATUSCODE_GOOD)
40572 return retval;
40573 // TODO where do we get the discoveryProfileUri for application data?
40574
40575 target->discoveryUrlsSize = registeredServer->discoveryUrlsSize;
40576 if(registeredServer->discoveryUrlsSize) {
40577 size_t duSize = sizeof(UA_String) * registeredServer->discoveryUrlsSize;
40578 target->discoveryUrls = (UA_String *)UA_malloc(size: duSize);
40579 if(!target->discoveryUrls)
40580 return UA_STATUSCODE_BADOUTOFMEMORY;
40581 for(size_t i = 0; i < registeredServer->discoveryUrlsSize; i++) {
40582 retval = UA_String_copy(src: &registeredServer->discoveryUrls[i],
40583 dst: &target->discoveryUrls[i]);
40584 if(retval != UA_STATUSCODE_GOOD)
40585 return retval;
40586 }
40587 }
40588
40589 return retval;
40590}
40591#endif
40592
40593void Service_FindServers(UA_Server *server, UA_Session *session,
40594 const UA_FindServersRequest *request,
40595 UA_FindServersResponse *response) {
40596 UA_LOG_DEBUG_SESSION(server->config.logging, session, "Processing FindServersRequest");
40597 UA_LOCK_ASSERT(&server->serviceMutex, 1);
40598
40599 /* Return the server itself? */
40600 UA_Boolean foundSelf = false;
40601 if(request->serverUrisSize) {
40602 for(size_t i = 0; i < request->serverUrisSize; i++) {
40603 if(UA_String_equal(p1: &request->serverUris[i],
40604 p2: &server->config.applicationDescription.applicationUri)) {
40605 foundSelf = true;
40606 break;
40607 }
40608 }
40609 } else {
40610 foundSelf = true;
40611 }
40612
40613#ifndef UA_ENABLE_DISCOVERY
40614 if(!foundSelf)
40615 return;
40616
40617 response->responseHeader.serviceResult =
40618 UA_Array_copy(&server->config.applicationDescription, 1,
40619 (void**)&response->servers,
40620 &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]);
40621 if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
40622 return;
40623
40624 response->serversSize = 1;
40625#else
40626 UA_DiscoveryManager *dm = (UA_DiscoveryManager*)
40627 getServerComponentByName(server, name: UA_STRING(chars: "discovery"));
40628 if(!dm) {
40629 response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR;
40630 return;
40631 }
40632
40633 /* Allocate enough memory, including memory for the "self" response */
40634 size_t maxResults = dm->registeredServersSize + 1;
40635 response->servers = (UA_ApplicationDescription*)
40636 UA_Array_new(size: maxResults, type: &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]);
40637 if(!response->servers) {
40638 response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
40639 return;
40640 }
40641
40642 /* Copy into the response. TODO: Evaluate return codes */
40643 size_t pos = 0;
40644 if(foundSelf)
40645 UA_ApplicationDescription_copy(src: &server->config.applicationDescription,
40646 dst: &response->servers[pos++]);
40647
40648 registeredServer_list_entry* current;
40649 LIST_FOREACH(current, &dm->registeredServers, pointers) {
40650 UA_Boolean usable = (request->serverUrisSize == 0);
40651 if(!usable) {
40652 /* If client only requested a specific set of servers */
40653 for(size_t i = 0; i < request->serverUrisSize; i++) {
40654 if(UA_String_equal(p1: &current->registeredServer.serverUri,
40655 p2: &request->serverUris[i])) {
40656 usable = true;
40657 break;
40658 }
40659 }
40660 }
40661
40662 if(usable)
40663 setApplicationDescriptionFromRegisteredServer(request, target: &response->servers[pos++],
40664 registeredServer: &current->registeredServer);
40665 }
40666
40667 /* Set the final size */
40668 if(pos > 0) {
40669 response->serversSize = pos;
40670 } else {
40671 UA_free(ptr: response->servers);
40672 response->servers = NULL;
40673 }
40674#endif
40675
40676 if(request->endpointUrl.length > 0 && response->servers != NULL) {
40677 for(size_t i = 0; i < response->serversSize; i++) {
40678 UA_Array_delete(p: response->servers[i].discoveryUrls,
40679 size: response->servers[i].discoveryUrlsSize,
40680 type: &UA_TYPES[UA_TYPES_STRING]);
40681 response->servers[i].discoveryUrls = NULL;
40682 response->servers[i].discoveryUrlsSize = 0;
40683 response->responseHeader.serviceResult |=
40684 UA_Array_appendCopy(p: (void**)&response->servers[i].discoveryUrls,
40685 size: &response->servers[i].discoveryUrlsSize,
40686 newElem: &request->endpointUrl, type: &UA_TYPES[UA_TYPES_STRING]);
40687 }
40688 }
40689}
40690
40691#if defined(UA_ENABLE_DISCOVERY) && defined(UA_ENABLE_DISCOVERY_MULTICAST)
40692/* All filter criteria must be fulfilled in the list entry. The comparison is
40693 * case insensitive. Returns true if the entry matches the filter. */
40694static UA_Boolean
40695entryMatchesCapabilityFilter(size_t serverCapabilityFilterSize,
40696 UA_String *serverCapabilityFilter,
40697 serverOnNetwork_list_entry* current) {
40698 /* If the entry has less capabilities defined than the filter, there's no match */
40699 if(serverCapabilityFilterSize > current->serverOnNetwork.serverCapabilitiesSize)
40700 return false;
40701 for(size_t i = 0; i < serverCapabilityFilterSize; i++) {
40702 UA_Boolean capabilityFound = false;
40703 for(size_t j = 0; j < current->serverOnNetwork.serverCapabilitiesSize; j++) {
40704 if(UA_String_equal_ignorecase(&serverCapabilityFilter[i],
40705 &current->serverOnNetwork.serverCapabilities[j])) {
40706 capabilityFound = true;
40707 break;
40708 }
40709 }
40710 if(!capabilityFound)
40711 return false;
40712 }
40713 return true;
40714}
40715
40716void
40717Service_FindServersOnNetwork(UA_Server *server, UA_Session *session,
40718 const UA_FindServersOnNetworkRequest *request,
40719 UA_FindServersOnNetworkResponse *response) {
40720 UA_LOCK_ASSERT(&server->serviceMutex, 1);
40721
40722 UA_DiscoveryManager *dm = (UA_DiscoveryManager*)
40723 getServerComponentByName(server, UA_STRING("discovery"));
40724 if(!dm) {
40725 response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR;
40726 return;
40727 }
40728
40729 if(!server->config.mdnsEnabled) {
40730 response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTIMPLEMENTED;
40731 return;
40732 }
40733
40734 /* Set LastCounterResetTime */
40735 response->lastCounterResetTime =
40736 dm->serverOnNetworkRecordIdLastReset;
40737
40738 /* Compute the max number of records to return */
40739 UA_UInt32 recordCount = 0;
40740 if(request->startingRecordId < dm->serverOnNetworkRecordIdCounter)
40741 recordCount = dm->serverOnNetworkRecordIdCounter - request->startingRecordId;
40742 if(request->maxRecordsToReturn && recordCount > request->maxRecordsToReturn)
40743 recordCount = UA_MIN(recordCount, request->maxRecordsToReturn);
40744 if(recordCount == 0) {
40745 response->serversSize = 0;
40746 return;
40747 }
40748
40749 /* Iterate over all records and add to filtered list */
40750 UA_UInt32 filteredCount = 0;
40751 UA_STACKARRAY(UA_ServerOnNetwork*, filtered, recordCount);
40752 serverOnNetwork_list_entry* current;
40753 LIST_FOREACH(current, &dm->serverOnNetwork, pointers) {
40754 if(filteredCount >= recordCount)
40755 break;
40756 if(current->serverOnNetwork.recordId < request->startingRecordId)
40757 continue;
40758 if(!entryMatchesCapabilityFilter(request->serverCapabilityFilterSize,
40759 request->serverCapabilityFilter, current))
40760 continue;
40761 filtered[filteredCount++] = &current->serverOnNetwork;
40762 }
40763
40764 if(filteredCount == 0)
40765 return;
40766
40767 /* Allocate the array for the response */
40768 response->servers = (UA_ServerOnNetwork*)
40769 UA_malloc(sizeof(UA_ServerOnNetwork)*filteredCount);
40770 if(!response->servers) {
40771 response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
40772 return;
40773 }
40774 response->serversSize = filteredCount;
40775
40776 /* Copy the server names */
40777 for(size_t i = 0; i < filteredCount; i++)
40778 UA_ServerOnNetwork_copy(filtered[i], &response->servers[filteredCount-i-1]);
40779}
40780#endif
40781
40782static const UA_String UA_SECURITY_POLICY_BASIC256SHA256_URI =
40783 UA_STRING_STATIC("http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256");
40784
40785UA_SecurityPolicy *
40786getDefaultEncryptedSecurityPolicy(UA_Server *server) {
40787 for(size_t i = 0; i < server->config.securityPoliciesSize; i++) {
40788 UA_SecurityPolicy *sp = &server->config.securityPolicies[i];
40789 if(UA_String_equal(p1: &UA_SECURITY_POLICY_BASIC256SHA256_URI, p2: &sp->policyUri))
40790 return sp;
40791 }
40792 for(size_t i = server->config.securityPoliciesSize; i > 0; i--) {
40793 UA_SecurityPolicy *sp = &server->config.securityPolicies[i-1];
40794 if(!UA_String_equal(p1: &UA_SECURITY_POLICY_NONE_URI, p2: &sp->policyUri))
40795 return sp;
40796 }
40797 return NULL; /* No encrypted policy found */
40798}
40799
40800const char *securityModeStrs[4] = {"-invalid", "-none", "-sign", "-sign+encrypt"};
40801
40802UA_String
40803securityPolicyUriPostfix(const UA_String uri) {
40804 for(UA_Byte *b = uri.data + uri.length - 1; b >= uri.data; b--) {
40805 if(*b != '#')
40806 continue;
40807 UA_String postfix = {uri.length - (size_t)(b - uri.data), b};
40808 return postfix;
40809 }
40810 return uri;
40811}
40812
40813static UA_StatusCode
40814updateEndpointUserIdentityToken(UA_Server *server, UA_EndpointDescription *ed) {
40815 /* Don't change the UserIdentityTokens if there are manually configured
40816 * entries */
40817 if(ed->userIdentityTokensSize > 0)
40818 return UA_STATUSCODE_GOOD;
40819
40820 /* Copy the UserTokenPolicies from the AccessControl plugin, but only the matching ones to the securityPolicyUri.
40821 * TODO: Different instances of the AccessControl plugin per Endpoint */
40822 UA_StatusCode res = UA_STATUSCODE_GOOD;
40823 UA_ServerConfig *sc = &server->config;
40824 for(size_t i = 0; i < sc->accessControl.userTokenPoliciesSize; i++) {
40825 UA_UserTokenPolicy *utp = &sc->accessControl.userTokenPolicies[i];
40826 res = UA_Array_appendCopy(p: (void**)&ed->userIdentityTokens,
40827 size: &ed->userIdentityTokensSize, newElem: utp,
40828 type: &UA_TYPES[UA_TYPES_USERTOKENPOLICY]);
40829 if(res != UA_STATUSCODE_GOOD)
40830 return res;
40831
40832 /* Select the SecurityPolicy for the UserTokenType.
40833 * If not set, the SecurityPolicy of the SecureChannel is used. */
40834 utp = &ed->userIdentityTokens[ed->userIdentityTokensSize - 1];
40835 UA_String_clear(p: &utp->securityPolicyUri);
40836#ifdef UA_ENABLE_ENCRYPTION
40837 /* Anonymous tokens don't need encryption. All other tokens require
40838 * encryption with the exception of Username/Password if also the
40839 * allowNonePolicyPassword option has been set. The same logic is used
40840 * in selectEndpointAndTokenPolicy (ua_services_session.c). */
40841 if(utp->tokenType != UA_USERTOKENTYPE_ANONYMOUS &&
40842 !(sc->allowNonePolicyPassword && utp->tokenType == UA_USERTOKENTYPE_USERNAME) &&
40843 UA_String_equal(p1: &ed->securityPolicyUri, p2: &UA_SECURITY_POLICY_NONE_URI)) {
40844 UA_SecurityPolicy *encSP = getDefaultEncryptedSecurityPolicy(server);
40845 if(!encSP) {
40846 /* No encrypted SecurityPolicy available */
40847 UA_LOG_WARNING(logger: sc->logging, category: UA_LOGCATEGORY_CLIENT,
40848 msg: "Removing a UserTokenPolicy that would allow the "
40849 "password to be transmitted without encryption "
40850 "(Can be enabled via config->allowNonePolicyPassword)");
40851 UA_StatusCode res2 =
40852 UA_Array_resize(p: (void **)&ed->userIdentityTokens,
40853 size: &ed->userIdentityTokensSize,
40854 newSize: ed->userIdentityTokensSize - 1,
40855 type: &UA_TYPES[UA_TYPES_USERTOKENPOLICY]);
40856 (void)res2;
40857 continue;
40858 }
40859 res |= UA_String_copy(src: &encSP->policyUri, dst: &utp->securityPolicyUri);
40860 }
40861#endif
40862
40863 /* Append the SecurityMode and SecurityPolicy postfix to the PolicyId to
40864 * make it unique */
40865 UA_String postfix;
40866 if(utp->securityPolicyUri.length > 0)
40867 postfix = securityPolicyUriPostfix(uri: utp->securityPolicyUri);
40868 else
40869 postfix = securityPolicyUriPostfix(uri: ed->securityPolicyUri);
40870 size_t newLen = utp->policyId.length + postfix.length +
40871 strlen(s: securityModeStrs[ed->securityMode]);
40872 UA_Byte *newString = (UA_Byte*)UA_realloc(ptr: utp->policyId.data, size: newLen);
40873 if(!newString)
40874 continue;
40875 size_t pos = utp->policyId.length;
40876 memcpy(dest: &newString[pos], src: securityModeStrs[ed->securityMode],
40877 n: strlen(s: securityModeStrs[ed->securityMode]));
40878 pos += strlen(s: securityModeStrs[ed->securityMode]);
40879 memcpy(dest: &newString[pos], src: postfix.data, n: postfix.length);
40880 utp->policyId.data = newString;
40881 utp->policyId.length = newLen;
40882 }
40883
40884 return res;
40885}
40886
40887/* Also reused to create the EndpointDescription array in the CreateSessionResponse */
40888UA_StatusCode
40889setCurrentEndPointsArray(UA_Server *server, const UA_String endpointUrl,
40890 UA_String *profileUris, size_t profileUrisSize,
40891 UA_EndpointDescription **arr, size_t *arrSize) {
40892 /* Clone the endpoint for each discoveryURL? */
40893 size_t clone_times = 1;
40894 if(endpointUrl.length == 0)
40895 clone_times = server->config.applicationDescription.discoveryUrlsSize;
40896
40897 /* Allocate the array */
40898 *arr = (UA_EndpointDescription*)
40899 UA_Array_new(size: server->config.endpointsSize * clone_times,
40900 type: &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
40901 if(!*arr)
40902 return UA_STATUSCODE_BADOUTOFMEMORY;
40903
40904 size_t pos = 0;
40905 UA_StatusCode retval = UA_STATUSCODE_GOOD;
40906 for(size_t j = 0; j < server->config.endpointsSize; ++j) {
40907 /* Test if the supported binary profile shall be returned */
40908 UA_Boolean usable = (profileUrisSize == 0);
40909 if(!usable) {
40910 for(size_t i = 0; i < profileUrisSize; ++i) {
40911 if(!UA_String_equal(p1: &profileUris[i], p2: &server->config.endpoints[j].transportProfileUri))
40912 continue;
40913 usable = true;
40914 break;
40915 }
40916 }
40917 if(!usable)
40918 continue;
40919
40920 /* Copy into the results */
40921 for(size_t i = 0; i < clone_times; ++i) {
40922 /* Copy the endpoint with a current ApplicationDescription */
40923 UA_EndpointDescription *ed = &(*arr)[pos];
40924 retval |= UA_EndpointDescription_copy(src: &server->config.endpoints[j], dst: ed);
40925 UA_ApplicationDescription_clear(p: &ed->server);
40926 retval |= UA_ApplicationDescription_copy(src: &server->config.applicationDescription,
40927 dst: &ed->server);
40928
40929 /* Return the certificate for the SecurityPolicy. If the
40930 * SecureChannel is unencrypted, select the default encrypted
40931 * SecurityPolicy. */
40932 UA_SecurityPolicy *sp = getSecurityPolicyByUri(server, securityPolicyUri: &ed->securityPolicyUri);
40933 if(!sp || UA_String_equal(p1: &UA_SECURITY_POLICY_NONE_URI, p2: &sp->policyUri))
40934 sp = getDefaultEncryptedSecurityPolicy(server);
40935 if(sp) {
40936 UA_ByteString_clear(p: &ed->serverCertificate);
40937 retval |= UA_String_copy(src: &sp->localCertificate, dst: &ed->serverCertificate);
40938 }
40939
40940 /* Set the User Identity Token list fromt the AccessControl plugin */
40941 retval |= updateEndpointUserIdentityToken(server, ed);
40942
40943 /* Set the EndpointURL */
40944 UA_String_clear(p: &ed->endpointUrl);
40945 if(endpointUrl.length == 0) {
40946 retval |= UA_String_copy(src: &server->config.applicationDescription.
40947 discoveryUrls[i], dst: &ed->endpointUrl);
40948 } else {
40949 /* Mirror back the requested EndpointUrl and also add it to the
40950 * array of discovery urls */
40951 retval |= UA_String_copy(src: &endpointUrl, dst: &ed->endpointUrl);
40952
40953 /* Check if the ServerUrl is already present in the DiscoveryUrl array */
40954 size_t k = 0;
40955 for(; k < ed->server.discoveryUrlsSize; k++) {
40956 if(UA_String_equal(p1: &ed->endpointUrl, p2: &ed->server.discoveryUrls[k]))
40957 break;
40958 }
40959 if(k == ed->server.discoveryUrlsSize) {
40960 retval |= UA_Array_appendCopy(
40961 p: (void **)&ed->server.discoveryUrls, size: &ed->server.discoveryUrlsSize,
40962 newElem: &endpointUrl, type: &UA_TYPES[UA_TYPES_STRING]);
40963 }
40964 }
40965 if(retval != UA_STATUSCODE_GOOD)
40966 goto error;
40967
40968 pos++;
40969 }
40970 }
40971
40972 *arrSize = pos;
40973 return UA_STATUSCODE_GOOD;
40974
40975 error:
40976 UA_Array_delete(p: *arr, size: server->config.endpointsSize * clone_times,
40977 type: &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
40978 *arr = NULL;
40979 return retval;
40980}
40981
40982void
40983Service_GetEndpoints(UA_Server *server, UA_Session *session,
40984 const UA_GetEndpointsRequest *request,
40985 UA_GetEndpointsResponse *response) {
40986 UA_LOCK_ASSERT(&server->serviceMutex, 1);
40987
40988 /* If the client expects to see a specific endpointurl, mirror it back. If
40989 * not, clone the endpoints with the discovery url of all networklayers. */
40990 if(request->endpointUrl.length > 0) {
40991 UA_LOG_DEBUG_SESSION(server->config.logging, session,
40992 "Processing GetEndpointsRequest with endpointUrl "
40993 UA_PRINTF_STRING_FORMAT, UA_PRINTF_STRING_DATA(request->endpointUrl));
40994 } else {
40995 UA_LOG_DEBUG_SESSION(server->config.logging, session,
40996 "Processing GetEndpointsRequest with an empty endpointUrl");
40997 }
40998
40999 response->responseHeader.serviceResult =
41000 setCurrentEndPointsArray(server, endpointUrl: request->endpointUrl,
41001 profileUris: request->profileUris, profileUrisSize: request->profileUrisSize,
41002 arr: &response->endpoints, arrSize: &response->endpointsSize);
41003}
41004
41005#ifdef UA_ENABLE_DISCOVERY
41006
41007static void
41008process_RegisterServer(UA_Server *server, UA_Session *session,
41009 const UA_RequestHeader* requestHeader,
41010 const UA_RegisteredServer *requestServer,
41011 const size_t requestDiscoveryConfigurationSize,
41012 const UA_ExtensionObject *requestDiscoveryConfiguration,
41013 UA_ResponseHeader* responseHeader,
41014 size_t *responseConfigurationResultsSize,
41015 UA_StatusCode **responseConfigurationResults,
41016 size_t *responseDiagnosticInfosSize,
41017 UA_DiagnosticInfo *responseDiagnosticInfos) {
41018 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41019
41020 UA_DiscoveryManager *dm = (UA_DiscoveryManager*)
41021 getServerComponentByName(server, name: UA_STRING(chars: "discovery"));
41022 if(!dm)
41023 return;
41024
41025 if(dm->serverConfig->applicationDescription.applicationType != UA_APPLICATIONTYPE_DISCOVERYSERVER) {
41026 responseHeader->serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED;
41027 return;
41028 }
41029
41030 /* Find the server from the request in the registered list */
41031 registeredServer_list_entry* current;
41032 registeredServer_list_entry *registeredServer_entry = NULL;
41033 LIST_FOREACH(current, &dm->registeredServers, pointers) {
41034 if(UA_String_equal(p1: &current->registeredServer.serverUri, p2: &requestServer->serverUri)) {
41035 registeredServer_entry = current;
41036 break;
41037 }
41038 }
41039
41040 UA_MdnsDiscoveryConfiguration *mdnsConfig = NULL;
41041
41042 const UA_String* mdnsServerName = NULL;
41043 if(requestDiscoveryConfigurationSize) {
41044 *responseConfigurationResults =
41045 (UA_StatusCode *)UA_Array_new(size: requestDiscoveryConfigurationSize,
41046 type: &UA_TYPES[UA_TYPES_STATUSCODE]);
41047 if(!(*responseConfigurationResults)) {
41048 responseHeader->serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
41049 return;
41050 }
41051 *responseConfigurationResultsSize = requestDiscoveryConfigurationSize;
41052
41053 for(size_t i = 0; i < requestDiscoveryConfigurationSize; i++) {
41054 const UA_ExtensionObject *object = &requestDiscoveryConfiguration[i];
41055 if(!mdnsConfig && (object->encoding == UA_EXTENSIONOBJECT_DECODED ||
41056 object->encoding == UA_EXTENSIONOBJECT_DECODED_NODELETE) &&
41057 (object->content.decoded.type == &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION])) {
41058 mdnsConfig = (UA_MdnsDiscoveryConfiguration *)object->content.decoded.data;
41059 mdnsServerName = &mdnsConfig->mdnsServerName;
41060 (*responseConfigurationResults)[i] = UA_STATUSCODE_GOOD;
41061 } else {
41062 (*responseConfigurationResults)[i] = UA_STATUSCODE_BADNOTSUPPORTED;
41063 }
41064 }
41065 }
41066
41067 if(!mdnsServerName && requestServer->serverNamesSize)
41068 mdnsServerName = &requestServer->serverNames[0].text;
41069
41070 if(!mdnsServerName) {
41071 responseHeader->serviceResult = UA_STATUSCODE_BADSERVERNAMEMISSING;
41072 return;
41073 }
41074
41075 if(requestServer->discoveryUrlsSize == 0) {
41076 responseHeader->serviceResult = UA_STATUSCODE_BADDISCOVERYURLMISSING;
41077 return;
41078 }
41079
41080 if(requestServer->semaphoreFilePath.length) {
41081#ifdef UA_ENABLE_DISCOVERY_SEMAPHORE
41082 char* filePath = (char*)
41083 UA_malloc(size: sizeof(char)*requestServer->semaphoreFilePath.length+1);
41084 if(!filePath) {
41085 UA_LOG_ERROR_SESSION(server->config.logging, session,
41086 "Cannot allocate memory for semaphore path. Out of memory.");
41087 responseHeader->serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
41088 return;
41089 }
41090 memcpy(dest: filePath, src: requestServer->semaphoreFilePath.data, n: requestServer->semaphoreFilePath.length );
41091 filePath[requestServer->semaphoreFilePath.length] = '\0';
41092 if(!UA_fileExists( filePath )) {
41093 responseHeader->serviceResult = UA_STATUSCODE_BADSEMPAHOREFILEMISSING;
41094 UA_free(ptr: filePath);
41095 return;
41096 }
41097 UA_free(ptr: filePath);
41098#else
41099 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_CLIENT,
41100 "Ignoring semaphore file path. open62541 not compiled "
41101 "with UA_ENABLE_DISCOVERY_SEMAPHORE=ON");
41102#endif
41103 }
41104
41105#ifdef UA_ENABLE_DISCOVERY_MULTICAST
41106 if(server->config.mdnsEnabled) {
41107 for(size_t i = 0; i < requestServer->discoveryUrlsSize; i++) {
41108 /* create TXT if is online and first index, delete TXT if is offline and last index */
41109 UA_Boolean updateTxt = (requestServer->isOnline && i==0) ||
41110 (!requestServer->isOnline && i==requestServer->discoveryUrlsSize);
41111 UA_Discovery_updateMdnsForDiscoveryUrl(dm, mdnsServerName, mdnsConfig,
41112 &requestServer->discoveryUrls[i],
41113 requestServer->isOnline, updateTxt);
41114 }
41115 }
41116#endif
41117
41118 if(!requestServer->isOnline) {
41119 // server is shutting down. Remove it from the registered servers list
41120 if(!registeredServer_entry) {
41121 // server not found, show warning
41122 UA_LOG_WARNING_SESSION(server->config.logging, session,
41123 "Could not unregister server %.*s. Not registered.",
41124 (int)requestServer->serverUri.length, requestServer->serverUri.data);
41125 responseHeader->serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
41126 return;
41127 }
41128
41129 if(dm->registerServerCallback)
41130 dm->registerServerCallback(requestServer, dm->registerServerCallbackData);
41131
41132 // server found, remove from list
41133 LIST_REMOVE(registeredServer_entry, pointers);
41134 UA_RegisteredServer_clear(p: &registeredServer_entry->registeredServer);
41135 UA_free(ptr: registeredServer_entry);
41136 dm->registeredServersSize--;
41137 responseHeader->serviceResult = UA_STATUSCODE_GOOD;
41138 return;
41139 }
41140
41141 UA_StatusCode retval = UA_STATUSCODE_GOOD;
41142 if(!registeredServer_entry) {
41143 // server not yet registered, register it by adding it to the list
41144 UA_LOG_DEBUG_SESSION(server->config.logging, session, "Registering new server: %.*s",
41145 (int)requestServer->serverUri.length, requestServer->serverUri.data);
41146
41147 registeredServer_entry =
41148 (registeredServer_list_entry *)UA_malloc(size: sizeof(registeredServer_list_entry));
41149 if(!registeredServer_entry) {
41150 responseHeader->serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
41151 return;
41152 }
41153
41154 LIST_INSERT_HEAD(&dm->registeredServers,
41155 registeredServer_entry, pointers);
41156 dm->registeredServersSize++;
41157 } else {
41158 UA_RegisteredServer_clear(p: &registeredServer_entry->registeredServer);
41159 }
41160
41161 // Always call the callback, if it is set.
41162 // Previously we only called it if it was a new register call. It may be the case that this endpoint
41163 // registered before, then crashed, restarts and registeres again. In that case the entry is not deleted
41164 // and the callback would not be called.
41165 if(dm->registerServerCallback)
41166 dm->registerServerCallback(requestServer, dm->registerServerCallbackData);
41167
41168 // copy the data from the request into the list
41169 UA_RegisteredServer_copy(src: requestServer, dst: &registeredServer_entry->registeredServer);
41170 registeredServer_entry->lastSeen = UA_DateTime_nowMonotonic();
41171 responseHeader->serviceResult = retval;
41172}
41173
41174void Service_RegisterServer(UA_Server *server, UA_Session *session,
41175 const UA_RegisterServerRequest *request,
41176 UA_RegisterServerResponse *response) {
41177 UA_LOG_DEBUG_SESSION(server->config.logging, session,
41178 "Processing RegisterServerRequest");
41179 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41180 process_RegisterServer(server, session, requestHeader: &request->requestHeader, requestServer: &request->server, requestDiscoveryConfigurationSize: 0,
41181 NULL, responseHeader: &response->responseHeader, responseConfigurationResultsSize: 0, NULL, responseDiagnosticInfosSize: 0, NULL);
41182}
41183
41184void Service_RegisterServer2(UA_Server *server, UA_Session *session,
41185 const UA_RegisterServer2Request *request,
41186 UA_RegisterServer2Response *response) {
41187 UA_LOG_DEBUG_SESSION(server->config.logging, session,
41188 "Processing RegisterServer2Request");
41189 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41190 process_RegisterServer(server, session, requestHeader: &request->requestHeader, requestServer: &request->server,
41191 requestDiscoveryConfigurationSize: request->discoveryConfigurationSize, requestDiscoveryConfiguration: request->discoveryConfiguration,
41192 responseHeader: &response->responseHeader, responseConfigurationResultsSize: &response->configurationResultsSize,
41193 responseConfigurationResults: &response->configurationResults, responseDiagnosticInfosSize: &response->diagnosticInfosSize,
41194 responseDiagnosticInfos: response->diagnosticInfos);
41195}
41196
41197#endif /* UA_ENABLE_DISCOVERY */
41198
41199/**** amalgamated original file "/src/server/ua_services_subscription.c" ****/
41200
41201/* This Source Code Form is subject to the terms of the Mozilla Public
41202 * License, v. 2.0. If a copy of the MPL was not distributed with this
41203 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
41204 *
41205 * Copyright 2014-2018, 2022 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
41206 * Copyright 2016-2017 (c) Florian Palm
41207 * Copyright 2015 (c) Chris Iatrou
41208 * Copyright 2015-2016 (c) Sten Grüner
41209 * Copyright 2015-2016 (c) Oleksiy Vasylyev
41210 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
41211 * Copyright 2018 (c) Ari Breitkreuz, fortiss GmbH
41212 * Copyright 2017 (c) Mattias Bornhager
41213 * Copyright 2017 (c) Henrik Norrman
41214 * Copyright 2017-2018 (c) Thomas Stalder, Blue Time Concept SA
41215 * Copyright 2018 (c) Fabian Arndt, Root-Core
41216 * Copyright 2017-2019 (c) HMS Industrial Networks AB (Author: Jonas Green)
41217 */
41218
41219
41220#ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */
41221
41222static void
41223setSubscriptionSettings(UA_Server *server, UA_Subscription *subscription,
41224 UA_Double requestedPublishingInterval,
41225 UA_UInt32 requestedLifetimeCount,
41226 UA_UInt32 requestedMaxKeepAliveCount,
41227 UA_UInt32 maxNotificationsPerPublish,
41228 UA_Byte priority) {
41229 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41230
41231 /* re-parameterize the subscription */
41232 UA_BOUNDEDVALUE_SETWBOUNDS(server->config.publishingIntervalLimits,
41233 requestedPublishingInterval,
41234 subscription->publishingInterval);
41235 /* check for nan*/
41236 if(requestedPublishingInterval != requestedPublishingInterval)
41237 subscription->publishingInterval = server->config.publishingIntervalLimits.min;
41238 UA_BOUNDEDVALUE_SETWBOUNDS(server->config.keepAliveCountLimits,
41239 requestedMaxKeepAliveCount, subscription->maxKeepAliveCount);
41240 UA_BOUNDEDVALUE_SETWBOUNDS(server->config.lifeTimeCountLimits,
41241 requestedLifetimeCount, subscription->lifeTimeCount);
41242 if(subscription->lifeTimeCount < 3 * subscription->maxKeepAliveCount)
41243 subscription->lifeTimeCount = 3 * subscription->maxKeepAliveCount;
41244 subscription->notificationsPerPublish = maxNotificationsPerPublish;
41245 if(maxNotificationsPerPublish == 0 ||
41246 maxNotificationsPerPublish > server->config.maxNotificationsPerPublish)
41247 subscription->notificationsPerPublish = server->config.maxNotificationsPerPublish;
41248 subscription->priority = priority;
41249}
41250
41251void
41252Service_CreateSubscription(UA_Server *server, UA_Session *session,
41253 const UA_CreateSubscriptionRequest *request,
41254 UA_CreateSubscriptionResponse *response) {
41255 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41256
41257 /* Check limits for the number of subscriptions */
41258 if(((server->config.maxSubscriptions != 0) &&
41259 (server->subscriptionsSize >= server->config.maxSubscriptions)) ||
41260 ((server->config.maxSubscriptionsPerSession != 0) &&
41261 (session->subscriptionsSize >= server->config.maxSubscriptionsPerSession))) {
41262 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYSUBSCRIPTIONS;
41263 return;
41264 }
41265
41266 /* Create the subscription */
41267 UA_Subscription *sub = UA_Subscription_new();
41268 if(!sub) {
41269 UA_LOG_DEBUG_SESSION(server->config.logging, session,
41270 "Processing CreateSubscriptionRequest failed");
41271 response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
41272 return;
41273 }
41274
41275 /* Set the subscription parameters */
41276 setSubscriptionSettings(server, subscription: sub, requestedPublishingInterval: request->requestedPublishingInterval,
41277 requestedLifetimeCount: request->requestedLifetimeCount,
41278 requestedMaxKeepAliveCount: request->requestedMaxKeepAliveCount,
41279 maxNotificationsPerPublish: request->maxNotificationsPerPublish, priority: request->priority);
41280 sub->subscriptionId = ++server->lastSubscriptionId; /* Assign the SubscriptionId */
41281
41282 /* Register the subscription in the server */
41283 LIST_INSERT_HEAD(&server->subscriptions, sub, serverListEntry);
41284 server->subscriptionsSize++;
41285
41286 /* Update the server statistics */
41287 server->serverDiagnosticsSummary.currentSubscriptionCount++;
41288 server->serverDiagnosticsSummary.cumulatedSubscriptionCount++;
41289
41290 /* Attach the Subscription to the session */
41291 UA_Session_attachSubscription(session, sub);
41292
41293 /* Create representation in the Session object */
41294#ifdef UA_ENABLE_DIAGNOSTICS
41295 createSubscriptionObject(server, session, sub);
41296#endif
41297
41298 /* Set the subscription state. This also registers the callback.
41299 * Note that also a disabled subscription publishes keepalives. */
41300 UA_SubscriptionState sState = (request->publishingEnabled) ?
41301 UA_SUBSCRIPTIONSTATE_ENABLED : UA_SUBSCRIPTIONSTATE_ENABLED_NOPUBLISH;
41302 UA_StatusCode res = Subscription_setState(server, sub, state: sState);
41303 if(res != UA_STATUSCODE_GOOD) {
41304 UA_LOG_DEBUG_SESSION(server->config.logging, sub->session,
41305 "Subscription %" PRIu32 " | Could not register "
41306 "publish callback with error code %s",
41307 sub->subscriptionId, UA_StatusCode_name(res));
41308 response->responseHeader.serviceResult = res;
41309 UA_Subscription_delete(server, sub);
41310 return;
41311 }
41312
41313 UA_LOG_INFO_SUBSCRIPTION(server->config.logging, sub,
41314 "Subscription created (Publishing interval %.2fms, "
41315 "max %lu notifications per publish)",
41316 sub->publishingInterval,
41317 (long unsigned)sub->notificationsPerPublish);
41318
41319 /* Prepare the response */
41320 response->subscriptionId = sub->subscriptionId;
41321 response->revisedPublishingInterval = sub->publishingInterval;
41322 response->revisedLifetimeCount = sub->lifeTimeCount;
41323 response->revisedMaxKeepAliveCount = sub->maxKeepAliveCount;
41324}
41325
41326void
41327Service_ModifySubscription(UA_Server *server, UA_Session *session,
41328 const UA_ModifySubscriptionRequest *request,
41329 UA_ModifySubscriptionResponse *response) {
41330 UA_LOG_DEBUG_SESSION(server->config.logging, session,
41331 "Processing ModifySubscriptionRequest");
41332 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41333
41334 UA_Subscription *sub = UA_Session_getSubscriptionById(session, subscriptionId: request->subscriptionId);
41335 if(!sub) {
41336 response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
41337 return;
41338 }
41339
41340 /* Store the old publishing interval */
41341 UA_Double oldPublishingInterval = sub->publishingInterval;
41342 UA_Byte oldPriority = sub->priority;
41343
41344 /* Change the Subscription settings */
41345 setSubscriptionSettings(server, subscription: sub, requestedPublishingInterval: request->requestedPublishingInterval,
41346 requestedLifetimeCount: request->requestedLifetimeCount,
41347 requestedMaxKeepAliveCount: request->requestedMaxKeepAliveCount,
41348 maxNotificationsPerPublish: request->maxNotificationsPerPublish, priority: request->priority);
41349
41350 /* Reset the subscription lifetime */
41351 Subscription_resetLifetime(sub);
41352
41353 /* The publish interval has changed */
41354 if(sub->publishingInterval != oldPublishingInterval) {
41355 /* Change the repeated callback to the new interval. This cannot fail as
41356 * memory is reused. */
41357 if(sub->publishCallbackId > 0)
41358 changeRepeatedCallbackInterval(server, callbackId: sub->publishCallbackId,
41359 interval_ms: sub->publishingInterval);
41360
41361 /* For each MonitoredItem check if it was/shall be attached to the
41362 * publish interval. This ensures that we have less cyclic callbacks
41363 * registered and that the notifications are fresh. */
41364 UA_MonitoredItem *mon;
41365 LIST_FOREACH(mon, &sub->monitoredItems, listEntry) {
41366 if(mon->parameters.samplingInterval == sub->publishingInterval ||
41367 mon->parameters.samplingInterval == oldPublishingInterval) {
41368 UA_MonitoredItem_unregisterSampling(server, mon);
41369 UA_MonitoredItem_registerSampling(server, mon);
41370 }
41371 }
41372 }
41373
41374 /* If the priority has changed, re-enter the subscription to the
41375 * priority-ordered queue in the session. */
41376 if(oldPriority != sub->priority) {
41377 UA_Session_detachSubscription(server, session, sub, false);
41378 UA_Session_attachSubscription(session, sub);
41379 }
41380
41381 /* Set the response */
41382 response->revisedPublishingInterval = sub->publishingInterval;
41383 response->revisedLifetimeCount = sub->lifeTimeCount;
41384 response->revisedMaxKeepAliveCount = sub->maxKeepAliveCount;
41385
41386 /* Update the diagnostics statistics */
41387#ifdef UA_ENABLE_DIAGNOSTICS
41388 sub->modifyCount++;
41389#endif
41390}
41391
41392static void
41393Operation_SetPublishingMode(UA_Server *server, UA_Session *session,
41394 const UA_Boolean *publishingEnabled,
41395 const UA_UInt32 *subscriptionId,
41396 UA_StatusCode *result) {
41397 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41398 UA_Subscription *sub = UA_Session_getSubscriptionById(session, subscriptionId: *subscriptionId);
41399 if(!sub) {
41400 *result = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
41401 return;
41402 }
41403
41404 /* Enable/disable */
41405 UA_SubscriptionState sState = (*publishingEnabled) ?
41406 UA_SUBSCRIPTIONSTATE_ENABLED : UA_SUBSCRIPTIONSTATE_ENABLED_NOPUBLISH;
41407 *result = Subscription_setState(server, sub, state: sState);
41408
41409 /* Reset the lifetime counter */
41410 Subscription_resetLifetime(sub);
41411}
41412
41413void
41414Service_SetPublishingMode(UA_Server *server, UA_Session *session,
41415 const UA_SetPublishingModeRequest *request,
41416 UA_SetPublishingModeResponse *response) {
41417 UA_LOG_DEBUG_SESSION(server->config.logging, session,
41418 "Processing SetPublishingModeRequest");
41419 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41420
41421 UA_Boolean publishingEnabled = request->publishingEnabled; /* request is const */
41422 response->responseHeader.serviceResult =
41423 UA_Server_processServiceOperations(server, session,
41424 operationCallback: (UA_ServiceOperation)Operation_SetPublishingMode,
41425 context: &publishingEnabled,
41426 requestOperations: &request->subscriptionIdsSize,
41427 requestOperationsType: &UA_TYPES[UA_TYPES_UINT32],
41428 responseOperations: &response->resultsSize,
41429 responseOperationsType: &UA_TYPES[UA_TYPES_STATUSCODE]);
41430}
41431
41432UA_StatusCode
41433Service_Publish(UA_Server *server, UA_Session *session,
41434 const UA_PublishRequest *request, UA_UInt32 requestId) {
41435 UA_LOG_DEBUG_SESSION(server->config.logging, session,
41436 "Processing PublishRequest with RequestId %u", requestId);
41437 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41438
41439 /* Return an error if the session has no subscription */
41440 if(TAILQ_EMPTY(&session->subscriptions)) {
41441 sendServiceFault(channel: session->header.channel, requestId,
41442 requestHandle: request->requestHeader.requestHandle,
41443 UA_STATUSCODE_BADNOSUBSCRIPTION);
41444 return UA_STATUSCODE_BADNOSUBSCRIPTION;
41445 }
41446
41447 /* Handle too many subscriptions to free resources before trying to allocate
41448 * resources for the new publish request. If the limit has been reached the
41449 * oldest publish request are returned with an error message. */
41450 UA_Session_ensurePublishQueueSpace(server, session);
41451
41452 /* Allocate the response to store it in the retransmission queue */
41453 UA_PublishResponseEntry *entry = (UA_PublishResponseEntry *)
41454 UA_malloc(size: sizeof(UA_PublishResponseEntry));
41455 if(!entry) {
41456 sendServiceFault(channel: session->header.channel, requestId,
41457 requestHandle: request->requestHeader.requestHandle,
41458 UA_STATUSCODE_BADOUTOFMEMORY);
41459 return UA_STATUSCODE_BADOUTOFMEMORY;
41460 }
41461
41462 /* Prepare the response */
41463 entry->requestId = requestId;
41464 UA_PublishResponse *response = &entry->response;
41465 UA_PublishResponse_init(p: response);
41466 response->responseHeader.requestHandle = request->requestHeader.requestHandle;
41467
41468 /* Allocate the results array to acknowledge the acknowledge */
41469 if(request->subscriptionAcknowledgementsSize > 0) {
41470 response->results = (UA_StatusCode *)
41471 UA_Array_new(size: request->subscriptionAcknowledgementsSize,
41472 type: &UA_TYPES[UA_TYPES_STATUSCODE]);
41473 if(!response->results) {
41474 UA_free(ptr: entry);
41475 sendServiceFault(channel: session->header.channel, requestId,
41476 requestHandle: request->requestHeader.requestHandle,
41477 UA_STATUSCODE_BADOUTOFMEMORY);
41478 return UA_STATUSCODE_BADOUTOFMEMORY;
41479 }
41480 response->resultsSize = request->subscriptionAcknowledgementsSize;
41481 }
41482
41483 /* <--- A good StatusCode is returned from here on ---> */
41484
41485 /* Delete Acknowledged Subscription Messages */
41486 for(size_t i = 0; i < request->subscriptionAcknowledgementsSize; ++i) {
41487 UA_SubscriptionAcknowledgement *ack = &request->subscriptionAcknowledgements[i];
41488 UA_Subscription *sub = UA_Session_getSubscriptionById(session, subscriptionId: ack->subscriptionId);
41489 if(!sub) {
41490 response->results[i] = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
41491 UA_LOG_DEBUG_SESSION(server->config.logging, session,
41492 "Cannot process acknowledgements subscription %u" PRIu32,
41493 ack->subscriptionId);
41494 continue;
41495 }
41496 /* Remove the acked transmission from the retransmission queue */
41497 response->results[i] =
41498 UA_Subscription_removeRetransmissionMessage(sub, sequenceNumber: ack->sequenceNumber);
41499 }
41500
41501 /* Set the maxTime if a timeout hint is defined */
41502 entry->maxTime = UA_INT64_MAX;
41503 if(request->requestHeader.timeoutHint > 0) {
41504 UA_EventLoop *el = server->config.eventLoop;
41505 entry->maxTime = el->dateTime_nowMonotonic(el) +
41506 (request->requestHeader.timeoutHint * UA_DATETIME_MSEC);
41507 }
41508
41509 /* Queue the publish response. It will be dequeued in a repeated publish
41510 * callback. This can also be triggered right now for a late
41511 * subscription. */
41512 UA_Session_queuePublishReq(session, entry, false);
41513 UA_LOG_DEBUG_SESSION(server->config.logging, session, "Queued a publication message");
41514
41515 /* If there are late subscriptions, the new publish request is used to
41516 * answer them immediately. Late subscriptions with higher priority are
41517 * considered earlier. However, a single subscription that generates many
41518 * notifications must not "starve" other late subscriptions. Hence we move
41519 * it to the end of the queue for the subscriptions of that priority. */
41520 UA_Subscription *late, *late_tmp;
41521 TAILQ_FOREACH_SAFE(late, &session->subscriptions, sessionListEntry, late_tmp) {
41522 /* Skip non-late subscriptions */
41523 if(!late->late)
41524 continue;
41525
41526 /* Call publish on the late subscription */
41527 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, late,
41528 "Send PublishResponse on a late subscription");
41529 UA_Subscription_publish(server, sub: late);
41530
41531 /* Skip re-insert if the subscription was deleted or deactivated during
41532 * _publish */
41533 if(late->state >= UA_SUBSCRIPTIONSTATE_ENABLED_NOPUBLISH) {
41534 /* Find the first element with smaller priority and insert before
41535 * that. If there is none, insert at the end of the queue. */
41536 UA_Subscription *after = TAILQ_NEXT(late, sessionListEntry);
41537 while(after && after->priority >= late->priority)
41538 after = TAILQ_NEXT(after, sessionListEntry);
41539 TAILQ_REMOVE(&session->subscriptions, late, sessionListEntry);
41540 if(after)
41541 TAILQ_INSERT_BEFORE(after, late, sessionListEntry);
41542 else
41543 TAILQ_INSERT_TAIL(&session->subscriptions, late, sessionListEntry);
41544 }
41545
41546 /* Responses left in the queue? */
41547 if(session->responseQueueSize == 0)
41548 break;
41549 }
41550
41551 return UA_STATUSCODE_GOOD;
41552}
41553
41554static void
41555Operation_DeleteSubscription(UA_Server *server, UA_Session *session, void *_,
41556 const UA_UInt32 *subscriptionId, UA_StatusCode *result) {
41557 UA_Subscription *sub = UA_Session_getSubscriptionById(session, subscriptionId: *subscriptionId);
41558 if(!sub) {
41559 *result = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
41560 UA_LOG_DEBUG_SESSION(server->config.logging, session,
41561 "Deleting Subscription with Id %" PRIu32
41562 " failed with error code %s",
41563 *subscriptionId, UA_StatusCode_name(*result));
41564 return;
41565 }
41566
41567 UA_Subscription_delete(server, sub);
41568 *result = UA_STATUSCODE_GOOD;
41569 UA_LOG_DEBUG_SESSION(server->config.logging, session,
41570 "Subscription %" PRIu32 " | Subscription deleted",
41571 *subscriptionId);
41572}
41573
41574void
41575Service_DeleteSubscriptions(UA_Server *server, UA_Session *session,
41576 const UA_DeleteSubscriptionsRequest *request,
41577 UA_DeleteSubscriptionsResponse *response) {
41578 UA_LOG_DEBUG_SESSION(server->config.logging, session,
41579 "Processing DeleteSubscriptionsRequest");
41580 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41581
41582 response->responseHeader.serviceResult =
41583 UA_Server_processServiceOperations(server, session,
41584 operationCallback: (UA_ServiceOperation)Operation_DeleteSubscription, NULL,
41585 requestOperations: &request->subscriptionIdsSize, requestOperationsType: &UA_TYPES[UA_TYPES_UINT32],
41586 responseOperations: &response->resultsSize, responseOperationsType: &UA_TYPES[UA_TYPES_STATUSCODE]);
41587}
41588
41589void
41590Service_Republish(UA_Server *server, UA_Session *session,
41591 const UA_RepublishRequest *request,
41592 UA_RepublishResponse *response) {
41593 UA_LOG_DEBUG_SESSION(server->config.logging, session,
41594 "Processing RepublishRequest");
41595 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41596
41597 /* Get the subscription */
41598 UA_Subscription *sub = UA_Session_getSubscriptionById(session, subscriptionId: request->subscriptionId);
41599 if(!sub) {
41600 response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
41601 return;
41602 }
41603
41604 /* Reset the lifetime counter */
41605 Subscription_resetLifetime(sub);
41606
41607 /* Update the subscription statistics */
41608#ifdef UA_ENABLE_DIAGNOSTICS
41609 sub->republishRequestCount++;
41610#endif
41611
41612 /* Find the notification in the retransmission queue */
41613 UA_NotificationMessageEntry *entry;
41614 TAILQ_FOREACH(entry, &sub->retransmissionQueue, listEntry) {
41615 if(entry->message.sequenceNumber == request->retransmitSequenceNumber)
41616 break;
41617 }
41618 if(!entry) {
41619 response->responseHeader.serviceResult = UA_STATUSCODE_BADMESSAGENOTAVAILABLE;
41620 return;
41621 }
41622
41623 response->responseHeader.serviceResult =
41624 UA_NotificationMessage_copy(src: &entry->message, dst: &response->notificationMessage);
41625
41626 /* Update the subscription statistics for the case where we return a message */
41627#ifdef UA_ENABLE_DIAGNOSTICS
41628 sub->republishMessageCount++;
41629#endif
41630}
41631
41632static UA_StatusCode
41633setTransferredSequenceNumbers(const UA_Subscription *sub, UA_TransferResult *result) {
41634 /* Allocate memory */
41635 result->availableSequenceNumbers = (UA_UInt32*)
41636 UA_Array_new(size: sub->retransmissionQueueSize, type: &UA_TYPES[UA_TYPES_UINT32]);
41637 if(!result->availableSequenceNumbers)
41638 return UA_STATUSCODE_BADOUTOFMEMORY;
41639 result->availableSequenceNumbersSize = sub->retransmissionQueueSize;
41640
41641 /* Copy over the sequence numbers */
41642 UA_NotificationMessageEntry *entry;
41643 size_t i = 0;
41644 TAILQ_FOREACH(entry, &sub->retransmissionQueue, listEntry) {
41645 result->availableSequenceNumbers[i] = entry->message.sequenceNumber;
41646 i++;
41647 }
41648
41649 UA_assert(i == result->availableSequenceNumbersSize);
41650
41651 return UA_STATUSCODE_GOOD;
41652}
41653
41654static void
41655Operation_TransferSubscription(UA_Server *server, UA_Session *session,
41656 const UA_Boolean *sendInitialValues,
41657 const UA_UInt32 *subscriptionId,
41658 UA_TransferResult *result) {
41659 /* Get the subscription. This requires a server-wide lookup instead of the
41660 * usual session-wide lookup. */
41661 UA_Subscription *sub = getSubscriptionById(server, subscriptionId: *subscriptionId);
41662 if(!sub) {
41663 result->statusCode = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
41664 return;
41665 }
41666
41667 /* Update the diagnostics statistics */
41668#ifdef UA_ENABLE_DIAGNOSTICS
41669 sub->transferRequestCount++;
41670#endif
41671
41672 /* Is this the same session? Return the sequence numbers and do nothing else. */
41673 UA_Session *oldSession = sub->session;
41674 if(oldSession == session) {
41675 result->statusCode = setTransferredSequenceNumbers(sub, result);
41676#ifdef UA_ENABLE_DIAGNOSTICS
41677 sub->transferredToSameClientCount++;
41678#endif
41679 return;
41680 }
41681
41682 /* Check with AccessControl if the transfer is allowed */
41683 if(server->config.accessControl.allowTransferSubscription) {
41684 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41685 if(!server->config.accessControl.
41686 allowTransferSubscription(server, &server->config.accessControl,
41687 oldSession ? &oldSession->sessionId : NULL,
41688 oldSession ? oldSession->sessionHandle : NULL,
41689 &session->sessionId, session->sessionHandle)) {
41690 result->statusCode = UA_STATUSCODE_BADUSERACCESSDENIED;
41691 return;
41692 }
41693 } else {
41694 result->statusCode = UA_STATUSCODE_BADUSERACCESSDENIED;
41695 return;
41696 }
41697
41698 /* Check limits for the number of subscriptions for this Session */
41699 if((server->config.maxSubscriptionsPerSession != 0) &&
41700 (session->subscriptionsSize >= server->config.maxSubscriptionsPerSession)) {
41701 result->statusCode = UA_STATUSCODE_BADTOOMANYSUBSCRIPTIONS;
41702 return;
41703 }
41704
41705 /* Allocate memory for the new subscription */
41706 UA_Subscription *newSub = (UA_Subscription*)UA_malloc(size: sizeof(UA_Subscription));
41707 if(!newSub) {
41708 result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
41709 return;
41710 }
41711
41712 /* Set the available sequence numbers */
41713 result->statusCode = setTransferredSequenceNumbers(sub, result);
41714 if(result->statusCode != UA_STATUSCODE_GOOD) {
41715 UA_free(ptr: newSub);
41716 return;
41717 }
41718
41719 /* Create an identical copy of the Subscription struct. The original
41720 * subscription remains in place until a StatusChange notification has been
41721 * sent. The elements for lists and queues are moved over manually to ensure
41722 * that all backpointers are set correctly. */
41723 memcpy(dest: newSub, src: sub, n: sizeof(UA_Subscription));
41724
41725 /* Set to the same state as the original subscription */
41726 newSub->publishCallbackId = 0;
41727 result->statusCode = Subscription_setState(server, sub: newSub, state: sub->state);
41728 if(result->statusCode != UA_STATUSCODE_GOOD) {
41729 UA_Array_delete(p: result->availableSequenceNumbers,
41730 size: sub->retransmissionQueueSize, type: &UA_TYPES[UA_TYPES_UINT32]);
41731 result->availableSequenceNumbers = NULL;
41732 result->availableSequenceNumbersSize = 0;
41733 UA_free(ptr: newSub);
41734 return;
41735 }
41736
41737 /* <-- The point of no return --> */
41738
41739 /* Move over the MonitoredItems and adjust the backpointers */
41740 LIST_INIT(&newSub->monitoredItems);
41741 UA_MonitoredItem *mon, *mon_tmp;
41742 LIST_FOREACH_SAFE(mon, &sub->monitoredItems, listEntry, mon_tmp) {
41743 LIST_REMOVE(mon, listEntry);
41744 mon->subscription = newSub;
41745 LIST_INSERT_HEAD(&newSub->monitoredItems, mon, listEntry);
41746 }
41747 sub->monitoredItemsSize = 0;
41748
41749 /* Move over the notification queue */
41750 TAILQ_INIT(&newSub->notificationQueue);
41751 UA_Notification *nn, *nn_tmp;
41752 TAILQ_FOREACH_SAFE(nn, &sub->notificationQueue, globalEntry, nn_tmp) {
41753 TAILQ_REMOVE(&sub->notificationQueue, nn, globalEntry);
41754 TAILQ_INSERT_TAIL(&newSub->notificationQueue, nn, globalEntry);
41755 }
41756 sub->notificationQueueSize = 0;
41757 sub->dataChangeNotifications = 0;
41758 sub->eventNotifications = 0;
41759
41760 TAILQ_INIT(&newSub->retransmissionQueue);
41761 UA_NotificationMessageEntry *nme, *nme_tmp;
41762 TAILQ_FOREACH_SAFE(nme, &sub->retransmissionQueue, listEntry, nme_tmp) {
41763 TAILQ_REMOVE(&sub->retransmissionQueue, nme, listEntry);
41764 TAILQ_INSERT_TAIL(&newSub->retransmissionQueue, nme, listEntry);
41765 if(oldSession)
41766 oldSession->totalRetransmissionQueueSize -= 1;
41767 sub->retransmissionQueueSize -= 1;
41768 }
41769 UA_assert(sub->retransmissionQueueSize == 0);
41770 sub->retransmissionQueueSize = 0;
41771
41772 /* Add to the server */
41773 UA_assert(newSub->subscriptionId == sub->subscriptionId);
41774 LIST_INSERT_HEAD(&server->subscriptions, newSub, serverListEntry);
41775 server->subscriptionsSize++;
41776
41777 /* Attach to the session */
41778 UA_Session_attachSubscription(session, sub: newSub);
41779
41780 UA_LOG_INFO_SUBSCRIPTION(server->config.logging, newSub, "Transferred to this Session");
41781
41782 /* Set StatusChange in the original subscription and force publish. This
41783 * also removes the Subscription, even if there was no PublishResponse
41784 * queued to send a StatusChangeNotification. */
41785 sub->statusChange = UA_STATUSCODE_GOODSUBSCRIPTIONTRANSFERRED;
41786 UA_Subscription_publish(server, sub);
41787
41788 /* Re-create notifications with the current values for the new subscription */
41789 if(*sendInitialValues)
41790 UA_Subscription_resendData(server, sub: newSub);
41791
41792 /* Do not update the statistics for the number of Subscriptions here. The
41793 * fact that we duplicate the subscription and move over the content is just
41794 * an implementtion detail.
41795 * server->serverDiagnosticsSummary.currentSubscriptionCount++;
41796 * server->serverDiagnosticsSummary.cumulatedSubscriptionCount++;
41797 *
41798 * Update the diagnostics statistics: */
41799#ifdef UA_ENABLE_DIAGNOSTICS
41800 if(oldSession &&
41801 UA_equal(p1: &oldSession->clientDescription, p2: &session->clientDescription,
41802 type: &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]))
41803 sub->transferredToSameClientCount++;
41804 else
41805 sub->transferredToAltClientCount++;
41806#endif
41807}
41808
41809void Service_TransferSubscriptions(UA_Server *server, UA_Session *session,
41810 const UA_TransferSubscriptionsRequest *request,
41811 UA_TransferSubscriptionsResponse *response) {
41812 UA_LOG_DEBUG_SESSION(server->config.logging, session,
41813 "Processing TransferSubscriptionsRequest");
41814 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41815
41816 response->responseHeader.serviceResult =
41817 UA_Server_processServiceOperations(server, session,
41818 operationCallback: (UA_ServiceOperation)Operation_TransferSubscription,
41819 context: &request->sendInitialValues,
41820 requestOperations: &request->subscriptionIdsSize, requestOperationsType: &UA_TYPES[UA_TYPES_UINT32],
41821 responseOperations: &response->resultsSize, responseOperationsType: &UA_TYPES[UA_TYPES_TRANSFERRESULT]);
41822}
41823
41824#endif /* UA_ENABLE_SUBSCRIPTIONS */
41825
41826/**** amalgamated original file "/src/server/ua_services_monitoreditem.c" ****/
41827
41828/* This Source Code Form is subject to the terms of the Mozilla Public
41829 * License, v. 2.0. If a copy of the MPL was not distributed with this
41830 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
41831 *
41832 * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
41833 * Copyright 2016-2017 (c) Florian Palm
41834 * Copyright 2015 (c) Chris Iatrou
41835 * Copyright 2015-2016 (c) Sten Grüner
41836 * Copyright 2015-2016 (c) Oleksiy Vasylyev
41837 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
41838 * Copyright 2018 (c) Ari Breitkreuz, fortiss GmbH
41839 * Copyright 2017 (c) Mattias Bornhager
41840 * Copyright 2017 (c) Henrik Norrman
41841 * Copyright 2017-2023 (c) Thomas Stalder, Blue Time Concept SA
41842 * Copyright 2018 (c) Fabian Arndt, Root-Core
41843 * Copyright 2020 (c) Kalycito Infotech Private Limited
41844 * Copyright 2021 (c) Uranik, Berisha
41845 * Copyright 2021 (c) Ammar, Morshed
41846 * Copyright 2021 (c) Fraunhofer IOSB (Author: Andreas Ebner)
41847 */
41848
41849
41850#ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */
41851
41852#ifdef UA_ENABLE_DA
41853
41854/* Translate a percentage deadband into an absolute deadband based on the
41855 * UARange property of the variable */
41856static UA_StatusCode
41857setAbsoluteFromPercentageDeadband(UA_Server *server, UA_Session *session,
41858 const UA_MonitoredItem *mon, UA_DataChangeFilter *filter) {
41859 /* A valid deadband? */
41860 if(filter->deadbandValue < 0.0 || filter->deadbandValue > 100.0)
41861 return UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED;
41862
41863 /* Browse for the percent range */
41864 UA_QualifiedName qn = UA_QUALIFIEDNAME(nsIndex: 0, chars: "EURange");
41865 UA_BrowsePathResult bpr =
41866 browseSimplifiedBrowsePath(server, origin: mon->itemToMonitor.nodeId, browsePathSize: 1, browsePath: &qn);
41867 if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) {
41868 UA_BrowsePathResult_clear(p: &bpr);
41869 return UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED;
41870 }
41871
41872 /* Read the range */
41873 UA_ReadValueId rvi;
41874 UA_ReadValueId_init(p: &rvi);
41875 rvi.nodeId = bpr.targets->targetId.nodeId;
41876 rvi.attributeId = UA_ATTRIBUTEID_VALUE;
41877 UA_DataValue rangeVal = readWithSession(server, session, item: &rvi,
41878 timestampsToReturn: UA_TIMESTAMPSTORETURN_NEITHER);
41879 UA_BrowsePathResult_clear(p: &bpr);
41880 if(!UA_Variant_isScalar(v: &rangeVal.value) ||
41881 rangeVal.value.type != &UA_TYPES[UA_TYPES_RANGE]) {
41882 UA_DataValue_clear(p: &rangeVal);
41883 return UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED;
41884 }
41885
41886 /* Compute the abs deadband */
41887 UA_Range *euRange = (UA_Range*)rangeVal.value.data;
41888 UA_Double absDeadband = (filter->deadbandValue/100.0) * (euRange->high - euRange->low);
41889
41890 UA_DataValue_clear(p: &rangeVal);
41891
41892 /* EURange invalid or NaN? */
41893 if(absDeadband < 0.0 || absDeadband != absDeadband) {
41894 UA_DataValue_clear(p: &rangeVal);
41895 return UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED;
41896 }
41897
41898 /* Adjust the original filter */
41899 filter->deadbandType = UA_DEADBANDTYPE_ABSOLUTE;
41900 filter->deadbandValue = absDeadband;
41901 return UA_STATUSCODE_GOOD;
41902}
41903
41904#endif /* UA_ENABLE_DA */
41905
41906void
41907Service_SetTriggering(UA_Server *server, UA_Session *session,
41908 const UA_SetTriggeringRequest *request,
41909 UA_SetTriggeringResponse *response) {
41910 /* Nothing to do? */
41911 if(request->linksToRemoveSize == 0 &&
41912 request->linksToAddSize == 0) {
41913 response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
41914 return;
41915 }
41916
41917 /* Get the Subscription */
41918 UA_Subscription *sub = UA_Session_getSubscriptionById(session, subscriptionId: request->subscriptionId);
41919 if(!sub) {
41920 response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
41921 return;
41922 }
41923
41924 /* Reset the lifetime counter of the Subscription */
41925 Subscription_resetLifetime(sub);
41926
41927 /* Get the MonitoredItem */
41928 UA_MonitoredItem *mon = UA_Subscription_getMonitoredItem(sub, monitoredItemId: request->triggeringItemId);
41929 if(!mon) {
41930 response->responseHeader.serviceResult = UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
41931 return;
41932 }
41933
41934 /* Allocate the results arrays */
41935 if(request->linksToRemoveSize > 0) {
41936 response->removeResults = (UA_StatusCode*)
41937 UA_Array_new(size: request->linksToRemoveSize, type: &UA_TYPES[UA_TYPES_STATUSCODE]);
41938 if(!response->removeResults) {
41939 response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
41940 return;
41941 }
41942 response->removeResultsSize = request->linksToRemoveSize;
41943 }
41944
41945 if(request->linksToAddSize> 0) {
41946 response->addResults = (UA_StatusCode*)
41947 UA_Array_new(size: request->linksToAddSize, type: &UA_TYPES[UA_TYPES_STATUSCODE]);
41948 if(!response->addResults) {
41949 UA_Array_delete(p: response->removeResults,
41950 size: request->linksToAddSize, type: &UA_TYPES[UA_TYPES_STATUSCODE]);
41951 response->removeResults = NULL;
41952 response->removeResultsSize = 0;
41953 response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
41954 return;
41955 }
41956 response->addResultsSize = request->linksToAddSize;
41957 }
41958
41959 /* Apply the changes */
41960 for(size_t i = 0; i < request->linksToRemoveSize; i++)
41961 response->removeResults[i] =
41962 UA_MonitoredItem_removeLink(sub, mon, linkId: request->linksToRemove[i]);
41963
41964 for(size_t i = 0; i < request->linksToAddSize; i++)
41965 response->addResults[i] =
41966 UA_MonitoredItem_addLink(sub, mon, linkId: request->linksToAdd[i]);
41967}
41968
41969/* Verify and adjust the parameters of a MonitoredItem */
41970static UA_StatusCode
41971checkAdjustMonitoredItemParams(UA_Server *server, UA_Session *session,
41972 const UA_MonitoredItem *mon,
41973 const UA_DataType* valueType,
41974 UA_MonitoringParameters *params) {
41975 UA_LOCK_ASSERT(&server->serviceMutex, 1);
41976
41977 /* Check the filter */
41978 if(mon->itemToMonitor.attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) {
41979 /* Event MonitoredItems need a filter */
41980#ifndef UA_ENABLE_SUBSCRIPTIONS_EVENTS
41981 return UA_STATUSCODE_BADNOTSUPPORTED;
41982#else
41983 if(params->filter.encoding != UA_EXTENSIONOBJECT_DECODED &&
41984 params->filter.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE)
41985 return UA_STATUSCODE_BADEVENTFILTERINVALID;
41986 if(params->filter.content.decoded.type != &UA_TYPES[UA_TYPES_EVENTFILTER])
41987 return UA_STATUSCODE_BADEVENTFILTERINVALID;
41988#endif
41989 } else {
41990 /* DataChange MonitoredItem. Can be "no filter" which defaults to
41991 * triggering on Status and Value. */
41992 if(params->filter.encoding != UA_EXTENSIONOBJECT_DECODED &&
41993 params->filter.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE &&
41994 params->filter.encoding != UA_EXTENSIONOBJECT_ENCODED_NOBODY)
41995 return UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED;
41996
41997 /* If the filter ExtensionObject has a body, then it must be a
41998 * DataChangeFilter */
41999 if(params->filter.encoding != UA_EXTENSIONOBJECT_ENCODED_NOBODY &&
42000 params->filter.content.decoded.type != &UA_TYPES[UA_TYPES_DATACHANGEFILTER])
42001 return UA_STATUSCODE_BADFILTERNOTALLOWED;
42002
42003 /* Check the deadband and adjust if necessary. */
42004 if(params->filter.content.decoded.type == &UA_TYPES[UA_TYPES_DATACHANGEFILTER]) {
42005 UA_DataChangeFilter *filter = (UA_DataChangeFilter *)
42006 params->filter.content.decoded.data;
42007 switch(filter->deadbandType) {
42008 case UA_DEADBANDTYPE_NONE:
42009 break;
42010 case UA_DEADBANDTYPE_ABSOLUTE:
42011 if(mon->itemToMonitor.attributeId != UA_ATTRIBUTEID_VALUE ||
42012 !valueType || !UA_DataType_isNumeric(type: valueType))
42013 return UA_STATUSCODE_BADFILTERNOTALLOWED;
42014 break;
42015#ifdef UA_ENABLE_DA
42016 case UA_DEADBANDTYPE_PERCENT: {
42017 if(mon->itemToMonitor.attributeId != UA_ATTRIBUTEID_VALUE ||
42018 !valueType || !UA_DataType_isNumeric(type: valueType))
42019 return UA_STATUSCODE_BADFILTERNOTALLOWED;
42020 /* If percentage deadband is supported, look up the range values
42021 * and precompute as if it was an absolute deadband. */
42022 UA_StatusCode res =
42023 setAbsoluteFromPercentageDeadband(server, session, mon, filter);
42024 if(res != UA_STATUSCODE_GOOD)
42025 return res;
42026 break;
42027 }
42028#endif
42029 default:
42030 return UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED;
42031 }
42032 }
42033 }
42034
42035 /* Read the minimum sampling interval for the variable. The sampling
42036 * interval of the MonitoredItem must not be less than that. */
42037 if(mon->itemToMonitor.attributeId == UA_ATTRIBUTEID_VALUE) {
42038 const UA_Node *node = UA_NODESTORE_GET(server, nodeId: &mon->itemToMonitor.nodeId);
42039 if(node) {
42040 const UA_VariableNode *vn = &node->variableNode;
42041 if(node->head.nodeClass == UA_NODECLASS_VARIABLE) {
42042 /* Take into account if the publishing interval is used for sampling */
42043 UA_Double samplingInterval = params->samplingInterval;
42044 if(samplingInterval < 0 && mon->subscription)
42045 samplingInterval = mon->subscription->publishingInterval;
42046 /* Adjust if smaller than the allowed minimum for the variable */
42047 if(samplingInterval < vn->minimumSamplingInterval)
42048 params->samplingInterval = vn->minimumSamplingInterval;
42049 }
42050 UA_NODESTORE_RELEASE(server, node);
42051 }
42052 }
42053
42054
42055 /* A negative number indicates that the sampling interval is the publishing
42056 * interval of the Subscription. Note that the sampling interval selected
42057 * here remains also when the Subscription's publish interval is adjusted
42058 * afterwards. */
42059 if(mon->subscription && params->samplingInterval < 0.0)
42060 params->samplingInterval = mon->subscription->publishingInterval;
42061
42062 /* Adjust non-null sampling interval to lie within the configured limits */
42063 if(params->samplingInterval != 0.0) {
42064 UA_BOUNDEDVALUE_SETWBOUNDS(server->config.samplingIntervalLimits,
42065 params->samplingInterval, params->samplingInterval);
42066 /* Check for NaN */
42067 if(mon->parameters.samplingInterval != mon->parameters.samplingInterval)
42068 params->samplingInterval = server->config.samplingIntervalLimits.min;
42069 }
42070
42071 /* Adjust the maximum queue size */
42072#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
42073 if(mon->itemToMonitor.attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) {
42074 /* 0 => Set to the configured maximum. Otherwise adjust with configured limits */
42075 if(params->queueSize == 0) {
42076 params->queueSize = server->config.queueSizeLimits.max;
42077 } else {
42078 UA_BOUNDEDVALUE_SETWBOUNDS(server->config.queueSizeLimits,
42079 params->queueSize, params->queueSize);
42080 }
42081 } else
42082#endif
42083 {
42084 /* 0 or 1 => queue-size 1. Otherwise adjust with configured limits */
42085 if(params->queueSize == 0)
42086 params->queueSize = 1;
42087 if(params->queueSize != 1)
42088 UA_BOUNDEDVALUE_SETWBOUNDS(server->config.queueSizeLimits,
42089 params->queueSize, params->queueSize);
42090 }
42091
42092 return UA_STATUSCODE_GOOD;
42093}
42094
42095#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
42096static UA_StatusCode
42097checkEventFilterParam(UA_Server *server, UA_Session *session,
42098 const UA_MonitoredItem *mon,
42099 const UA_MonitoringParameters *params,
42100 UA_ExtensionObject *filterResult) {
42101 /* Is an Event MonitoredItem? */
42102 if(mon->itemToMonitor.attributeId != UA_ATTRIBUTEID_EVENTNOTIFIER)
42103 return UA_STATUSCODE_GOOD;
42104
42105 /* Correct data type? */
42106 if(params->filter.encoding != UA_EXTENSIONOBJECT_DECODED &&
42107 params->filter.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE)
42108 return UA_STATUSCODE_BADEVENTFILTERINVALID;
42109 if(params->filter.content.decoded.type != &UA_TYPES[UA_TYPES_EVENTFILTER])
42110 return UA_STATUSCODE_BADEVENTFILTERINVALID;
42111
42112 UA_EventFilter *eventFilter = (UA_EventFilter *)params->filter.content.decoded.data;
42113
42114 /* Correct number of elements? */
42115 if(eventFilter->selectClausesSize == 0 ||
42116 eventFilter->selectClausesSize > UA_EVENTFILTER_MAXSELECT)
42117 return UA_STATUSCODE_BADEVENTFILTERINVALID;
42118
42119 /* Allow empty where clauses --> select every event */
42120 if(eventFilter->whereClause.elementsSize > UA_EVENTFILTER_MAXELEMENTS)
42121 return UA_STATUSCODE_BADEVENTFILTERINVALID;
42122
42123 /* Check where-clause */
42124 UA_StatusCode res = UA_STATUSCODE_GOOD;
42125 const UA_ContentFilter *cf = &eventFilter->whereClause;
42126 UA_ContentFilterElementResult whereRes[UA_EVENTFILTER_MAXELEMENTS];
42127 for(size_t i = 0; i < cf->elementsSize; ++i) {
42128 UA_ContentFilterElement *ef = &cf->elements[i];
42129 whereRes[i] = UA_ContentFilterElementValidation(server, operatorIndex: i, operatorsCount: cf->elementsSize, ef);
42130 if(whereRes[i].statusCode != UA_STATUSCODE_GOOD && res == UA_STATUSCODE_GOOD)
42131 res = whereRes[i].statusCode;
42132 }
42133
42134 /* Check select clause */
42135 UA_StatusCode selectRes[UA_EVENTFILTER_MAXSELECT];
42136 for(size_t i = 0; i < eventFilter->selectClausesSize; i++) {
42137 const UA_SimpleAttributeOperand *sao = &eventFilter->selectClauses[i];
42138 selectRes[i] = UA_SimpleAttributeOperandValidation(server, sao);
42139 if(selectRes[i] != UA_STATUSCODE_GOOD && res == UA_STATUSCODE_GOOD)
42140 res = selectRes[i];
42141 }
42142
42143 /* Filter bad, return details */
42144 if(res != UA_STATUSCODE_GOOD) {
42145 UA_EventFilterResult *efr = UA_EventFilterResult_new();
42146 if(!efr) {
42147 res = UA_STATUSCODE_BADOUTOFMEMORY;
42148 } else {
42149 UA_EventFilterResult tmp_efr;
42150 UA_EventFilterResult_init(p: &tmp_efr);
42151 tmp_efr.selectClauseResultsSize = eventFilter->selectClausesSize;
42152 tmp_efr.selectClauseResults = selectRes;
42153 tmp_efr.whereClauseResult.elementResultsSize = cf->elementsSize;
42154 tmp_efr.whereClauseResult.elementResults = whereRes;
42155 UA_EventFilterResult_copy(src: &tmp_efr, dst: efr);
42156 UA_ExtensionObject_setValue(eo: filterResult, p: efr,
42157 type: &UA_TYPES[UA_TYPES_EVENTFILTERRESULT]);
42158 }
42159 }
42160
42161 for(size_t i = 0; i < cf->elementsSize; ++i)
42162 UA_ContentFilterElementResult_clear(p: &whereRes[i]);
42163 return res;
42164}
42165#endif
42166
42167static const UA_String
42168binaryEncoding = {sizeof("Default Binary") - 1, (UA_Byte *)"Default Binary"};
42169
42170/* Structure to pass additional arguments into the operation */
42171struct createMonContext {
42172 UA_Subscription *sub;
42173 UA_TimestampsToReturn timestampsToReturn;
42174
42175 /* If sub is NULL, use local callbacks */
42176 UA_Server_DataChangeNotificationCallback dataChangeCallback;
42177 void *context;
42178};
42179
42180static void
42181Operation_CreateMonitoredItem(UA_Server *server, UA_Session *session,
42182 struct createMonContext *cmc,
42183 const UA_MonitoredItemCreateRequest *request,
42184 UA_MonitoredItemCreateResult *result) {
42185 UA_LOCK_ASSERT(&server->serviceMutex, 1);
42186
42187 /* Check available capacity */
42188 if(cmc->sub &&
42189 (((server->config.maxMonitoredItems != 0) &&
42190 (server->monitoredItemsSize >= server->config.maxMonitoredItems)) ||
42191 ((server->config.maxMonitoredItemsPerSubscription != 0) &&
42192 (cmc->sub->monitoredItemsSize >= server->config.maxMonitoredItemsPerSubscription)))) {
42193 result->statusCode = UA_STATUSCODE_BADTOOMANYMONITOREDITEMS;
42194 return;
42195 }
42196
42197 /* Check if the encoding is supported */
42198 if(request->itemToMonitor.dataEncoding.name.length > 0 &&
42199 (!UA_String_equal(p1: &binaryEncoding, p2: &request->itemToMonitor.dataEncoding.name) ||
42200 request->itemToMonitor.dataEncoding.namespaceIndex != 0)) {
42201 result->statusCode = UA_STATUSCODE_BADDATAENCODINGUNSUPPORTED;
42202 return;
42203 }
42204
42205 /* Check if the encoding is set for a value */
42206 if(request->itemToMonitor.attributeId != UA_ATTRIBUTEID_VALUE &&
42207 request->itemToMonitor.dataEncoding.name.length > 0) {
42208 result->statusCode = UA_STATUSCODE_BADDATAENCODINGINVALID;
42209 return;
42210 }
42211
42212 /* Make an example read to check the itemToMonitor. The DataSource itself
42213 * could return a (temporary) error. This should still result in a valid
42214 * MonitoredItem. Only a few StatusCodes are considered unrecoverable and
42215 * lead to an abort:
42216 * - The Node does not exist
42217 * - The AttributeId does not match the NodeClass
42218 * - The Session does not have sufficient access rights
42219 * - The indicated encoding is not supported or not valid */
42220 UA_DataValue v = readWithSession(server, session, item: &request->itemToMonitor,
42221 timestampsToReturn: cmc->timestampsToReturn);
42222 if(v.hasStatus &&
42223 (v.status == UA_STATUSCODE_BADNODEIDUNKNOWN ||
42224 v.status == UA_STATUSCODE_BADATTRIBUTEIDINVALID ||
42225 v.status == UA_STATUSCODE_BADDATAENCODINGUNSUPPORTED ||
42226 v.status == UA_STATUSCODE_BADDATAENCODINGINVALID ||
42227 v.status == UA_STATUSCODE_BADINDEXRANGEINVALID
42228 /* Part 4, 5.12.2 CreateMonitoredItems: When a user adds a monitored
42229 * item that the user is denied read access to, the add operation for
42230 * the item shall succeed and the bad status Bad_NotReadable or
42231 * Bad_UserAccessDenied shall be returned in the Publish response.
42232 * v.status == UA_STATUSCODE_BADNOTREADABLE
42233 * v.status == UA_STATUSCODE_BADUSERACCESSDENIED
42234 *
42235 * The IndexRange error can change depending on the value.
42236 * v.status == UA_STATUSCODE_BADINDEXRANGENODATA */
42237 )) {
42238 result->statusCode = v.status;
42239 UA_DataValue_clear(p: &v);
42240 return;
42241 }
42242
42243 /* Adding an Event MonitoredItem */
42244#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
42245 if(request->itemToMonitor.attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) {
42246 /* TODO: Only remote clients can add Event-MonitoredItems at the moment */
42247 if(!cmc->sub) {
42248 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
42249 msg: "Only remote clients can add Event-MonitoredItems");
42250 result->statusCode = UA_STATUSCODE_BADNOTSUPPORTED;
42251 UA_DataValue_clear(p: &v);
42252 return;
42253 }
42254
42255 /* If the 'SubscribeToEvents' bit of EventNotifier attribute is
42256 * zero, then the object cannot be subscribed to monitor events */
42257 if(!v.hasValue || !v.value.data) {
42258 result->statusCode = UA_STATUSCODE_BADINTERNALERROR;
42259 UA_DataValue_clear(p: &v);
42260 return;
42261 }
42262 UA_Byte eventNotifierValue = *((UA_Byte *)v.value.data);
42263 if((eventNotifierValue & 0x01) != 1) {
42264 result->statusCode = UA_STATUSCODE_BADNOTSUPPORTED;
42265 UA_LOG_INFO_SUBSCRIPTION(server->config.logging, cmc->sub,
42266 "Could not create a MonitoredItem as the "
42267 "'SubscribeToEvents' bit of the EventNotifier "
42268 "attribute is not set");
42269 UA_DataValue_clear(p: &v);
42270 return;
42271 }
42272 }
42273#endif
42274
42275 const UA_DataType *valueType = v.value.type;
42276 UA_DataValue_clear(p: &v);
42277
42278 /* Allocate the MonitoredItem */
42279 UA_MonitoredItem *newMon = NULL;
42280 if(cmc->sub) {
42281 newMon = (UA_MonitoredItem*)UA_malloc(size: sizeof(UA_MonitoredItem));
42282 } else {
42283 UA_LocalMonitoredItem *localMon = (UA_LocalMonitoredItem*)
42284 UA_malloc(size: sizeof(UA_LocalMonitoredItem));
42285 if(localMon) {
42286 /* Set special values only for the LocalMonitoredItem */
42287 localMon->context = cmc->context;
42288 localMon->callback.dataChangeCallback = cmc->dataChangeCallback;
42289 }
42290 newMon = &localMon->monitoredItem;
42291 }
42292 if(!newMon) {
42293 result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
42294 return;
42295 }
42296
42297 /* Initialize the MonitoredItem */
42298 UA_MonitoredItem_init(mon: newMon);
42299 newMon->subscription = cmc->sub; /* Can be NULL for local MonitoredItems */
42300 newMon->timestampsToReturn = cmc->timestampsToReturn;
42301 result->statusCode |= UA_ReadValueId_copy(src: &request->itemToMonitor,
42302 dst: &newMon->itemToMonitor);
42303 result->statusCode |= UA_MonitoringParameters_copy(src: &request->requestedParameters,
42304 dst: &newMon->parameters);
42305 result->statusCode |= checkAdjustMonitoredItemParams(server, session, mon: newMon,
42306 valueType, params: &newMon->parameters);
42307#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
42308 const UA_StatusCode eventFilterStatus = checkEventFilterParam(server, session, mon: newMon,
42309 params: &newMon->parameters,
42310 filterResult: &result->filterResult);
42311
42312 if(eventFilterStatus != UA_STATUSCODE_GOOD) {
42313 result->statusCode = UA_STATUSCODE_BADEVENTFILTERINVALID;
42314 }
42315#endif
42316 if(result->statusCode != UA_STATUSCODE_GOOD) {
42317 UA_LOG_INFO_SUBSCRIPTION(server->config.logging, cmc->sub,
42318 "Could not create a MonitoredItem "
42319 "with StatusCode %s",
42320 UA_StatusCode_name(result->statusCode));
42321 UA_MonitoredItem_delete(server, mon: newMon);
42322 return;
42323 }
42324
42325 /* Initialize the value status so the first sample always passes the filter */
42326 newMon->lastValue.hasStatus = true;
42327 newMon->lastValue.status = ~(UA_StatusCode)0;
42328
42329 /* Register the Monitoreditem in the server and subscription */
42330 UA_Server_registerMonitoredItem(server, mon: newMon);
42331
42332 /* Activate the MonitoredItem */
42333 result->statusCode |=
42334 UA_MonitoredItem_setMonitoringMode(server, mon: newMon, monitoringMode: request->monitoringMode);
42335 if(result->statusCode != UA_STATUSCODE_GOOD) {
42336 UA_MonitoredItem_delete(server, mon: newMon);
42337 return;
42338 }
42339
42340 /* Prepare the response */
42341 result->revisedSamplingInterval = newMon->parameters.samplingInterval;
42342 result->revisedQueueSize = newMon->parameters.queueSize;
42343 result->monitoredItemId = newMon->monitoredItemId;
42344
42345 /* If the sampling interval is negative (the sampling callback is called
42346 * from within the publishing callback), return the publishing interval of
42347 * the Subscription. Note that we only use the cyclic callback of the
42348 * Subscription. So if the Subscription publishing interval is modified,
42349 * this also impacts this MonitoredItem. */
42350 if(result->revisedSamplingInterval < 0.0 && cmc->sub)
42351 result->revisedSamplingInterval = cmc->sub->publishingInterval;
42352
42353 UA_LOG_INFO_SUBSCRIPTION(server->config.logging, cmc->sub,
42354 "MonitoredItem %" PRIi32 " | "
42355 "Created the MonitoredItem "
42356 "(Sampling Interval: %.2fms, Queue Size: %lu)",
42357 newMon->monitoredItemId,
42358 newMon->parameters.samplingInterval,
42359 (unsigned long)newMon->parameters.queueSize);
42360}
42361
42362void
42363Service_CreateMonitoredItems(UA_Server *server, UA_Session *session,
42364 const UA_CreateMonitoredItemsRequest *request,
42365 UA_CreateMonitoredItemsResponse *response) {
42366 UA_LOG_DEBUG_SESSION(server->config.logging, session,
42367 "Processing CreateMonitoredItemsRequest");
42368 UA_LOCK_ASSERT(&server->serviceMutex, 1);
42369
42370 if(server->config.maxMonitoredItemsPerCall != 0 &&
42371 request->itemsToCreateSize > server->config.maxMonitoredItemsPerCall) {
42372 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
42373 return;
42374 }
42375
42376 /* Check if the timestampstoreturn is valid */
42377 struct createMonContext cmc;
42378 cmc.timestampsToReturn = request->timestampsToReturn;
42379 if(cmc.timestampsToReturn > UA_TIMESTAMPSTORETURN_NEITHER) {
42380 response->responseHeader.serviceResult = UA_STATUSCODE_BADTIMESTAMPSTORETURNINVALID;
42381 return;
42382 }
42383
42384 /* Find the subscription */
42385 cmc.sub = UA_Session_getSubscriptionById(session, subscriptionId: request->subscriptionId);
42386 if(!cmc.sub) {
42387 response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
42388 return;
42389 }
42390
42391 /* Reset the lifetime counter of the Subscription */
42392 Subscription_resetLifetime(sub: cmc.sub);
42393
42394 response->responseHeader.serviceResult =
42395 UA_Server_processServiceOperations(server, session,
42396 operationCallback: (UA_ServiceOperation)Operation_CreateMonitoredItem,
42397 context: &cmc, requestOperations: &request->itemsToCreateSize,
42398 requestOperationsType: &UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST],
42399 responseOperations: &response->resultsSize,
42400 responseOperationsType: &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT]);
42401}
42402
42403UA_MonitoredItemCreateResult
42404UA_Server_createDataChangeMonitoredItem(UA_Server *server,
42405 UA_TimestampsToReturn timestampsToReturn,
42406 const UA_MonitoredItemCreateRequest item,
42407 void *monitoredItemContext,
42408 UA_Server_DataChangeNotificationCallback callback) {
42409 struct createMonContext cmc;
42410 cmc.sub = NULL;
42411 cmc.context = monitoredItemContext;
42412 cmc.dataChangeCallback = callback;
42413 cmc.timestampsToReturn = timestampsToReturn;
42414
42415 UA_MonitoredItemCreateResult result;
42416 UA_MonitoredItemCreateResult_init(p: &result);
42417 lockServer(server);
42418 Operation_CreateMonitoredItem(server, session: &server->adminSession, cmc: &cmc, request: &item, result: &result);
42419 unlockServer(server);
42420 return result;
42421}
42422
42423static void
42424Operation_ModifyMonitoredItem(UA_Server *server, UA_Session *session, UA_Subscription *sub,
42425 const UA_MonitoredItemModifyRequest *request,
42426 UA_MonitoredItemModifyResult *result) {
42427 /* Get the MonitoredItem */
42428 UA_MonitoredItem *mon = UA_Subscription_getMonitoredItem(sub, monitoredItemId: request->monitoredItemId);
42429 if(!mon) {
42430 result->statusCode = UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
42431 return;
42432 }
42433
42434 /* Make local copy of the settings */
42435 UA_MonitoringParameters params;
42436 result->statusCode =
42437 UA_MonitoringParameters_copy(src: &request->requestedParameters, dst: &params);
42438 if(result->statusCode != UA_STATUSCODE_GOOD)
42439 return;
42440
42441 /* Read the current value to test if filters are possible.
42442 * Can return an empty value (v.value.type == NULL). */
42443 UA_DataValue v = readWithSession(server, session, item: &mon->itemToMonitor,
42444 timestampsToReturn: mon->timestampsToReturn);
42445
42446 /* Verify and adjust the new parameters. This still leaves the original
42447 * MonitoredItem untouched. */
42448 result->statusCode =
42449 checkAdjustMonitoredItemParams(server, session, mon,
42450 valueType: v.value.type, params: &params);
42451 UA_DataValue_clear(p: &v);
42452 if(result->statusCode != UA_STATUSCODE_GOOD) {
42453 UA_MonitoringParameters_clear(p: &params);
42454 return;
42455 }
42456
42457#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
42458 const UA_StatusCode eventFilterStatus = checkEventFilterParam(server, session, mon,
42459 params: &request->requestedParameters,
42460 filterResult: &result->filterResult);
42461 if(eventFilterStatus != UA_STATUSCODE_GOOD) {
42462 result->statusCode = UA_STATUSCODE_BADEVENTFILTERINVALID;
42463 UA_MonitoringParameters_clear(p: &params);
42464 return;
42465 }
42466#endif
42467
42468 /* Store the old sampling interval */
42469 UA_Double oldSamplingInterval = mon->parameters.samplingInterval;
42470
42471 /* Move over the new settings */
42472 UA_MonitoringParameters_clear(p: &mon->parameters);
42473 mon->parameters = params;
42474
42475 /* Re-register the callback if necessary */
42476 if(oldSamplingInterval != mon->parameters.samplingInterval) {
42477 UA_MonitoredItem_unregisterSampling(server, mon);
42478 result->statusCode =
42479 UA_MonitoredItem_setMonitoringMode(server, mon, monitoringMode: mon->monitoringMode);
42480 }
42481
42482 result->revisedSamplingInterval = mon->parameters.samplingInterval;
42483 result->revisedQueueSize = mon->parameters.queueSize;
42484
42485 /* If the sampling interval is negative (the sampling callback is called
42486 * from within the publishing callback), return the publishing interval of
42487 * the Subscription. Note that we only use the cyclic callback of the
42488 * Subscription. So if the Subscription publishing interval is modified,
42489 * this also impacts this MonitoredItem. */
42490 if(result->revisedSamplingInterval < 0.0 && mon->subscription)
42491 result->revisedSamplingInterval = mon->subscription->publishingInterval;
42492
42493 /* Remove some notifications if the queue is now too small */
42494 UA_MonitoredItem_ensureQueueSpace(server, mon);
42495
42496 /* Remove the overflow bits if the queue has now a size of 1 */
42497 UA_MonitoredItem_removeOverflowInfoBits(mon);
42498
42499 /* If the sampling interval is negative (the sampling callback is called
42500 * from within the publishing callback), return the publishing interval of
42501 * the Subscription. Note that we only use the cyclic callback of the
42502 * Subscription. So if the Subscription publishing interval is modified,
42503 * this also impacts this MonitoredItem. */
42504 if(result->revisedSamplingInterval < 0.0 && mon->subscription)
42505 result->revisedSamplingInterval = mon->subscription->publishingInterval;
42506
42507 UA_LOG_INFO_SUBSCRIPTION(server->config.logging, sub,
42508 "MonitoredItem %" PRIi32 " | "
42509 "Modified the MonitoredItem "
42510 "(Sampling Interval: %fms, Queue Size: %lu)",
42511 mon->monitoredItemId,
42512 mon->parameters.samplingInterval,
42513 (unsigned long)mon->queueSize);
42514}
42515
42516void
42517Service_ModifyMonitoredItems(UA_Server *server, UA_Session *session,
42518 const UA_ModifyMonitoredItemsRequest *request,
42519 UA_ModifyMonitoredItemsResponse *response) {
42520 UA_LOG_DEBUG_SESSION(server->config.logging, session,
42521 "Processing ModifyMonitoredItemsRequest");
42522 UA_LOCK_ASSERT(&server->serviceMutex, 1);
42523
42524 if(server->config.maxMonitoredItemsPerCall != 0 &&
42525 request->itemsToModifySize > server->config.maxMonitoredItemsPerCall) {
42526 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
42527 return;
42528 }
42529
42530 /* Check if the timestampstoreturn is valid */
42531 if(request->timestampsToReturn > UA_TIMESTAMPSTORETURN_NEITHER) {
42532 response->responseHeader.serviceResult = UA_STATUSCODE_BADTIMESTAMPSTORETURNINVALID;
42533 return;
42534 }
42535
42536 /* Get the subscription */
42537 UA_Subscription *sub = UA_Session_getSubscriptionById(session, subscriptionId: request->subscriptionId);
42538 if(!sub) {
42539 response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
42540 return;
42541 }
42542
42543 /* Reset the lifetime counter of the Subscription */
42544 Subscription_resetLifetime(sub);
42545
42546 response->responseHeader.serviceResult =
42547 UA_Server_processServiceOperations(server, session,
42548 operationCallback: (UA_ServiceOperation)Operation_ModifyMonitoredItem,
42549 context: sub, requestOperations: &request->itemsToModifySize,
42550 requestOperationsType: &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST],
42551 responseOperations: &response->resultsSize,
42552 responseOperationsType: &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT]);
42553}
42554
42555struct setMonitoringContext {
42556 UA_Subscription *sub;
42557 UA_MonitoringMode monitoringMode;
42558};
42559
42560static void
42561Operation_SetMonitoringMode(UA_Server *server, UA_Session *session,
42562 struct setMonitoringContext *smc,
42563 const UA_UInt32 *monitoredItemId, UA_StatusCode *result) {
42564 UA_MonitoredItem *mon = UA_Subscription_getMonitoredItem(sub: smc->sub, monitoredItemId: *monitoredItemId);
42565 if(!mon) {
42566 *result = UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
42567 return;
42568 }
42569 *result = UA_MonitoredItem_setMonitoringMode(server, mon, monitoringMode: smc->monitoringMode);
42570}
42571
42572void
42573Service_SetMonitoringMode(UA_Server *server, UA_Session *session,
42574 const UA_SetMonitoringModeRequest *request,
42575 UA_SetMonitoringModeResponse *response) {
42576 UA_LOG_DEBUG_SESSION(server->config.logging, session, "Processing SetMonitoringMode");
42577 UA_LOCK_ASSERT(&server->serviceMutex, 1);
42578
42579 if(server->config.maxMonitoredItemsPerCall != 0 &&
42580 request->monitoredItemIdsSize > server->config.maxMonitoredItemsPerCall) {
42581 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
42582 return;
42583 }
42584
42585 /* Get the subscription */
42586 struct setMonitoringContext smc;
42587 smc.sub = UA_Session_getSubscriptionById(session, subscriptionId: request->subscriptionId);
42588 if(!smc.sub) {
42589 response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
42590 return;
42591 }
42592
42593 /* Reset the lifetime counter of the Subscription */
42594 Subscription_resetLifetime(sub: smc.sub);
42595
42596 smc.monitoringMode = request->monitoringMode;
42597 response->responseHeader.serviceResult =
42598 UA_Server_processServiceOperations(server, session,
42599 operationCallback: (UA_ServiceOperation)Operation_SetMonitoringMode,
42600 context: &smc, requestOperations: &request->monitoredItemIdsSize,
42601 requestOperationsType: &UA_TYPES[UA_TYPES_UINT32],
42602 responseOperations: &response->resultsSize,
42603 responseOperationsType: &UA_TYPES[UA_TYPES_STATUSCODE]);
42604}
42605
42606static void
42607Operation_DeleteMonitoredItem(UA_Server *server, UA_Session *session, UA_Subscription *sub,
42608 const UA_UInt32 *monitoredItemId, UA_StatusCode *result) {
42609 UA_LOCK_ASSERT(&server->serviceMutex, 1);
42610 UA_MonitoredItem *mon = UA_Subscription_getMonitoredItem(sub, monitoredItemId: *monitoredItemId);
42611 if(!mon) {
42612 *result = UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
42613 return;
42614 }
42615 UA_MonitoredItem_delete(server, mon);
42616}
42617
42618void
42619Service_DeleteMonitoredItems(UA_Server *server, UA_Session *session,
42620 const UA_DeleteMonitoredItemsRequest *request,
42621 UA_DeleteMonitoredItemsResponse *response) {
42622 UA_LOG_DEBUG_SESSION(server->config.logging, session,
42623 "Processing DeleteMonitoredItemsRequest");
42624 UA_LOCK_ASSERT(&server->serviceMutex, 1);
42625
42626 if(server->config.maxMonitoredItemsPerCall != 0 &&
42627 request->monitoredItemIdsSize > server->config.maxMonitoredItemsPerCall) {
42628 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
42629 return;
42630 }
42631
42632 /* Get the subscription */
42633 UA_Subscription *sub = UA_Session_getSubscriptionById(session, subscriptionId: request->subscriptionId);
42634 if(!sub) {
42635 response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
42636 return;
42637 }
42638
42639 /* Reset the lifetime counter of the Subscription */
42640 Subscription_resetLifetime(sub);
42641
42642 response->responseHeader.serviceResult =
42643 UA_Server_processServiceOperations(server, session,
42644 operationCallback: (UA_ServiceOperation)Operation_DeleteMonitoredItem,
42645 context: sub, requestOperations: &request->monitoredItemIdsSize,
42646 requestOperationsType: &UA_TYPES[UA_TYPES_UINT32],
42647 responseOperations: &response->resultsSize,
42648 responseOperationsType: &UA_TYPES[UA_TYPES_STATUSCODE]);
42649}
42650
42651UA_StatusCode
42652UA_Server_deleteMonitoredItem(UA_Server *server, UA_UInt32 monitoredItemId) {
42653 lockServer(server);
42654 UA_MonitoredItem *mon, *mon_tmp;
42655 LIST_FOREACH_SAFE(mon, &server->localMonitoredItems, listEntry, mon_tmp) {
42656 if(mon->monitoredItemId != monitoredItemId)
42657 continue;
42658 UA_MonitoredItem_delete(server, mon);
42659 unlockServer(server);
42660 return UA_STATUSCODE_GOOD;
42661 }
42662 unlockServer(server);
42663 return UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
42664}
42665
42666#endif /* UA_ENABLE_SUBSCRIPTIONS */
42667
42668/**** amalgamated original file "/src/server/ua_services_securechannel.c" ****/
42669
42670/* This Source Code Form is subject to the terms of the Mozilla Public
42671 * License, v. 2.0. If a copy of the MPL was not distributed with this
42672 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
42673 *
42674 * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
42675 * Copyright 2014, 2017 (c) Florian Palm
42676 * Copyright 2015 (c) Oleksiy Vasylyev
42677 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
42678 * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB
42679 * Copyright 2023 (c) Hilscher Gesellschaft für Systemautomation mbH (Author: Phuong Nguyen)
42680 */
42681
42682
42683/* This contains the SecureChannel Services to be called after validation and
42684 * decoding of the message. The main SecureChannel logic is handled in
42685 * /src/ua_securechannel.* and /src/server/ua_server_binary.c. */
42686
42687void
42688Service_OpenSecureChannel(UA_Server *server, UA_SecureChannel *channel,
42689 UA_OpenSecureChannelRequest *request,
42690 UA_OpenSecureChannelResponse *response) {
42691 const UA_SecurityPolicy *sp = channel->securityPolicy;
42692
42693 switch(request->requestType) {
42694 /* Open the channel */
42695 case UA_SECURITYTOKENREQUESTTYPE_ISSUE:
42696 /* We must expect an OPN handshake */
42697 if(channel->state != UA_SECURECHANNELSTATE_ACK_SENT) {
42698 UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
42699 "Called open on already open or closed channel");
42700 response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR;
42701 goto error;
42702 }
42703
42704 /* Set the SecurityMode */
42705 if(request->securityMode != UA_MESSAGESECURITYMODE_NONE &&
42706 UA_ByteString_equal(p1: &sp->policyUri, p2: &UA_SECURITY_POLICY_NONE_URI)) {
42707 response->responseHeader.serviceResult = UA_STATUSCODE_BADSECURITYMODEREJECTED;
42708 goto error;
42709 }
42710 channel->securityMode = request->securityMode;
42711 break;
42712
42713 /* Renew the channel */
42714 case UA_SECURITYTOKENREQUESTTYPE_RENEW:
42715 /* The channel must be open to be renewed */
42716 if(channel->state != UA_SECURECHANNELSTATE_OPEN) {
42717 UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
42718 "Called renew on channel which is not open");
42719 response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR;
42720 goto error;
42721 }
42722
42723 /* Check whether the nonce was reused */
42724 if(channel->securityMode != UA_MESSAGESECURITYMODE_NONE &&
42725 UA_ByteString_equal(p1: &channel->remoteNonce, p2: &request->clientNonce)) {
42726 UA_LOG_ERROR_CHANNEL(server->config.logging, channel,
42727 "The client reused the last nonce");
42728 response->responseHeader.serviceResult = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
42729 goto error;
42730 }
42731
42732 break;
42733
42734 /* Unknown request type */
42735 default:
42736 response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR;
42737 return;
42738 }
42739
42740 /* Create a new SecurityToken. It will be switched over when the first
42741 * message is received. The ChannelId is left unchanged. */
42742 channel->altSecurityToken.channelId = channel->securityToken.channelId;
42743 channel->altSecurityToken.tokenId = generateSecureChannelTokenId(server);
42744 channel->altSecurityToken.createdAt = UA_DateTime_nowMonotonic();
42745 channel->altSecurityToken.revisedLifetime =
42746 (request->requestedLifetime > server->config.maxSecurityTokenLifetime) ?
42747 server->config.maxSecurityTokenLifetime : request->requestedLifetime;
42748 if(channel->altSecurityToken.revisedLifetime == 0)
42749 channel->altSecurityToken.revisedLifetime = server->config.maxSecurityTokenLifetime;
42750
42751 /* Set the nonces. The remote nonce will be "rotated in" when it is first used. */
42752 UA_ByteString_clear(p: &channel->remoteNonce);
42753 channel->remoteNonce = request->clientNonce;
42754 UA_ByteString_init(p: &request->clientNonce);
42755
42756 response->responseHeader.serviceResult = UA_SecureChannel_generateLocalNonce(channel);
42757 UA_CHECK_STATUS(response->responseHeader.serviceResult, goto error);
42758
42759 /* Update the channel state */
42760 channel->renewState = UA_SECURECHANNELRENEWSTATE_NEWTOKEN_SERVER;
42761 channel->state = UA_SECURECHANNELSTATE_OPEN;
42762
42763 /* Set the response */
42764 response->securityToken = channel->altSecurityToken;
42765 response->securityToken.createdAt = UA_DateTime_now(); /* only for sending */
42766 response->responseHeader.timestamp = response->securityToken.createdAt;
42767 response->responseHeader.requestHandle = request->requestHeader.requestHandle;
42768 response->responseHeader.serviceResult =
42769 UA_ByteString_copy(src: &channel->localNonce, dst: &response->serverNonce);
42770 UA_CHECK_STATUS(response->responseHeader.serviceResult, goto error);
42771
42772 /* Success */
42773 if(request->requestType == UA_SECURITYTOKENREQUESTTYPE_ISSUE) {
42774 UA_LOG_INFO_CHANNEL(server->config.logging, channel,
42775 "SecureChannel opened with SecurityPolicy %.*s "
42776 "and a revised lifetime of %.2fs",
42777 (int)channel->securityPolicy->policyUri.length,
42778 channel->securityPolicy->policyUri.data,
42779 (UA_Float)response->securityToken.revisedLifetime / 1000);
42780 } else {
42781 UA_LOG_INFO_CHANNEL(server->config.logging, channel, "SecureChannel renewed "
42782 "with a revised lifetime of %.2fs",
42783 (UA_Float)response->securityToken.revisedLifetime / 1000);
42784 }
42785
42786 return;
42787
42788 error:
42789 if(request->requestType == UA_SECURITYTOKENREQUESTTYPE_ISSUE) {
42790 UA_LOG_INFO_CHANNEL(server->config.logging, channel,
42791 "Opening a SecureChannel failed");
42792 } else {
42793 UA_LOG_DEBUG_CHANNEL(server->config.logging, channel,
42794 "Renewing SecureChannel failed");
42795 }
42796}
42797
42798/* The server does not send a CloseSecureChannel response */
42799void
42800Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel) {
42801 UA_SecureChannel_shutdown(channel, shutdownReason: UA_SHUTDOWNREASON_CLOSE);
42802}
42803
42804/**** amalgamated original file "/src/server/ua_services_nodemanagement.c" ****/
42805
42806/* This Source Code Form is subject to the terms of the Mozilla Public
42807 * License, v. 2.0. If a copy of the MPL was not distributed with this
42808 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
42809 *
42810 * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
42811 * Copyright 2014-2017 (c) Florian Palm
42812 * Copyright 2015-2016 (c) Sten Grüner
42813 * Copyright 2015-2016 (c) Chris Iatrou
42814 * Copyright 2015-2016 (c) Oleksiy Vasylyev
42815 * Copyright 2017 (c) Julian Grothoff
42816 * Copyright 2016 (c) LEvertz
42817 * Copyright 2016 (c) Lorenz Haas
42818 * Copyright 2017 (c) frax2222
42819 * Copyright 2017-2018 (c) Stefan Profanter, fortiss GmbH
42820 * Copyright 2017 (c) Christian von Arnim
42821 * Copyright 2021 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati)
42822 * Copyright 2017 (c) Henrik Norrman
42823 * Copyright 2021 (c) Fraunhofer IOSB (Author: Andreas Ebner)
42824 */
42825
42826
42827/*********************/
42828/* Edit Node Context */
42829/*********************/
42830
42831UA_StatusCode
42832UA_Server_getNodeContext(UA_Server *server, UA_NodeId nodeId,
42833 void **nodeContext) {
42834 lockServer(server);
42835 UA_StatusCode retval = getNodeContext(server, nodeId, nodeContext);
42836 unlockServer(server);
42837 return retval;
42838}
42839
42840UA_StatusCode
42841getNodeContext(UA_Server *server, UA_NodeId nodeId,
42842 void **nodeContext) {
42843 const UA_Node *node = UA_NODESTORE_GET(server, nodeId: &nodeId);
42844 if(!node)
42845 return UA_STATUSCODE_BADNODEIDUNKNOWN;
42846 *nodeContext = node->head.context;
42847 UA_NODESTORE_RELEASE(server, node);
42848 return UA_STATUSCODE_GOOD;
42849}
42850
42851static UA_StatusCode
42852setDeconstructedNode(UA_Server *server, UA_Session *session,
42853 UA_NodeHead *head, void *context) {
42854 head->constructed = false;
42855 return UA_STATUSCODE_GOOD;
42856}
42857
42858static UA_StatusCode
42859setConstructedNodeContext(UA_Server *server, UA_Session *session,
42860 UA_NodeHead *head, void *context) {
42861 head->context = context;
42862 head->constructed = true;
42863 return UA_STATUSCODE_GOOD;
42864}
42865
42866static UA_StatusCode
42867editNodeContext(UA_Server *server, UA_Session* session,
42868 UA_NodeHead *head, void *context) {
42869 head->context = context;
42870 return UA_STATUSCODE_GOOD;
42871}
42872
42873UA_StatusCode
42874setNodeContext(UA_Server *server, UA_NodeId nodeId,
42875 void *nodeContext) {
42876 return UA_Server_editNode(server, session: &server->adminSession, nodeId: &nodeId,
42877 callback: (UA_EditNodeCallback)editNodeContext, data: nodeContext);
42878}
42879
42880UA_StatusCode
42881UA_Server_setNodeContext(UA_Server *server, UA_NodeId nodeId,
42882 void *nodeContext) {
42883 lockServer(server);
42884 UA_StatusCode retval = setNodeContext(server, nodeId, nodeContext);
42885 unlockServer(server);
42886 return retval;
42887}
42888
42889static UA_StatusCode
42890checkSetIsDynamicVariable(UA_Server *server, UA_Session *session,
42891 const UA_NodeId *nodeId);
42892
42893/**********************/
42894/* Consistency Checks */
42895/**********************/
42896
42897#define UA_PARENT_REFERENCES_COUNT 2
42898
42899const UA_NodeId parentReferences[UA_PARENT_REFERENCES_COUNT] = {
42900 {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASSUBTYPE}},
42901 {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASCOMPONENT}}
42902};
42903
42904static void
42905logAddNode(const UA_Logger *logger, UA_Session *session,
42906 const UA_NodeId *nodeId, const char *msg) {
42907 UA_LOG_NODEID_INFO(nodeId,
42908 UA_LOG_INFO_SESSION(logger, session, "AddNode (%.*s): %s",
42909 (int)nodeIdStr.length, nodeIdStr.data, msg));
42910}
42911
42912/* Check if the requested parent node exists, has the right node class and is
42913 * referenced with an allowed (hierarchical) reference type. For "type" nodes,
42914 * only hasSubType references are allowed. */
42915static UA_StatusCode
42916checkParentReference(UA_Server *server, UA_Session *session, const UA_NodeHead *head,
42917 const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId) {
42918 /* Objects do not need a parent (e.g. mandatory/optional modellingrules).
42919 * Also, there are some variables which do not have parents, e.g.
42920 * EnumStrings, EnumValues */
42921 if((head->nodeClass == UA_NODECLASS_OBJECT ||
42922 head->nodeClass == UA_NODECLASS_VARIABLE) &&
42923 UA_NodeId_isNull(p: parentNodeId) && UA_NodeId_isNull(p: referenceTypeId))
42924 return UA_STATUSCODE_GOOD;
42925
42926 /* See if the parent exists */
42927 const UA_Node *parent = UA_NODESTORE_GET(server, nodeId: parentNodeId);
42928 if(!parent) {
42929 logAddNode(logger: server->config.logging, session, nodeId: &head->nodeId,
42930 msg: "Parent node not found");
42931 return UA_STATUSCODE_BADPARENTNODEIDINVALID;
42932 }
42933
42934 UA_NodeClass parentNodeClass = parent->head.nodeClass;
42935 UA_NODESTORE_RELEASE(server, parent);
42936
42937 /* Check the referencetype exists */
42938 const UA_Node *referenceType = UA_NODESTORE_GET(server, nodeId: referenceTypeId);
42939 if(!referenceType) {
42940 logAddNode(logger: server->config.logging, session, nodeId: &head->nodeId,
42941 msg: "Reference type to the parent not found");
42942 return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
42943 }
42944
42945 /* Check if the referencetype is a reference type node */
42946 if(referenceType->head.nodeClass != UA_NODECLASS_REFERENCETYPE) {
42947 logAddNode(logger: server->config.logging, session, nodeId: &head->nodeId,
42948 msg: "Reference type to the parent is not a ReferenceTypeNode");
42949 UA_NODESTORE_RELEASE(server, referenceType);
42950 return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
42951 }
42952
42953 /* Check that the reference type is not abstract */
42954 UA_Boolean referenceTypeIsAbstract = referenceType->referenceTypeNode.isAbstract;
42955 UA_NODESTORE_RELEASE(server, referenceType);
42956 if(referenceTypeIsAbstract == true) {
42957 logAddNode(logger: server->config.logging, session, nodeId: &head->nodeId,
42958 msg: "Abstract reference type to the parent not allowed");
42959 return UA_STATUSCODE_BADREFERENCENOTALLOWED;
42960 }
42961
42962 /* Check hassubtype relation for type nodes */
42963 if(head->nodeClass == UA_NODECLASS_DATATYPE ||
42964 head->nodeClass == UA_NODECLASS_VARIABLETYPE ||
42965 head->nodeClass == UA_NODECLASS_OBJECTTYPE ||
42966 head->nodeClass == UA_NODECLASS_REFERENCETYPE) {
42967 /* Type needs hassubtype reference to the supertype */
42968 if(referenceType->referenceTypeNode.referenceTypeIndex !=
42969 UA_REFERENCETYPEINDEX_HASSUBTYPE) {
42970 logAddNode(logger: server->config.logging, session, nodeId: &head->nodeId,
42971 msg: "Type nodes need to have a HasSubType reference to the parent");
42972 return UA_STATUSCODE_BADREFERENCENOTALLOWED;
42973 }
42974 /* Supertype needs to be of the same node type */
42975 if(parentNodeClass != head->nodeClass) {
42976 logAddNode(logger: server->config.logging, session, nodeId: &head->nodeId,
42977 msg: "Type nodes needs to be of the same node "
42978 "type as their parent");
42979 return UA_STATUSCODE_BADPARENTNODEIDINVALID;
42980 }
42981 return UA_STATUSCODE_GOOD;
42982 }
42983
42984 /* Test if the referencetype is hierarchical */
42985 const UA_NodeId hierarchRefs = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HIERARCHICALREFERENCES);
42986 if(!isNodeInTree_singleRef(server, leafNode: referenceTypeId, nodeToFind: &hierarchRefs,
42987 UA_REFERENCETYPEINDEX_HASSUBTYPE)) {
42988 logAddNode(logger: server->config.logging, session, nodeId: &head->nodeId,
42989 msg: "Reference type to the parent is not hierarchical");
42990 return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
42991 }
42992
42993 return UA_STATUSCODE_GOOD;
42994}
42995
42996/* Only BaseDataType can have empty values. Generate a default value. */
42997static UA_StatusCode
42998setDefaultValue(UA_Server *server, const UA_VariableNode *node) {
42999 /* Get the DataType */
43000 UA_StatusCode res = UA_STATUSCODE_GOOD;
43001 const UA_DataType *type = UA_Server_findDataType(server, typeId: &node->dataType);
43002 if(!type) {
43003 /* No description for the DataType found. It is possible that an
43004 * abstract DataType is used, e.g. UInteger. Browse to see if there is a
43005 * non-abstract subtype that can be used for the default value.
43006 *
43007 * Look up and downwards in the hierarchy. Some data types (e.g.
43008 * UtcTime) are derived from a non-abstract data type. This is then used
43009 * for the actual value, Use the first match. */
43010 UA_ReferenceTypeSet refs = UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASSUBTYPE);
43011 UA_ExpandedNodeId *typeCandidates = NULL;
43012 size_t typeCandidatesSize = 0;
43013 res = browseRecursive(server, startNodesSize: 1, startNodes: &node->dataType,
43014 browseDirection: UA_BROWSEDIRECTION_BOTH, refTypes: &refs,
43015 nodeClassMask: UA_NODECLASS_DATATYPE, false,
43016 resultsSize: &typeCandidatesSize, results: &typeCandidates);
43017 if(res != UA_STATUSCODE_GOOD)
43018 return res;
43019
43020 for(size_t i = 0; i < typeCandidatesSize; i++) {
43021 /* Skip BaseDataType (Variant). This is the root of the DataType
43022 * hierarchy. Variables of BaseDataType can be empty. */
43023 if(UA_NodeId_equal(p1: &UA_TYPES[UA_TYPES_VARIANT].typeId,
43024 p2: &typeCandidates[i].nodeId))
43025 continue;
43026
43027 /* Skip ExtensionObject. Even though we can encode the type it is
43028 * abstract and nodes should not contain them as value. */
43029 if(UA_NodeId_equal(p1: &UA_TYPES[UA_TYPES_EXTENSIONOBJECT].typeId,
43030 p2: &typeCandidates[i].nodeId))
43031 continue;
43032
43033 /* Get the type encoding information */
43034 type = UA_Server_findDataType(server, typeId: &typeCandidates[i].nodeId);
43035 if(type)
43036 break;
43037 }
43038
43039 UA_Array_delete(p: typeCandidates, size: typeCandidatesSize,
43040 type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
43041 if(!type)
43042 return UA_STATUSCODE_BADTYPEMISMATCH;
43043 }
43044
43045 /* Set up the value with the default content */
43046 UA_Variant val;
43047 UA_Variant_init(p: &val);
43048 if(node->valueRank < 0) {
43049 /* Set a scalar */
43050 void *data = UA_new(type);
43051 if(!data)
43052 return UA_STATUSCODE_BADOUTOFMEMORY;
43053 UA_Variant_setScalar(v: &val, p: data, type);
43054 } else {
43055 /* Set an array
43056 *
43057 * https://reference.opcfoundation.org/v104/Core/docs/Part3/5.6.2/#Table13
43058 * specifies ArrayDimensions as follows: This Attribute specifies the
43059 * maximum supported length of each dimension. If the maximum is unknown
43060 * the value shall be 0. The number of elements shall be equal to the
43061 * value of the ValueRank Attribute. This Attribute shall be null if
43062 * ValueRank <= 0.
43063 *
43064 * The (variant) values themselves cannot have ArrayDimensions with a
43065 * dimension length of zero. We however consider that empty arrays
43066 * (null-array or length zero) have implicit array dimensions [0,0,...].
43067 * With the appropriate number of dimensions. So they always match.
43068 *
43069 * We automatically create a null array during the node creation when
43070 * required for the type-checking..
43071 *
43072 * Also see the method 'compatibleValueArrayDimensions' where the
43073 * compatibility of the ArrayDimensions is checked. */
43074 UA_Variant_setArray(v: &val, NULL, arraySize: 0, type);
43075 }
43076
43077 /* Write the value */
43078 res = writeAttribute(server, session: &server->adminSession, nodeId: &node->head.nodeId,
43079 attributeId: UA_ATTRIBUTEID_VALUE, attr: &val, attr_type: &UA_TYPES[UA_TYPES_VARIANT]);
43080
43081 /* Clean up */
43082 UA_Variant_clear(p: &val);
43083 return res;
43084}
43085
43086static UA_StatusCode
43087typeCheckVariableNode(UA_Server *server, UA_Session *session,
43088 const UA_VariableNode *node,
43089 const UA_VariableTypeNode *vt) {
43090 /* Check the datatype against the vt */
43091 if(!compatibleDataTypes(server, dataType: &node->dataType, constraintDataType: &vt->dataType)) {
43092 logAddNode(logger: server->config.logging, session, nodeId: &node->head.nodeId,
43093 msg: "The value of is incompatible with "
43094 "the datatype of the VariableType");
43095 return UA_STATUSCODE_BADTYPEMISMATCH;
43096 }
43097
43098 /* Check valueRank against array dimensions */
43099 if(!compatibleValueRankArrayDimensions(server, session, valueRank: node->valueRank,
43100 arrayDimensionsSize: node->arrayDimensionsSize)) {
43101 logAddNode(logger: server->config.logging, session, nodeId: &node->head.nodeId,
43102 msg: "The value rank of is incompatible with its array dimensions");
43103 return UA_STATUSCODE_BADTYPEMISMATCH;
43104 }
43105
43106 /* Check valueRank against the vt */
43107 if(!compatibleValueRanks(valueRank: node->valueRank, constraintValueRank: vt->valueRank)) {
43108 logAddNode(logger: server->config.logging, session, nodeId: &node->head.nodeId,
43109 msg: "The value rank is incompatible "
43110 "with the value rank of the VariableType");
43111 return UA_STATUSCODE_BADTYPEMISMATCH;
43112 }
43113
43114 /* Check array dimensions against the vt */
43115 if(!compatibleArrayDimensions(constraintArrayDimensionsSize: vt->arrayDimensionsSize, constraintArrayDimensions: vt->arrayDimensions,
43116 testArrayDimensionsSize: node->arrayDimensionsSize, testArrayDimensions: node->arrayDimensions)) {
43117 logAddNode(logger: server->config.logging, session, nodeId: &node->head.nodeId,
43118 msg: "The array dimensions are incompatible with the "
43119 "array dimensions of the VariableType");
43120 return UA_STATUSCODE_BADTYPEMISMATCH;
43121 }
43122
43123 /* Typecheck the value. Less strict for NS0 -- we adjust nodes after loading
43124 * the generated definitions. */
43125 if(server->bootstrapNS0)
43126 return UA_STATUSCODE_GOOD;
43127
43128 /* The value might come from a datasource, so we perform a
43129 * regular read. */
43130 UA_DataValue value;
43131 UA_DataValue_init(p: &value);
43132 UA_StatusCode retval = readValueAttribute(server, session, vn: node, v: &value);
43133 if(retval != UA_STATUSCODE_GOOD)
43134 return retval;
43135
43136 /* We have a value. Write it back to perform checks and adjustments. */
43137 const char *reason;
43138 if(node->valueSource == UA_VALUESOURCE_DATA && value.hasValue) {
43139 if(!compatibleValue(server, session, targetDataTypeId: &node->dataType, targetValueRank: node->valueRank,
43140 targetArrayDimensionsSize: node->arrayDimensionsSize, targetArrayDimensions: node->arrayDimensions,
43141 value: &value.value, NULL, reason: &reason)) {
43142 retval = writeAttribute(server, session, nodeId: &node->head.nodeId,
43143 attributeId: UA_ATTRIBUTEID_VALUE, attr: &value.value,
43144 attr_type: &UA_TYPES[UA_TYPES_VARIANT]);
43145 }
43146 UA_DataValue_clear(p: &value);
43147 return retval;
43148 }
43149
43150 /* Only BaseDataType (Variant) can have empty values */
43151 if(!value.hasValue &&
43152 !UA_NodeId_equal(p1: &node->dataType, p2: &UA_TYPES[UA_TYPES_VARIANT].typeId)) {
43153 /* Warn if that is configured */
43154 if(server->config.allowEmptyVariables != UA_RULEHANDLING_ACCEPT)
43155 UA_LOG_NODEID_DEBUG(&node->head.nodeId,
43156 UA_LOG_DEBUG_SESSION(server->config.logging, session,
43157 "AddNode (%.*s): The value is empty. "
43158 "But this is only allowed for BaseDataType. "
43159 "Create a matching default value.",
43160 (int)nodeIdStr.length, nodeIdStr.data));
43161
43162 /* Abort if that is configured */
43163 if(server->config.allowEmptyVariables == UA_RULEHANDLING_ABORT)
43164 retval = UA_STATUSCODE_BADTYPEMISMATCH;
43165
43166 /* Try to generate and write a default value */
43167 if(server->config.allowEmptyVariables == UA_RULEHANDLING_DEFAULT) {
43168 retval = setDefaultValue(server, node);
43169 if(retval != UA_STATUSCODE_GOOD) {
43170 UA_LOG_NODEID_INFO(&node->head.nodeId,
43171 UA_LOG_INFO_SESSION(server->config.logging, session,
43172 "AddNode (%.*s): Could not create a default value "
43173 "with StatusCode %s", (int)nodeIdStr.length,
43174 nodeIdStr.data, UA_StatusCode_name(retval)));
43175 }
43176 }
43177 return retval;
43178 }
43179
43180 /* Type-check the value */
43181 UA_Boolean compatible =
43182 compatibleValue(server, session, targetDataTypeId: &node->dataType,
43183 targetValueRank: node->valueRank, targetArrayDimensionsSize: node->arrayDimensionsSize,
43184 targetArrayDimensions: node->arrayDimensions, value: &value.value, NULL, reason: &reason);
43185 if(!compatible) {
43186 UA_LOG_NODEID_INFO(&node->head.nodeId,
43187 UA_LOG_INFO_SESSION(server->config.logging, session,
43188 "AddNode (%.*s): The VariableNode value has "
43189 "failed the type check with reason %s. ",
43190 (int)nodeIdStr.length, nodeIdStr.data, reason));
43191 retval = UA_STATUSCODE_BADINTERNALERROR;
43192 }
43193
43194 UA_DataValue_clear(p: &value);
43195 return retval;
43196}
43197
43198/********************/
43199/* Instantiate Node */
43200/********************/
43201
43202static const UA_NodeId baseDataVariableType =
43203 {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_BASEDATAVARIABLETYPE}};
43204static const UA_NodeId baseObjectType =
43205 {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_BASEOBJECTTYPE}};
43206static const UA_NodeId hasTypeDefinition =
43207 {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASTYPEDEFINITION}};
43208
43209/* Use attributes from the variable type wherever required. Reload the node if
43210 * changes were made. */
43211static UA_StatusCode
43212useVariableTypeAttributes(UA_Server *server, UA_Session *session,
43213 const UA_VariableNode *node,
43214 const UA_VariableTypeNode *vt) {
43215 /* If no value is set, see if the vt provides one and copy it. This needs to
43216 * be done before copying the datatype from the vt, as setting the datatype
43217 * triggers a typecheck. */
43218 UA_Variant orig;
43219 UA_StatusCode retval =
43220 readWithReadValue(server, nodeId: &node->head.nodeId, attributeId: UA_ATTRIBUTEID_VALUE, v: &orig);
43221 if(retval != UA_STATUSCODE_GOOD)
43222 return retval;
43223
43224 if(orig.type) {
43225 /* A value is present */
43226 UA_Variant_clear(p: &orig);
43227 } else {
43228 UA_DataValue v;
43229 UA_DataValue_init(p: &v);
43230 retval = readValueAttribute(server, session, vn: (const UA_VariableNode*)vt, v: &v);
43231 if(retval == UA_STATUSCODE_GOOD && v.hasValue) {
43232 retval = writeAttribute(server, session, nodeId: &node->head.nodeId,
43233 attributeId: UA_ATTRIBUTEID_VALUE, attr: &v.value,
43234 attr_type: &UA_TYPES[UA_TYPES_VARIANT]);
43235 }
43236 UA_DataValue_clear(p: &v);
43237
43238 if(retval != UA_STATUSCODE_GOOD) {
43239 logAddNode(logger: server->config.logging, session, nodeId: &node->head.nodeId,
43240 msg: "The default content of the VariableType could "
43241 "not be used. This may happen if the VariableNode "
43242 "makes additional restrictions.");
43243 retval = UA_STATUSCODE_GOOD;
43244 }
43245 }
43246
43247 /* If no datatype is given, use the datatype of the vt */
43248 if(UA_NodeId_isNull(p: &node->dataType)) {
43249 logAddNode(logger: server->config.logging, session, nodeId: &node->head.nodeId,
43250 msg: "No datatype given; Copy the datatype attribute "
43251 "from the TypeDefinition");
43252 retval = writeAttribute(server, session, nodeId: &node->head.nodeId,
43253 attributeId: UA_ATTRIBUTEID_DATATYPE, attr: &vt->dataType,
43254 attr_type: &UA_TYPES[UA_TYPES_NODEID]);
43255 if(retval != UA_STATUSCODE_GOOD)
43256 return retval;
43257 }
43258
43259 /* Use the ArrayDimensions of the vt */
43260 if(node->arrayDimensionsSize == 0 && vt->arrayDimensionsSize > 0) {
43261 UA_Variant v;
43262 UA_Variant_init(p: &v);
43263 UA_Variant_setArray(v: &v, array: vt->arrayDimensions, arraySize: vt->arrayDimensionsSize,
43264 type: &UA_TYPES[UA_TYPES_UINT32]);
43265 retval = writeAttribute(server, session, nodeId: &node->head.nodeId,
43266 attributeId: UA_ATTRIBUTEID_ARRAYDIMENSIONS, attr: &v,
43267 attr_type: &UA_TYPES[UA_TYPES_VARIANT]);
43268 }
43269
43270 return retval;
43271}
43272
43273/* Search for an instance of "browseName" in node searchInstance. Used during
43274 * copyChildNodes to find overwritable/mergable nodes. Does not touch
43275 * outInstanceNodeId if no child is found. */
43276static UA_StatusCode
43277findChildByBrowsename(UA_Server *server, UA_Session *session,
43278 const UA_NodeId *searchInstance,
43279 const UA_QualifiedName *browseName,
43280 UA_NodeId *outInstanceNodeId) {
43281 UA_BrowseDescription bd;
43282 UA_BrowseDescription_init(p: &bd);
43283 bd.nodeId = *searchInstance;
43284 bd.referenceTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_AGGREGATES);
43285 bd.includeSubtypes = true;
43286 bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;
43287 bd.nodeClassMask = UA_NODECLASS_OBJECT | UA_NODECLASS_VARIABLE | UA_NODECLASS_METHOD;
43288 bd.resultMask = UA_BROWSERESULTMASK_BROWSENAME;
43289
43290 UA_BrowseResult br;
43291 UA_BrowseResult_init(p: &br);
43292 UA_UInt32 maxrefs = 0;
43293 Operation_Browse(server, session, maxrefs: &maxrefs, descr: &bd, result: &br);
43294 if(br.statusCode != UA_STATUSCODE_GOOD)
43295 return br.statusCode;
43296
43297 UA_StatusCode retval = UA_STATUSCODE_GOOD;
43298 for(size_t i = 0; i < br.referencesSize; ++i) {
43299 UA_ReferenceDescription *rd = &br.references[i];
43300 if(rd->browseName.namespaceIndex == browseName->namespaceIndex &&
43301 UA_String_equal(p1: &rd->browseName.name, p2: &browseName->name)) {
43302 retval = UA_NodeId_copy(src: &rd->nodeId.nodeId, dst: outInstanceNodeId);
43303 break;
43304 }
43305 }
43306
43307 UA_BrowseResult_clear(p: &br);
43308 return retval;
43309}
43310
43311static const UA_ExpandedNodeId mandatoryId =
43312 {{0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_MODELLINGRULE_MANDATORY}}, {0, NULL}, 0};
43313
43314static UA_Boolean
43315isMandatoryChild(UA_Server *server, UA_Session *session,
43316 const UA_NodeId *childNodeId) {
43317 /* Get the child */
43318 const UA_Node *child = UA_NODESTORE_GET(server, nodeId: childNodeId);
43319 if(!child)
43320 return false;
43321
43322 /* Look for the reference making the child mandatory */
43323 UA_Boolean found = false;
43324 for(size_t i = 0; i < child->head.referencesSize; ++i) {
43325 UA_NodeReferenceKind *rk = &child->head.references[i];
43326 if(rk->referenceTypeIndex != UA_REFERENCETYPEINDEX_HASMODELLINGRULE)
43327 continue;
43328 if(rk->isInverse)
43329 continue;
43330
43331 if(UA_NodeReferenceKind_findTarget(rk, targetId: &mandatoryId)) {
43332 found = true;
43333 break;
43334 }
43335 }
43336
43337 UA_NODESTORE_RELEASE(server, child);
43338 return found;
43339}
43340
43341static UA_StatusCode
43342copyAllChildren(UA_Server *server, UA_Session *session,
43343 const UA_NodeId *source, const UA_NodeId *destination);
43344
43345static void
43346Operation_addReference(UA_Server *server, UA_Session *session, void *context,
43347 const UA_AddReferencesItem *item, UA_StatusCode *retval);
43348
43349UA_StatusCode
43350addRefWithSession(UA_Server *server, UA_Session *session, const UA_NodeId *sourceId,
43351 const UA_NodeId *referenceTypeId, const UA_NodeId *targetId,
43352 UA_Boolean forward) {
43353 UA_AddReferencesItem ref_item;
43354 UA_AddReferencesItem_init(p: &ref_item);
43355 ref_item.sourceNodeId = *sourceId;
43356 ref_item.referenceTypeId = *referenceTypeId;
43357 ref_item.isForward = forward;
43358 ref_item.targetNodeId.nodeId = *targetId;
43359
43360 UA_StatusCode retval = UA_STATUSCODE_GOOD;
43361 Operation_addReference(server, session, NULL, item: &ref_item, retval: &retval);
43362 return retval;
43363}
43364
43365UA_StatusCode
43366addRef(UA_Server *server, const UA_NodeId sourceId,
43367 const UA_NodeId referenceTypeId, const UA_NodeId targetId,
43368 UA_Boolean forward) {
43369 return addRefWithSession(server, session: &server->adminSession, sourceId: &sourceId,
43370 referenceTypeId: &referenceTypeId, targetId: &targetId, forward);
43371}
43372
43373static UA_StatusCode
43374addInterfaceChildren(UA_Server *server, UA_Session *session,
43375 const UA_NodeId *nodeId, const UA_NodeId *typeId) {
43376 /* Get the hierarchy of the type and all its supertypes */
43377 UA_NodeId *hierarchy = NULL;
43378 size_t hierarchySize = 0;
43379 UA_StatusCode retval = getAllInterfaceChildNodeIds(server, objectNode: nodeId, objectTypeNode: typeId,
43380 interfaceChildNodes: &hierarchy, interfaceChildNodesSize: &hierarchySize);
43381 if(retval != UA_STATUSCODE_GOOD)
43382 return retval;
43383
43384 /* Copy members of the type and supertypes (and instantiate them) */
43385 for(size_t i = 0; i < hierarchySize; ++i) {
43386 retval = copyAllChildren(server, session, source: &hierarchy[i], destination: nodeId);
43387 if(retval != UA_STATUSCODE_GOOD) {
43388 UA_Array_delete(p: hierarchy, size: hierarchySize, type: &UA_TYPES[UA_TYPES_NODEID]);
43389 return retval;
43390 }
43391 }
43392
43393 for(size_t i = 0; i < hierarchySize; ++i) {
43394 UA_NodeId refId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASINTERFACE);
43395 retval = addRef(server, sourceId: *nodeId, referenceTypeId: refId, targetId: hierarchy[i], true);
43396
43397 /* Don't add the original HasInterface reference to ObjectType sub nodes */
43398 if(retval == UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED) {
43399 retval = UA_STATUSCODE_GOOD;
43400 } else if(retval != UA_STATUSCODE_GOOD) {
43401 break;
43402 }
43403 }
43404
43405 UA_Array_delete(p: hierarchy, size: hierarchySize, type: &UA_TYPES[UA_TYPES_NODEID]);
43406 return retval;
43407}
43408
43409static UA_StatusCode
43410copyChild(UA_Server *server, UA_Session *session,
43411 const UA_NodeId *destinationNodeId,
43412 const UA_ReferenceDescription *rd) {
43413 UA_assert(session);
43414 UA_LOCK_ASSERT(&server->serviceMutex, 1);
43415
43416 /* Is there an existing child with the browsename? */
43417 UA_NodeId existingChild = UA_NODEID_NULL;
43418 UA_StatusCode retval = findChildByBrowsename(server, session, searchInstance: destinationNodeId,
43419 browseName: &rd->browseName, outInstanceNodeId: &existingChild);
43420 if(retval != UA_STATUSCODE_GOOD)
43421 return retval;
43422
43423 /* Have a child with that browseName. Deep-copy missing members. */
43424 if(!UA_NodeId_isNull(p: &existingChild)) {
43425 if(rd->nodeClass == UA_NODECLASS_VARIABLE ||
43426 rd->nodeClass == UA_NODECLASS_OBJECT)
43427 retval = copyAllChildren(server, session, source: &rd->nodeId.nodeId, destination: &existingChild);
43428 UA_NodeId_clear(p: &existingChild);
43429 return retval;
43430 }
43431
43432 /* Is the child mandatory? If not, ask callback whether child should be instantiated.
43433 * If not, skip. */
43434 if(!isMandatoryChild(server, session, childNodeId: &rd->nodeId.nodeId)) {
43435 if(!server->config.nodeLifecycle.createOptionalChild)
43436 return UA_STATUSCODE_GOOD;
43437 UA_Boolean createChild = server->config.nodeLifecycle.
43438 createOptionalChild(server, &session->sessionId, session->sessionHandle,
43439 &rd->nodeId.nodeId, destinationNodeId, &rd->referenceTypeId);
43440 if(!createChild)
43441 return UA_STATUSCODE_GOOD;
43442 }
43443
43444 /* Child is a method -> create a reference */
43445 if(rd->nodeClass == UA_NODECLASS_METHOD) {
43446 UA_AddReferencesItem newItem;
43447 UA_AddReferencesItem_init(p: &newItem);
43448 newItem.sourceNodeId = *destinationNodeId;
43449 newItem.referenceTypeId = rd->referenceTypeId;
43450 newItem.isForward = true;
43451 newItem.targetNodeId = rd->nodeId;
43452 newItem.targetNodeClass = UA_NODECLASS_METHOD;
43453 Operation_addReference(server, session, NULL, item: &newItem, retval: &retval);
43454 return retval;
43455 }
43456
43457 /* Child is a variable or object */
43458 if(rd->nodeClass == UA_NODECLASS_VARIABLE ||
43459 rd->nodeClass == UA_NODECLASS_OBJECT) {
43460 /* Make a copy of the node */
43461 UA_Node *node;
43462 retval = UA_NODESTORE_GETCOPY(server, &rd->nodeId.nodeId, &node);
43463 if(retval != UA_STATUSCODE_GOOD)
43464 return retval;
43465
43466 /* Remove the context of the copied node */
43467 node->head.context = NULL;
43468 node->head.constructed = false;
43469#ifdef UA_ENABLE_SUBSCRIPTIONS
43470 node->head.monitoredItems = NULL;
43471#endif
43472
43473 /* The value backend is copied by default. But we don't want to keep it
43474 * here. */
43475 if(node->head.nodeClass == UA_NODECLASS_VARIABLE ||
43476 node->head.nodeClass == UA_NODECLASS_VARIABLETYPE) {
43477 if(node->variableNode.valueSource != UA_VALUESOURCE_DATA)
43478 memset(s: &node->variableNode.value, c: 0, n: sizeof(node->variableNode.value));
43479 node->variableNode.valueSource = UA_VALUESOURCE_DATA;
43480 memset(s: &node->variableNode.valueBackend, c: 0, n: sizeof(UA_ValueBackend));
43481 }
43482
43483 /* Reset the NodeId (random numeric id will be assigned in the nodestore) */
43484 UA_NodeId_clear(p: &node->head.nodeId);
43485 node->head.nodeId.namespaceIndex = destinationNodeId->namespaceIndex;
43486
43487 if(server->config.nodeLifecycle.generateChildNodeId) {
43488 retval = server->config.nodeLifecycle.
43489 generateChildNodeId(server, &session->sessionId, session->sessionHandle,
43490 &rd->nodeId.nodeId, destinationNodeId,
43491 &rd->referenceTypeId, &node->head.nodeId);
43492 if(retval != UA_STATUSCODE_GOOD) {
43493 UA_NODESTORE_DELETE(server, node);
43494 return retval;
43495 }
43496 }
43497
43498 /* Remove references, they are re-created from scratch in addnode_finish */
43499 /* TODO: Be more clever in removing references that are re-added during
43500 * addnode_finish. That way, we can call addnode_finish also on children that were
43501 * manually added by the user during addnode_begin and addnode_finish. */
43502 /* For now we keep all the modelling rule references and delete all others */
43503 const UA_NodeId nodeId_typesFolder= UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_TYPESFOLDER);
43504 const UA_ReferenceTypeSet reftypes_aggregates =
43505 UA_REFTYPESET(UA_REFERENCETYPEINDEX_AGGREGATES);
43506 UA_ReferenceTypeSet reftypes_skipped;
43507 /* Check if the hasModellingRule-reference is required (configured or node in an
43508 instance declaration) */
43509 if(server->config.modellingRulesOnInstances ||
43510 isNodeInTree(server, leafNode: destinationNodeId,
43511 nodeToFind: &nodeId_typesFolder, relevantRefs: &reftypes_aggregates)) {
43512 reftypes_skipped = UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASMODELLINGRULE);
43513 } else {
43514 UA_ReferenceTypeSet_init(set: &reftypes_skipped);
43515 }
43516 reftypes_skipped = UA_ReferenceTypeSet_union(setA: reftypes_skipped, setB: UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASINTERFACE));
43517 UA_Node_deleteReferencesSubset(node, keepSet: &reftypes_skipped);
43518
43519 /* Add the node to the nodestore */
43520 UA_NodeId newNodeId = UA_NODEID_NULL;
43521 retval = UA_NODESTORE_INSERT(server, node, &newNodeId);
43522 /* node = NULL; The pointer is no longer valid */
43523 if(retval != UA_STATUSCODE_GOOD)
43524 return retval;
43525
43526 /* Add the node references */
43527 retval = addNode_addRefs(server, session, nodeId: &newNodeId, parentNodeId: destinationNodeId,
43528 referenceTypeId: &rd->referenceTypeId, typeDefinitionId: &rd->typeDefinition.nodeId);
43529 if(retval != UA_STATUSCODE_GOOD) {
43530 UA_NODESTORE_REMOVE(server, &newNodeId);
43531 UA_NodeId_clear(p: &newNodeId);
43532 return retval;
43533 }
43534
43535 if (rd->nodeClass == UA_NODECLASS_VARIABLE) {
43536 retval = checkSetIsDynamicVariable(server, session, nodeId: &newNodeId);
43537
43538 if(retval != UA_STATUSCODE_GOOD) {
43539 UA_NODESTORE_REMOVE(server, &newNodeId);
43540 return retval;
43541 }
43542 }
43543
43544 /* For the new child, recursively copy the members of the original. No
43545 * typechecking is performed here. Assuming that the original is
43546 * consistent. */
43547 retval = copyAllChildren(server, session, source: &rd->nodeId.nodeId, destination: &newNodeId);
43548 if(retval != UA_STATUSCODE_GOOD) {
43549 deleteNode(server, nodeId: newNodeId, true);
43550 return retval;
43551 }
43552
43553 /* Check if its a dynamic variable, add all type and/or interface
43554 * children and call the constructor */
43555 retval = addNode_finish(server, session, nodeId: &newNodeId);
43556 if(retval != UA_STATUSCODE_GOOD) {
43557 deleteNode(server, nodeId: newNodeId, true);
43558 return retval;
43559 }
43560
43561 /* Clean up. Because it can happen that a string is assigned as ID at
43562 * generateChildNodeId. */
43563 UA_NodeId_clear(p: &newNodeId);
43564 }
43565
43566 return retval;
43567}
43568
43569/* Copy any children of Node sourceNodeId to another node destinationNodeId. */
43570static UA_StatusCode
43571copyAllChildren(UA_Server *server, UA_Session *session,
43572 const UA_NodeId *source, const UA_NodeId *destination) {
43573 /* Browse to get all children of the source */
43574 UA_BrowseDescription bd;
43575 UA_BrowseDescription_init(p: &bd);
43576 bd.nodeId = *source;
43577 bd.referenceTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_AGGREGATES);
43578 bd.includeSubtypes = true;
43579 bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;
43580 bd.nodeClassMask = UA_NODECLASS_OBJECT | UA_NODECLASS_VARIABLE | UA_NODECLASS_METHOD;
43581 bd.resultMask = UA_BROWSERESULTMASK_REFERENCETYPEID | UA_BROWSERESULTMASK_NODECLASS |
43582 UA_BROWSERESULTMASK_BROWSENAME | UA_BROWSERESULTMASK_TYPEDEFINITION;
43583
43584 UA_BrowseResult br;
43585 UA_BrowseResult_init(p: &br);
43586 UA_UInt32 maxrefs = 0;
43587 Operation_Browse(server, session, maxrefs: &maxrefs, descr: &bd, result: &br);
43588 if(br.statusCode != UA_STATUSCODE_GOOD)
43589 return br.statusCode;
43590
43591 UA_StatusCode retval = UA_STATUSCODE_GOOD;
43592 for(size_t i = 0; i < br.referencesSize; ++i) {
43593 UA_ReferenceDescription *rd = &br.references[i];
43594 retval = copyChild(server, session, destinationNodeId: destination, rd);
43595 if(retval != UA_STATUSCODE_GOOD)
43596 break;
43597 }
43598
43599 UA_BrowseResult_clear(p: &br);
43600 return retval;
43601}
43602
43603static UA_StatusCode
43604addTypeChildren(UA_Server *server, UA_Session *session,
43605 const UA_NodeId *nodeId, const UA_NodeId *typeId) {
43606 /* Get the hierarchy of the type and all its supertypes */
43607 UA_NodeId *hierarchy = NULL;
43608 size_t hierarchySize = 0;
43609 UA_StatusCode retval = getParentTypeAndInterfaceHierarchy(server, typeNode: typeId,
43610 typeHierarchy: &hierarchy, typeHierarchySize: &hierarchySize);
43611 if(retval != UA_STATUSCODE_GOOD)
43612 return retval;
43613 UA_assert(hierarchySize < 1000);
43614
43615 /* Copy members of the type and supertypes (and instantiate them) */
43616 for(size_t i = 0; i < hierarchySize; ++i) {
43617 retval = copyAllChildren(server, session, source: &hierarchy[i], destination: nodeId);
43618 if(retval != UA_STATUSCODE_GOOD)
43619 break;
43620 }
43621
43622 UA_Array_delete(p: hierarchy, size: hierarchySize, type: &UA_TYPES[UA_TYPES_NODEID]);
43623 return retval;
43624}
43625
43626/************/
43627/* Add Node */
43628/************/
43629
43630static const UA_NodeId hasSubtype = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASSUBTYPE}};
43631
43632UA_StatusCode
43633addNode_addRefs(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId,
43634 const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId,
43635 const UA_NodeId *typeDefinitionId) {
43636 /* Get the node */
43637 const UA_Node *type = NULL;
43638 const UA_Node *node = UA_NODESTORE_GET(server, nodeId);
43639 if(!node)
43640 return UA_STATUSCODE_BADNODEIDUNKNOWN;
43641
43642 /* Use the typeDefinition as parent for type-nodes */
43643 const UA_NodeHead *head = &node->head;
43644 if(head->nodeClass == UA_NODECLASS_VARIABLETYPE ||
43645 head->nodeClass == UA_NODECLASS_OBJECTTYPE ||
43646 head->nodeClass == UA_NODECLASS_REFERENCETYPE ||
43647 head->nodeClass == UA_NODECLASS_DATATYPE) {
43648 if(UA_NodeId_equal(p1: referenceTypeId, p2: &UA_NODEID_NULL))
43649 referenceTypeId = &hasSubtype;
43650 const UA_Node *parentNode = UA_NODESTORE_GET(server, nodeId: parentNodeId);
43651 if(parentNode) {
43652 if(parentNode->head.nodeClass == head->nodeClass)
43653 typeDefinitionId = parentNodeId;
43654 UA_NODESTORE_RELEASE(server, parentNode);
43655 }
43656 }
43657
43658 UA_StatusCode retval;
43659 /* Make sure newly created node does not have itself as parent */
43660 if(UA_NodeId_equal(p1: nodeId, p2: parentNodeId)) {
43661 logAddNode(logger: server->config.logging, session, nodeId,
43662 msg: "A node cannot have itself as parent");
43663 retval = UA_STATUSCODE_BADINVALIDARGUMENT;
43664 goto cleanup;
43665 }
43666
43667
43668 /* Check parent reference. Objects may have no parent. */
43669 retval = checkParentReference(server, session, head, parentNodeId, referenceTypeId);
43670 if(retval != UA_STATUSCODE_GOOD) {
43671 logAddNode(logger: server->config.logging, session, nodeId,
43672 msg: "The parent reference for is invalid");
43673 goto cleanup;
43674 }
43675
43676 /* Replace empty typeDefinition with the most permissive default */
43677 if((head->nodeClass == UA_NODECLASS_VARIABLE ||
43678 head->nodeClass == UA_NODECLASS_OBJECT) &&
43679 UA_NodeId_isNull(p: typeDefinitionId)) {
43680 logAddNode(logger: server->config.logging, session, nodeId,
43681 msg: "No TypeDefinition. Use the default "
43682 "TypeDefinition for the Variable/Object");
43683 if(head->nodeClass == UA_NODECLASS_VARIABLE)
43684 typeDefinitionId = &baseDataVariableType;
43685 else
43686 typeDefinitionId = &baseObjectType;
43687 }
43688
43689 /* Get the node type. There must be a typedefinition for variables, objects
43690 * and type-nodes. See the above checks. */
43691 if(!UA_NodeId_isNull(p: typeDefinitionId)) {
43692 /* Get the type node */
43693 type = UA_NODESTORE_GET(server, nodeId: typeDefinitionId);
43694 if(!type) {
43695 logAddNode(logger: server->config.logging, session, nodeId, msg: "Node type not found");
43696 retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
43697 goto cleanup;
43698 }
43699
43700 UA_Boolean typeOk = false;
43701 const UA_NodeHead *typeHead = &type->head;
43702 switch(head->nodeClass) {
43703 case UA_NODECLASS_DATATYPE:
43704 typeOk = typeHead->nodeClass == UA_NODECLASS_DATATYPE;
43705 break;
43706 case UA_NODECLASS_METHOD:
43707 typeOk = typeHead->nodeClass == UA_NODECLASS_METHOD;
43708 break;
43709 case UA_NODECLASS_OBJECT:
43710 case UA_NODECLASS_OBJECTTYPE:
43711 typeOk = typeHead->nodeClass == UA_NODECLASS_OBJECTTYPE;
43712 break;
43713 case UA_NODECLASS_REFERENCETYPE:
43714 typeOk = typeHead->nodeClass == UA_NODECLASS_REFERENCETYPE;
43715 break;
43716 case UA_NODECLASS_VARIABLE:
43717 case UA_NODECLASS_VARIABLETYPE:
43718 typeOk = typeHead->nodeClass == UA_NODECLASS_VARIABLETYPE;
43719 break;
43720 case UA_NODECLASS_VIEW:
43721 typeOk = typeHead->nodeClass == UA_NODECLASS_VIEW;
43722 break;
43723 default:
43724 typeOk = false;
43725 }
43726 if(!typeOk) {
43727 logAddNode(logger: server->config.logging, session, nodeId,
43728 msg: "Type does not match the NodeClass");
43729 retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
43730 goto cleanup;
43731 }
43732
43733 /* See if the type has the correct node class. For type-nodes, we know
43734 * that type has the same nodeClass from checkParentReference. */
43735 if(head->nodeClass == UA_NODECLASS_VARIABLE &&
43736 type->variableTypeNode.isAbstract) {
43737 /* Get subtypes of the parent reference types */
43738 UA_ReferenceTypeSet refTypes1, refTypes2;
43739 retval |= referenceTypeIndices(server, refType: &parentReferences[0], indices: &refTypes1, true);
43740 retval |= referenceTypeIndices(server, refType: &parentReferences[1], indices: &refTypes2, true);
43741 UA_ReferenceTypeSet refTypes = UA_ReferenceTypeSet_union(setA: refTypes1, setB: refTypes2);
43742 if(retval != UA_STATUSCODE_GOOD)
43743 goto cleanup;
43744
43745 /* Abstract variable is allowed if parent is a children of a
43746 * base data variable. An abstract variable may be part of an
43747 * object type which again is below BaseObjectType */
43748 const UA_NodeId variableTypes = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEDATAVARIABLETYPE);
43749 const UA_NodeId objectTypes = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEOBJECTTYPE);
43750 if(!isNodeInTree(server, leafNode: parentNodeId, nodeToFind: &variableTypes, relevantRefs: &refTypes) &&
43751 !isNodeInTree(server, leafNode: parentNodeId, nodeToFind: &objectTypes, relevantRefs: &refTypes)) {
43752 logAddNode(logger: server->config.logging, session, nodeId,
43753 msg: "Type of variable node must be a "
43754 "VariableType and not cannot be abstract");
43755 retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
43756 goto cleanup;
43757 }
43758 }
43759
43760 if(head->nodeClass == UA_NODECLASS_OBJECT &&
43761 type->objectTypeNode.isAbstract) {
43762 /* Get subtypes of the parent reference types */
43763 UA_ReferenceTypeSet refTypes1, refTypes2;
43764 retval |= referenceTypeIndices(server, refType: &parentReferences[0], indices: &refTypes1, true);
43765 retval |= referenceTypeIndices(server, refType: &parentReferences[1], indices: &refTypes2, true);
43766 UA_ReferenceTypeSet refTypes = UA_ReferenceTypeSet_union(setA: refTypes1, setB: refTypes2);
43767 if(retval != UA_STATUSCODE_GOOD)
43768 goto cleanup;
43769
43770
43771 /* Object node created of an abstract ObjectType. Only allowed if
43772 * within BaseObjectType folder or if it's an event (subType of
43773 * BaseEventType) */
43774 const UA_NodeId objectTypes = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEOBJECTTYPE);
43775 UA_Boolean isInBaseObjectType =
43776 isNodeInTree(server, leafNode: parentNodeId, nodeToFind: &objectTypes, relevantRefs: &refTypes);
43777
43778 const UA_NodeId eventTypes = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEEVENTTYPE);
43779 UA_Boolean isInBaseEventType =
43780 isNodeInTree_singleRef(server, leafNode: &type->head.nodeId, nodeToFind: &eventTypes,
43781 UA_REFERENCETYPEINDEX_HASSUBTYPE);
43782
43783 if(!isInBaseObjectType &&
43784 !(isInBaseEventType && UA_NodeId_isNull(p: parentNodeId))) {
43785 logAddNode(logger: server->config.logging, session, nodeId,
43786 msg: "Type of ObjectNode must be ObjectType and not be abstract");
43787 retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
43788 goto cleanup;
43789 }
43790 }
43791 }
43792
43793 /* Add reference to the parent */
43794 if(!UA_NodeId_isNull(p: parentNodeId)) {
43795 if(UA_NodeId_isNull(p: referenceTypeId)) {
43796 logAddNode(logger: server->config.logging, session, nodeId,
43797 msg: "Reference to parent cannot be null");
43798 retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
43799 goto cleanup;
43800 }
43801
43802 retval = addRefWithSession(server, session, sourceId: &head->nodeId, referenceTypeId,
43803 targetId: parentNodeId, false);
43804 if(retval != UA_STATUSCODE_GOOD) {
43805 logAddNode(logger: server->config.logging, session, nodeId,
43806 msg: "Adding reference to parent failed");
43807 goto cleanup;
43808 }
43809 }
43810
43811 /* Add a hasTypeDefinition reference */
43812 if(head->nodeClass == UA_NODECLASS_VARIABLE ||
43813 head->nodeClass == UA_NODECLASS_OBJECT) {
43814 UA_assert(type != NULL); /* see above */
43815 retval = addRefWithSession(server, session, sourceId: &head->nodeId, referenceTypeId: &hasTypeDefinition,
43816 targetId: &type->head.nodeId, true);
43817 if(retval != UA_STATUSCODE_GOOD) {
43818 logAddNode(logger: server->config.logging, session, nodeId,
43819 msg: "Adding a reference to the type definition failed");
43820 }
43821 }
43822
43823 cleanup:
43824 UA_NODESTORE_RELEASE(server, node);
43825 if(type)
43826 UA_NODESTORE_RELEASE(server, type);
43827 return retval;
43828}
43829
43830/* Create the node and add it to the nodestore. But don't typecheck and add
43831 * references so far */
43832UA_StatusCode
43833addNode_raw(UA_Server *server, UA_Session *session, void *nodeContext,
43834 const UA_AddNodesItem *item, UA_NodeId *outNewNodeId) {
43835 /* Do not check access for server */
43836 if(session != &server->adminSession && server->config.accessControl.allowAddNode) {
43837 UA_LOCK_ASSERT(&server->serviceMutex, 1);
43838 if(!server->config.accessControl.
43839 allowAddNode(server, &server->config.accessControl,
43840 &session->sessionId, session->sessionHandle, item)) {
43841 return UA_STATUSCODE_BADUSERACCESSDENIED;
43842 }
43843 }
43844
43845 /* Check the namespaceindex */
43846 if(item->requestedNewNodeId.nodeId.namespaceIndex >= server->namespacesSize) {
43847 UA_LOG_INFO_SESSION(server->config.logging, session,
43848 "AddNode: Namespace invalid");
43849 return UA_STATUSCODE_BADNODEIDINVALID;
43850 }
43851
43852 if(item->nodeAttributes.encoding != UA_EXTENSIONOBJECT_DECODED &&
43853 item->nodeAttributes.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) {
43854 UA_LOG_INFO_SESSION(server->config.logging, session,
43855 "AddNode: Node attributes invalid");
43856 return UA_STATUSCODE_BADINTERNALERROR;
43857 }
43858
43859 /* Create a node */
43860 UA_Node *node = UA_NODESTORE_NEW(server, item->nodeClass);
43861 if(!node) {
43862 UA_LOG_INFO_SESSION(server->config.logging, session,
43863 "AddNode: Node could not create a node "
43864 "in the nodestore");
43865 return UA_STATUSCODE_BADOUTOFMEMORY;
43866 }
43867
43868 UA_NodeId tmpOutId = UA_NODEID_NULL;
43869 /* Fill the node attributes */
43870 node->head.context = nodeContext;
43871 UA_StatusCode retval =
43872 UA_NodeId_copy(src: &item->requestedNewNodeId.nodeId, dst: &node->head.nodeId);
43873 if(retval != UA_STATUSCODE_GOOD)
43874 goto create_error;
43875
43876 retval = UA_QualifiedName_copy(src: &item->browseName, dst: &node->head.browseName);
43877 if(retval != UA_STATUSCODE_GOOD)
43878 goto create_error;
43879
43880 retval = UA_Node_setAttributes(node, attributes: item->nodeAttributes.content.decoded.data,
43881 attributeType: item->nodeAttributes.content.decoded.type);
43882 if(retval != UA_STATUSCODE_GOOD)
43883 goto create_error;
43884
43885 /* Create a current source timestamp for values that don't have any */
43886 if(node->head.nodeClass == UA_NODECLASS_VARIABLE &&
43887 !node->variableNode.value.data.value.hasSourceTimestamp) {
43888 node->variableNode.value.data.value.hasSourceTimestamp = true;
43889 node->variableNode.value.data.value.sourceTimestamp = UA_DateTime_now();
43890 }
43891
43892 /* Add the node to the nodestore */
43893 if(!outNewNodeId)
43894 outNewNodeId = &tmpOutId;
43895 retval = UA_NODESTORE_INSERT(server, node, outNewNodeId);
43896 if(retval != UA_STATUSCODE_GOOD) {
43897 UA_LOG_INFO_SESSION(server->config.logging, session,
43898 "AddNode: Node could not add the new node "
43899 "to the nodestore with error code %s",
43900 UA_StatusCode_name(retval));
43901 return retval;
43902 }
43903
43904 if(outNewNodeId == &tmpOutId)
43905 UA_NodeId_clear(p: &tmpOutId);
43906
43907 return UA_STATUSCODE_GOOD;
43908
43909create_error:
43910 UA_LOG_INFO_SESSION(server->config.logging, session,
43911 "AddNode: Node could not create a node "
43912 "with error code %s", UA_StatusCode_name(retval));
43913 UA_NODESTORE_DELETE(server, node);
43914 return retval;
43915}
43916
43917static UA_StatusCode
43918findDefaultInstanceBrowseNameNode(UA_Server *server, UA_NodeId startingNode,
43919 UA_NodeId *foundId) {
43920 UA_NodeId_init(p: foundId);
43921 UA_RelativePathElement rpe;
43922 UA_RelativePathElement_init(p: &rpe);
43923 rpe.referenceTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY);
43924 rpe.targetName = UA_QUALIFIEDNAME(nsIndex: 0, chars: "DefaultInstanceBrowseName");
43925 UA_BrowsePath bp;
43926 UA_BrowsePath_init(p: &bp);
43927 bp.startingNode = startingNode;
43928 bp.relativePath.elementsSize = 1;
43929 bp.relativePath.elements = &rpe;
43930 UA_BrowsePathResult bpr = translateBrowsePathToNodeIds(server, browsePath: &bp);
43931 UA_StatusCode retval = bpr.statusCode;
43932 if(retval == UA_STATUSCODE_GOOD && bpr.targetsSize > 0)
43933 retval = UA_NodeId_copy(src: &bpr.targets[0].targetId.nodeId, dst: foundId);
43934 UA_BrowsePathResult_clear(p: &bpr);
43935 return retval;
43936}
43937
43938/* Check if we got a valid browse name for the new node. For object nodes the
43939 * BrowseName may only be null if the parent type has a
43940 * 'DefaultInstanceBrowseName' property. */
43941static UA_StatusCode
43942checkSetBrowseName(UA_Server *server, UA_Session *session, UA_AddNodesItem *item) {
43943 /* If the object node already has a browse name we are done here. */
43944 if(!UA_QualifiedName_isNull(q: &item->browseName))
43945 return UA_STATUSCODE_GOOD;
43946
43947 /* Nodes other than Objects must have a BrowseName */
43948 if(item->nodeClass != UA_NODECLASS_OBJECT)
43949 return UA_STATUSCODE_BADBROWSENAMEINVALID;
43950
43951 /* At this point we have an object with an empty browse name. Check the type
43952 * node if it has a DefaultInstanceBrowseName property. */
43953 UA_NodeId defaultBrowseNameNode;
43954 UA_StatusCode retval =
43955 findDefaultInstanceBrowseNameNode(server, startingNode: item->typeDefinition.nodeId,
43956 foundId: &defaultBrowseNameNode);
43957 if(retval != UA_STATUSCODE_GOOD)
43958 return UA_STATUSCODE_BADBROWSENAMEINVALID;
43959
43960 UA_Variant defaultBrowseName;
43961 retval = readWithReadValue(server, nodeId: &defaultBrowseNameNode,
43962 attributeId: UA_ATTRIBUTEID_VALUE, v: &defaultBrowseName);
43963 UA_NodeId_clear(p: &defaultBrowseNameNode);
43964 if(retval != UA_STATUSCODE_GOOD)
43965 return UA_STATUSCODE_BADBROWSENAMEINVALID;
43966
43967 if(UA_Variant_hasScalarType(v: &defaultBrowseName, type: &UA_TYPES[UA_TYPES_QUALIFIEDNAME])) {
43968 item->browseName = *(UA_QualifiedName*)defaultBrowseName.data;
43969 UA_QualifiedName_init(p: (UA_QualifiedName*)defaultBrowseName.data);
43970 } else {
43971 retval = UA_STATUSCODE_BADBROWSENAMEINVALID;
43972 }
43973
43974 UA_Variant_clear(p: &defaultBrowseName);
43975 return retval;
43976}
43977
43978/* Prepare the node, then add it to the nodestore */
43979static UA_StatusCode
43980Operation_addNode_begin(UA_Server *server, UA_Session *session, void *nodeContext,
43981 const UA_AddNodesItem *item, const UA_NodeId *parentNodeId,
43982 const UA_NodeId *referenceTypeId, UA_NodeId *outNewNodeId) {
43983 /* Create a temporary NodeId if none is returned */
43984 UA_NodeId newId;
43985 if(!outNewNodeId) {
43986 UA_NodeId_init(p: &newId);
43987 outNewNodeId = &newId;
43988 }
43989
43990 /* Set the BrowsenName before adding to the Nodestore. The BrowseName is
43991 * immutable afterwards. */
43992 UA_Boolean noBrowseName = UA_QualifiedName_isNull(q: &item->browseName);
43993 UA_StatusCode retval =
43994 checkSetBrowseName(server, session, item: (UA_AddNodesItem*)(uintptr_t)item);
43995 if(retval != UA_STATUSCODE_GOOD)
43996 return retval;
43997
43998 /* Create the node and add it to the nodestore */
43999 retval = addNode_raw(server, session, nodeContext, item, outNewNodeId);
44000 if(retval != UA_STATUSCODE_GOOD)
44001 goto cleanup;
44002
44003 /* Typecheck and add references to parent and type definition */
44004 retval = addNode_addRefs(server, session, nodeId: outNewNodeId, parentNodeId,
44005 referenceTypeId, typeDefinitionId: &item->typeDefinition.nodeId);
44006 if(retval != UA_STATUSCODE_GOOD)
44007 deleteNode(server, nodeId: *outNewNodeId, true);
44008
44009 if(outNewNodeId == &newId)
44010 UA_NodeId_clear(p: &newId);
44011
44012 cleanup:
44013 if(noBrowseName)
44014 UA_QualifiedName_clear(p: (UA_QualifiedName*)(uintptr_t)&item->browseName);
44015 return retval;
44016}
44017
44018/* Construct children first */
44019static UA_StatusCode
44020recursiveCallConstructors(UA_Server *server, UA_Session *session,
44021 const UA_NodeId *nodeId, const UA_Node *type) {
44022 UA_LOCK_ASSERT(&server->serviceMutex, 1);
44023
44024 /* Browse the children */
44025 UA_BrowseDescription bd;
44026 UA_BrowseDescription_init(p: &bd);
44027 bd.nodeId = *nodeId;
44028 bd.referenceTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_AGGREGATES);
44029 bd.includeSubtypes = true;
44030 bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;
44031
44032 UA_BrowseResult br;
44033 UA_BrowseResult_init(p: &br);
44034 UA_UInt32 maxrefs = 0;
44035 Operation_Browse(server, session, maxrefs: &maxrefs, descr: &bd, result: &br);
44036 if(br.statusCode != UA_STATUSCODE_GOOD)
44037 return br.statusCode;
44038
44039 /* Call the constructor for every unconstructed child node */
44040 UA_StatusCode retval = UA_STATUSCODE_GOOD;
44041 for(size_t i = 0; i < br.referencesSize; ++i) {
44042 UA_ReferenceDescription *rd = &br.references[i];
44043 if(!UA_ExpandedNodeId_isLocal(n: &rd->nodeId))
44044 continue;
44045 const UA_Node *target = UA_NODESTORE_GET(server, nodeId: &rd->nodeId.nodeId);
44046 if(!target)
44047 continue;
44048 if(target->head.constructed) {
44049 UA_NODESTORE_RELEASE(server, target);
44050 continue;
44051 }
44052
44053 const UA_Node *targetType = NULL;
44054 if(target->head.nodeClass == UA_NODECLASS_VARIABLE ||
44055 target->head.nodeClass == UA_NODECLASS_OBJECT) {
44056 targetType = getNodeType(server, head: &target->head);
44057 if(!targetType) {
44058 UA_NODESTORE_RELEASE(server, target);
44059 retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
44060 break;
44061 }
44062 }
44063
44064 UA_NODESTORE_RELEASE(server, target);
44065 retval = recursiveCallConstructors(server, session, nodeId: &rd->nodeId.nodeId, type: targetType);
44066
44067 if(targetType)
44068 UA_NODESTORE_RELEASE(server, targetType);
44069 if(retval != UA_STATUSCODE_GOOD)
44070 break;
44071 }
44072
44073 UA_BrowseResult_clear(p: &br);
44074
44075 /* If a child could not be constructed or the node is already constructed */
44076 if(retval != UA_STATUSCODE_GOOD)
44077 return retval;
44078
44079 /* Get the node context */
44080 const UA_Node *node = UA_NODESTORE_GET(server, nodeId);
44081 if(!node)
44082 return UA_STATUSCODE_BADNODEIDUNKNOWN;
44083 void *context = node->head.context;
44084 UA_NODESTORE_RELEASE(server, node);
44085
44086 /* Call the global constructor */
44087 if(server->config.nodeLifecycle.constructor) {
44088 retval = server->config.nodeLifecycle.
44089 constructor(server, &session->sessionId,
44090 session->sessionHandle, nodeId, &context);
44091 if(retval != UA_STATUSCODE_GOOD)
44092 return retval;
44093 }
44094
44095 /* Call the local (per-type) constructor */
44096 const UA_NodeTypeLifecycle *lifecycle = NULL;
44097 if(type && node->head.nodeClass == UA_NODECLASS_OBJECT)
44098 lifecycle = &type->objectTypeNode.lifecycle;
44099 else if(type && node->head.nodeClass == UA_NODECLASS_VARIABLE)
44100 lifecycle = &type->variableTypeNode.lifecycle;
44101 if(lifecycle && lifecycle->constructor) {
44102 retval = lifecycle->constructor(server, &session->sessionId,
44103 session->sessionHandle, &type->head.nodeId,
44104 type->head.context, nodeId, &context);
44105 if(retval != UA_STATUSCODE_GOOD)
44106 goto global_destructor;
44107 }
44108
44109 /* Set the context *and* mark the node as constructed */
44110 retval = UA_Server_editNode(server, session: &server->adminSession, nodeId,
44111 callback: (UA_EditNodeCallback)setConstructedNodeContext, data: context);
44112 if(retval != UA_STATUSCODE_GOOD)
44113 goto local_destructor;
44114
44115 /* All good, return */
44116 return retval;
44117
44118 /* Fail. Call the destructors. */
44119 local_destructor:
44120 if(lifecycle && lifecycle->destructor) {
44121 lifecycle->destructor(server, &session->sessionId, session->sessionHandle,
44122 &type->head.nodeId, type->head.context, nodeId, &context);
44123 }
44124
44125 global_destructor:
44126 if(server->config.nodeLifecycle.destructor) {
44127 server->config.nodeLifecycle.destructor(server, &session->sessionId,
44128 session->sessionHandle,
44129 nodeId, context);
44130 }
44131 return retval;
44132}
44133
44134/* Add new ReferenceType to the subtypes bitfield */
44135static UA_StatusCode
44136addReferenceTypeSubtype(UA_Server *server, UA_Session *session,
44137 UA_Node *node, void *context) {
44138 node->referenceTypeNode.subTypes =
44139 UA_ReferenceTypeSet_union(setA: node->referenceTypeNode.subTypes,
44140 setB: *(UA_ReferenceTypeSet*)context);
44141 return UA_STATUSCODE_GOOD;
44142}
44143
44144static UA_StatusCode
44145setReferenceTypeSubtypes(UA_Server *server, const UA_ReferenceTypeNode *node) {
44146 /* Get the ReferenceTypes upwards in the hierarchy */
44147 size_t parentsSize = 0;
44148 UA_ExpandedNodeId *parents = NULL;
44149 UA_ReferenceTypeSet reftypes_subtype = UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASSUBTYPE);
44150 UA_StatusCode res =
44151 browseRecursive(server, startNodesSize: 1, startNodes: &node->head.nodeId, browseDirection: UA_BROWSEDIRECTION_INVERSE,
44152 refTypes: &reftypes_subtype, nodeClassMask: UA_NODECLASS_UNSPECIFIED,
44153 false, resultsSize: &parentsSize, results: &parents);
44154 if(res != UA_STATUSCODE_GOOD)
44155 return res;
44156
44157 /* Add the ReferenceTypeIndex of this node */
44158 const UA_ReferenceTypeSet *newRefSet = &node->subTypes;
44159 for(size_t i = 0; i < parentsSize; i++) {
44160 UA_Server_editNode(server, session: &server->adminSession, nodeId: &parents[i].nodeId,
44161 callback: addReferenceTypeSubtype, data: (void*)(uintptr_t)newRefSet);
44162 }
44163
44164 UA_Array_delete(p: parents, size: parentsSize, type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
44165 return UA_STATUSCODE_GOOD;
44166}
44167
44168static UA_StatusCode
44169setVariableNodeDynamic(UA_Server *server, UA_Session *session,
44170 UA_Node *node, const void *ctx) {
44171 if(node->head.nodeClass != UA_NODECLASS_VARIABLE)
44172 return UA_STATUSCODE_BADINTERNALERROR;
44173 ((UA_VariableNode*)node)->isDynamic = *(const UA_Boolean*)ctx;
44174 return UA_STATUSCODE_GOOD;
44175}
44176
44177static UA_StatusCode
44178checkSetIsDynamicVariable(UA_Server *server, UA_Session *session,
44179 const UA_NodeId *nodeId) {
44180 /* Get all hierarchical reference types */
44181 UA_ReferenceTypeSet reftypes_hierarchical;
44182 UA_ReferenceTypeSet_init(set: &reftypes_hierarchical);
44183 UA_NodeId hierarchicalRefs = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HIERARCHICALREFERENCES);
44184 UA_StatusCode res =
44185 referenceTypeIndices(server, refType: &hierarchicalRefs, indices: &reftypes_hierarchical, true);
44186 if(res != UA_STATUSCODE_GOOD)
44187 return res;
44188
44189 /* Is the variable under the server object? */
44190 UA_NodeId serverNodeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER);
44191 if(isNodeInTree(server, leafNode: nodeId, nodeToFind: &serverNodeId, relevantRefs: &reftypes_hierarchical))
44192 return UA_STATUSCODE_GOOD;
44193
44194 /* Is the variable in the type hierarchy? */
44195 UA_NodeId typesNodeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_TYPESFOLDER);
44196 if(isNodeInTree(server, leafNode: nodeId, nodeToFind: &typesNodeId, relevantRefs: &reftypes_hierarchical))
44197 return UA_STATUSCODE_GOOD;
44198
44199 /* Is the variable a property of a method node (InputArguments /
44200 * OutputArguments)? */
44201 UA_BrowseDescription bd;
44202 UA_BrowseDescription_init(p: &bd);
44203 bd.nodeId = *nodeId;
44204 bd.browseDirection = UA_BROWSEDIRECTION_INVERSE;
44205 bd.referenceTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY);
44206 bd.includeSubtypes = false;
44207 bd.nodeClassMask = UA_NODECLASS_METHOD;
44208 UA_BrowseResult br;
44209 UA_BrowseResult_init(p: &br);
44210 UA_UInt32 maxrefs = 0;
44211 Operation_Browse(server, session, maxrefs: &maxrefs, descr: &bd, result: &br);
44212 UA_Boolean hasParentMethod = (br.referencesSize > 0);
44213 UA_BrowseResult_clear(p: &br);
44214 if(hasParentMethod)
44215 return UA_STATUSCODE_GOOD;
44216
44217 /* Set the variable to "dynamic" */
44218 UA_Boolean isDynamic = true;
44219 UA_Server_editNode(server, session, nodeId,
44220 callback: (UA_EditNodeCallback)setVariableNodeDynamic, data: &isDynamic);
44221
44222 return UA_STATUSCODE_GOOD;
44223}
44224
44225UA_StatusCode
44226UA_Server_setVariableNodeDynamic(UA_Server *server, const UA_NodeId nodeId,
44227 UA_Boolean isDynamic) {
44228 lockServer(server);
44229 UA_StatusCode res =
44230 UA_Server_editNode(server, session: &server->adminSession, nodeId: &nodeId,
44231 callback: (UA_EditNodeCallback)setVariableNodeDynamic, data: &isDynamic);
44232 unlockServer(server);
44233 return res;
44234}
44235
44236/* Children, references, type-checking, constructors. */
44237UA_StatusCode
44238addNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId) {
44239 /* Get the node */
44240 const UA_Node *type = NULL;
44241 const UA_Node *node = UA_NODESTORE_GET(server, nodeId);
44242 if(!node)
44243 return UA_STATUSCODE_BADNODEIDUNKNOWN;
44244
44245 /* Set the ReferenceTypesSet of subtypes in the ReferenceTypeNode */
44246 UA_StatusCode retval = UA_STATUSCODE_GOOD;
44247 if(node->head.nodeClass == UA_NODECLASS_REFERENCETYPE) {
44248 retval = setReferenceTypeSubtypes(server, node: &node->referenceTypeNode);
44249 if(retval != UA_STATUSCODE_GOOD)
44250 goto cleanup;
44251 }
44252
44253 /* Check NodeClass for 'hasSubtype'. UA_NODECLASS_VARIABLE not allowed
44254 * to have subtype */
44255 if(node->head.nodeClass == UA_NODECLASS_VARIABLE) {
44256 for(size_t i = 0; i < node->head.referencesSize; i++) {
44257 if(node->head.references[i].referenceTypeIndex ==
44258 UA_REFERENCETYPEINDEX_HASSUBTYPE) {
44259 UA_LOG_NODEID_INFO(&node->head.nodeId,
44260 UA_LOG_INFO_SESSION(server->config.logging, session,
44261 "AddNode (%.*s): Variable not allowed "
44262 "to have HasSubType reference",
44263 (int)nodeIdStr.length, nodeIdStr.data));
44264 retval = UA_STATUSCODE_BADREFERENCENOTALLOWED;
44265 goto cleanup;
44266 }
44267 }
44268 }
44269
44270 /* Set variables to dynamic (source and server timestamps are meaningful) if
44271 * they fulfill some conditions. (Do this before replacing the default value
44272 * in a VariableNode. So that the sourceTimestamp is set in the Write service.) */
44273 if(node->head.nodeClass == UA_NODECLASS_VARIABLE) {
44274 retval = checkSetIsDynamicVariable(server, session, nodeId);
44275 if(retval != UA_STATUSCODE_GOOD)
44276 goto cleanup;
44277 }
44278
44279 /* Get the type node */
44280 if(node->head.nodeClass == UA_NODECLASS_VARIABLE ||
44281 node->head.nodeClass == UA_NODECLASS_VARIABLETYPE ||
44282 node->head.nodeClass == UA_NODECLASS_OBJECT) {
44283 type = getNodeType(server, head: &node->head);
44284 if(!type) {
44285 if(server->bootstrapNS0)
44286 goto constructor;
44287 logAddNode(logger: server->config.logging, session, nodeId: &node->head.nodeId,
44288 msg: "Node type not found");
44289 retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
44290 goto cleanup;
44291 }
44292 }
44293
44294 /* Initialize and typecheck the variable */
44295 if(node->head.nodeClass == UA_NODECLASS_VARIABLE ||
44296 node->head.nodeClass == UA_NODECLASS_VARIABLETYPE) {
44297 /* Use attributes from the type. The value and value constraints are the
44298 * same for the variable and variabletype attribute structs. */
44299 retval = useVariableTypeAttributes(server, session,
44300 node: &node->variableNode,
44301 vt: &type->variableTypeNode);
44302 if(retval != UA_STATUSCODE_GOOD) {
44303 UA_LOG_NODEID_INFO(&node->head.nodeId,
44304 UA_LOG_INFO_SESSION(server->config.logging, session,
44305 "AddNode (%.*s): Using attributes for from "
44306 "the variable type failed with error code %s",
44307 (int)nodeIdStr.length, nodeIdStr.data,
44308 UA_StatusCode_name(retval)));
44309 goto cleanup;
44310 }
44311
44312 /* Get a new pointer to the node. It might have been switched out */
44313#ifdef UA_ENABLE_IMMUTABLE_NODES
44314 UA_NODESTORE_RELEASE(server, node);
44315 node = UA_NODESTORE_GET(server, nodeId);
44316 if(!node || (node->head.nodeClass != UA_NODECLASS_VARIABLE &&
44317 node->head.nodeClass != UA_NODECLASS_VARIABLETYPE)) {
44318 retval = UA_STATUSCODE_BADINTERNALERROR;
44319 goto cleanup;
44320 }
44321#endif
44322
44323 /* Check if all attributes hold the constraints of the type now. The initial
44324 * attributes must type-check. The constructor might change the attributes
44325 * again. Then, the changes are type-checked by the normal write service. */
44326 retval = typeCheckVariableNode(server, session, node: &node->variableNode,
44327 vt: &type->variableTypeNode);
44328 if(retval != UA_STATUSCODE_GOOD) {
44329 UA_LOG_NODEID_INFO(&node->head.nodeId,
44330 UA_LOG_INFO_SESSION(server->config.logging, session,
44331 "AddNode (%.*s): Type-checking "
44332 "failed with error code %s", (int)nodeIdStr.length,
44333 nodeIdStr.data, UA_StatusCode_name(retval)));
44334 goto cleanup;
44335 }
44336 }
44337
44338 /* Add (mandatory) child nodes from the type definition */
44339 if(node->head.nodeClass == UA_NODECLASS_VARIABLE ||
44340 node->head.nodeClass == UA_NODECLASS_OBJECT) {
44341 retval = addTypeChildren(server, session, nodeId, typeId: &type->head.nodeId);
44342 if(retval != UA_STATUSCODE_GOOD) {
44343 UA_LOG_NODEID_INFO(&node->head.nodeId,
44344 UA_LOG_INFO_SESSION(server->config.logging, session,
44345 "AddNode (%.*s): Adding child nodes "
44346 "failed with error code %s", (int)nodeIdStr.length,
44347 nodeIdStr.data, UA_StatusCode_name(retval)));
44348 goto cleanup;
44349 }
44350 }
44351
44352 /* Add (mandatory) child nodes from the HasInterface references */
44353 if(node->head.nodeClass == UA_NODECLASS_OBJECT) {
44354 retval = addInterfaceChildren(server, session, nodeId, typeId: &type->head.nodeId);
44355 if(retval != UA_STATUSCODE_GOOD) {
44356 UA_LOG_NODEID_INFO(&node->head.nodeId,
44357 UA_LOG_INFO_SESSION(server->config.logging, session,
44358 "AddNode (%.*s): Adding child nodes "
44359 "interface failed with error code %s",
44360 (int)nodeIdStr.length, nodeIdStr.data,
44361 UA_StatusCode_name(retval)));
44362 goto cleanup;
44363 }
44364 }
44365
44366 /* Call the constructor(s) */
44367 constructor:
44368 if(!node->head.constructed)
44369 retval = recursiveCallConstructors(server, session, nodeId, type);
44370 if(retval != UA_STATUSCODE_GOOD) {
44371 UA_LOG_NODEID_INFO(&node->head.nodeId,
44372 UA_LOG_INFO_SESSION(server->config.logging, session,
44373 "AddNode (%.*s): Calling the node constructor(s) "
44374 "failed with status code %s", (int)nodeIdStr.length,
44375 nodeIdStr.data, UA_StatusCode_name(retval)));
44376 }
44377
44378 cleanup:
44379 UA_NODESTORE_RELEASE(server, node);
44380 if(type)
44381 UA_NODESTORE_RELEASE(server, type);
44382 if(retval != UA_STATUSCODE_GOOD)
44383 deleteNode(server, nodeId: *nodeId, true);
44384 return retval;
44385}
44386
44387static void
44388Operation_addNode(UA_Server *server, UA_Session *session, void *nodeContext,
44389 const UA_AddNodesItem *item, UA_AddNodesResult *result) {
44390 result->statusCode =
44391 Operation_addNode_begin(server, session, nodeContext,
44392 item, parentNodeId: &item->parentNodeId.nodeId,
44393 referenceTypeId: &item->referenceTypeId, outNewNodeId: &result->addedNodeId);
44394 if(result->statusCode != UA_STATUSCODE_GOOD)
44395 return;
44396
44397 /* AddNodes_finish */
44398 result->statusCode = addNode_finish(server, session, nodeId: &result->addedNodeId);
44399
44400 /* If finishing failed, the node was deleted */
44401 if(result->statusCode != UA_STATUSCODE_GOOD)
44402 UA_NodeId_clear(p: &result->addedNodeId);
44403}
44404
44405void
44406Service_AddNodes(UA_Server *server, UA_Session *session,
44407 const UA_AddNodesRequest *request,
44408 UA_AddNodesResponse *response) {
44409 UA_LOG_DEBUG_SESSION(server->config.logging, session, "Processing AddNodesRequest");
44410 UA_LOCK_ASSERT(&server->serviceMutex, 1);
44411
44412 if(server->config.maxNodesPerNodeManagement != 0 &&
44413 request->nodesToAddSize > server->config.maxNodesPerNodeManagement) {
44414 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
44415 return;
44416 }
44417
44418 response->responseHeader.serviceResult =
44419 UA_Server_processServiceOperations(server, session,
44420 operationCallback: (UA_ServiceOperation)Operation_addNode, NULL,
44421 requestOperations: &request->nodesToAddSize,
44422 requestOperationsType: &UA_TYPES[UA_TYPES_ADDNODESITEM],
44423 responseOperations: &response->resultsSize,
44424 responseOperationsType: &UA_TYPES[UA_TYPES_ADDNODESRESULT]);
44425}
44426
44427UA_StatusCode
44428addNode(UA_Server *server, const UA_NodeClass nodeClass, const UA_NodeId requestedNewNodeId,
44429 const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
44430 const UA_QualifiedName browseName, const UA_NodeId typeDefinition,
44431 const void *attr, const UA_DataType *attributeType,
44432 void *nodeContext, UA_NodeId *outNewNodeId) {
44433 UA_LOCK_ASSERT(&server->serviceMutex, 1);
44434
44435 /* Create the AddNodesItem */
44436 UA_AddNodesItem item;
44437 UA_AddNodesItem_init(p: &item);
44438 item.nodeClass = nodeClass;
44439 item.requestedNewNodeId.nodeId = requestedNewNodeId;
44440 item.browseName = browseName;
44441 item.parentNodeId.nodeId = parentNodeId;
44442 item.referenceTypeId = referenceTypeId;
44443 item.typeDefinition.nodeId = typeDefinition;
44444 UA_ExtensionObject_setValueNoDelete(eo: &item.nodeAttributes,
44445 p: (void*)(uintptr_t)attr, type: attributeType);
44446
44447 /* Call the normal addnodes service */
44448 UA_AddNodesResult result;
44449 UA_AddNodesResult_init(p: &result);
44450 Operation_addNode(server, session: &server->adminSession, nodeContext, item: &item, result: &result);
44451 if(outNewNodeId)
44452 *outNewNodeId = result.addedNodeId;
44453 else
44454 UA_NodeId_clear(p: &result.addedNodeId);
44455 return result.statusCode;
44456}
44457
44458UA_StatusCode
44459__UA_Server_addNode(UA_Server *server, const UA_NodeClass nodeClass,
44460 const UA_NodeId *requestedNewNodeId,
44461 const UA_NodeId *parentNodeId,
44462 const UA_NodeId *referenceTypeId,
44463 const UA_QualifiedName browseName,
44464 const UA_NodeId *typeDefinition,
44465 const UA_NodeAttributes *attr,
44466 const UA_DataType *attributeType,
44467 void *nodeContext, UA_NodeId *outNewNodeId) {
44468 lockServer(server);
44469 UA_StatusCode reval =
44470 addNode(server, nodeClass, requestedNewNodeId: *requestedNewNodeId, parentNodeId: *parentNodeId,
44471 referenceTypeId: *referenceTypeId, browseName, typeDefinition: *typeDefinition, attr,
44472 attributeType, nodeContext, outNewNodeId);
44473 unlockServer(server);
44474 return reval;
44475}
44476
44477UA_StatusCode
44478addNode_begin(UA_Server *server, const UA_NodeClass nodeClass,
44479 const UA_NodeId requestedNewNodeId, const UA_NodeId parentNodeId,
44480 const UA_NodeId referenceTypeId, const UA_QualifiedName browseName,
44481 const UA_NodeId typeDefinition, const void *attr,
44482 const UA_DataType *attributeType, void *nodeContext,
44483 UA_NodeId *outNewNodeId) {
44484 UA_AddNodesItem item;
44485 UA_AddNodesItem_init(p: &item);
44486 item.nodeClass = nodeClass;
44487 item.requestedNewNodeId.nodeId = requestedNewNodeId;
44488 item.browseName = browseName;
44489 item.typeDefinition.nodeId = typeDefinition;
44490 UA_ExtensionObject_setValueNoDelete(eo: &item.nodeAttributes,
44491 p: (void*)(uintptr_t)attr, type: attributeType);
44492 return Operation_addNode_begin(server, session: &server->adminSession, nodeContext, item: &item,
44493 parentNodeId: &parentNodeId, referenceTypeId: &referenceTypeId, outNewNodeId);
44494}
44495
44496UA_StatusCode
44497UA_Server_addNode_begin(UA_Server *server, const UA_NodeClass nodeClass,
44498 const UA_NodeId requestedNewNodeId, const UA_NodeId parentNodeId,
44499 const UA_NodeId referenceTypeId, const UA_QualifiedName browseName,
44500 const UA_NodeId typeDefinition, const void *attr,
44501 const UA_DataType *attributeType, void *nodeContext,
44502 UA_NodeId *outNewNodeId) {
44503 lockServer(server);
44504 UA_StatusCode res =
44505 addNode_begin(server, nodeClass, requestedNewNodeId, parentNodeId,
44506 referenceTypeId, browseName, typeDefinition, attr,
44507 attributeType, nodeContext, outNewNodeId);
44508 unlockServer(server);
44509 return res;
44510}
44511
44512UA_StatusCode
44513UA_Server_addNode_finish(UA_Server *server, const UA_NodeId nodeId) {
44514 lockServer(server);
44515 UA_StatusCode retval = addNode_finish(server, session: &server->adminSession, nodeId: &nodeId);
44516 unlockServer(server);
44517 return retval;
44518}
44519
44520/****************/
44521/* Delete Nodes */
44522/****************/
44523
44524static void
44525Operation_deleteReference(UA_Server *server, UA_Session *session, void *context,
44526 const UA_DeleteReferencesItem *item, UA_StatusCode *retval);
44527
44528struct RemoveIncomingContext {
44529 UA_Server *server;
44530 UA_Session *session;
44531 UA_DeleteReferencesItem *item;
44532};
44533
44534static void *
44535removeIncomingReferencesCallback(void *context, UA_ReferenceTarget *t) {
44536 struct RemoveIncomingContext *ctx = (struct RemoveIncomingContext *)context;
44537 if(!UA_NodePointer_isLocal(np: t->targetId))
44538 return NULL;
44539 UA_StatusCode dummy;
44540 ctx->item->sourceNodeId = UA_NodePointer_toNodeId(np: t->targetId);
44541 Operation_deleteReference(server: ctx->server, session: ctx->session, NULL, item: ctx->item, retval: &dummy);
44542 return NULL;
44543}
44544
44545/* Remove references to this node (in the other nodes) */
44546static void
44547removeIncomingReferences(UA_Server *server, UA_Session *session,
44548 const UA_NodeHead *head) {
44549 UA_DeleteReferencesItem item;
44550 UA_DeleteReferencesItem_init(p: &item);
44551 item.targetNodeId.nodeId = head->nodeId;
44552 item.deleteBidirectional = false;
44553
44554 struct RemoveIncomingContext ctx;
44555 ctx.server = server;
44556 ctx.session = session;
44557 ctx.item = &item;
44558
44559 for(size_t i = 0; i < head->referencesSize; ++i) {
44560 UA_NodeReferenceKind *rk = &head->references[i];
44561 item.isForward = rk->isInverse;
44562 item.referenceTypeId =
44563 *UA_NODESTORE_GETREFERENCETYPEID(server, rk->referenceTypeIndex);
44564 UA_NodeReferenceKind_iterate(rk, callback: removeIncomingReferencesCallback, context: &ctx);
44565 }
44566}
44567
44568static void *
44569checkTargetInRefTree(void *context, UA_ReferenceTarget *t) {
44570 RefTree *refTree = (RefTree*)context;
44571 if(!UA_NodePointer_isLocal(np: t->targetId))
44572 return NULL;
44573 UA_NodeId tmpId = UA_NodePointer_toNodeId(np: t->targetId);
44574 if(!RefTree_containsNodeId(rt: refTree, target: &tmpId))
44575 return (void*)0x1;
44576 return NULL;
44577}
44578
44579/* A node is auto-deleted if all its hierarchical parents are being deleted */
44580static UA_Boolean
44581hasParentRef(const UA_NodeHead *head, const UA_ReferenceTypeSet *refSet,
44582 RefTree *refTree) {
44583 for(size_t i = 0; i < head->referencesSize; i++) {
44584 UA_NodeReferenceKind *rk = &head->references[i];
44585 if(!rk->isInverse)
44586 continue;
44587 if(!UA_ReferenceTypeSet_contains(set: refSet, index: rk->referenceTypeIndex))
44588 continue;
44589 if(UA_NodeReferenceKind_iterate(rk, callback: checkTargetInRefTree, context: refTree) != NULL)
44590 return true;
44591 }
44592 return false;
44593}
44594
44595static void
44596deconstructNodeSet(UA_Server *server, UA_Session *session,
44597 UA_ReferenceTypeSet *hierarchRefsSet, RefTree *refTree) {
44598 UA_LOCK_ASSERT(&server->serviceMutex, 1);
44599
44600 /* Deconstruct the nodes based on the RefTree entries, parent nodes first */
44601 for(size_t i = 0; i < refTree->size; i++) {
44602 const UA_Node *member = UA_NODESTORE_GET(server, nodeId: &refTree->targets[i].nodeId);
44603 if(!member)
44604 continue;
44605
44606 /* Call the type-level destructor */
44607 void *context = member->head.context; /* No longer needed after this function */
44608 if(member->head.nodeClass == UA_NODECLASS_OBJECT ||
44609 member->head.nodeClass == UA_NODECLASS_VARIABLE) {
44610 const UA_Node *type = getNodeType(server, head: &member->head);
44611 if(type) {
44612 /* Get the lifecycle */
44613 const UA_NodeTypeLifecycle *lifecycle;
44614 if(member->head.nodeClass == UA_NODECLASS_OBJECT)
44615 lifecycle = &type->objectTypeNode.lifecycle;
44616 else
44617 lifecycle = &type->variableTypeNode.lifecycle;
44618
44619 /* Call the destructor */
44620 if(lifecycle->destructor) {
44621 lifecycle->destructor(server,
44622 &session->sessionId, session->sessionHandle,
44623 &type->head.nodeId, type->head.context,
44624 &member->head.nodeId, &context);
44625 }
44626
44627 /* Release the type node */
44628 UA_NODESTORE_RELEASE(server, type);
44629 }
44630 }
44631
44632 /* Call the global destructor */
44633 if(server->config.nodeLifecycle.destructor) {
44634 server->config.nodeLifecycle.destructor(server, &session->sessionId,
44635 session->sessionHandle,
44636 &member->head.nodeId, context);
44637 }
44638
44639 /* Release the node. Don't access the node context from here on. */
44640 UA_NODESTORE_RELEASE(server, member);
44641
44642 /* Set the constructed flag to false */
44643 UA_Server_editNode(server, session: &server->adminSession, nodeId: &refTree->targets[i].nodeId,
44644 callback: (UA_EditNodeCallback)setDeconstructedNode, NULL);
44645 }
44646}
44647
44648struct DeleteChildrenContext {
44649 UA_Server *server;
44650 const UA_ReferenceTypeSet *hierarchRefsSet;
44651 RefTree *refTree;
44652 UA_StatusCode res;
44653};
44654
44655static void *
44656deleteChildrenCallback(void *context, UA_ReferenceTarget *t) {
44657 struct DeleteChildrenContext *ctx = (struct DeleteChildrenContext*)context;
44658
44659 /* Get the child */
44660 const UA_Node *child = UA_NODESTORE_GETFROMREF(server: ctx->server, target: t->targetId);
44661 if(!child)
44662 return NULL;
44663
44664 /* Only delete child nodes that have no other parent */
44665 if(!hasParentRef(head: &child->head, refSet: ctx->hierarchRefsSet, refTree: ctx->refTree))
44666 ctx->res = RefTree_addNodeId(rt: ctx->refTree, target: &child->head.nodeId, NULL);
44667
44668 UA_NODESTORE_RELEASE(ctx->server, child);
44669 return (ctx->res == UA_STATUSCODE_GOOD) ? NULL : (void*)0x01;
44670}
44671
44672/* The processNodeLayer function searches all children's of the head node and
44673 * adds the children node to the RefTree if all incoming references sources are
44674 * contained in the RefTree (No external references to this node --> node can be
44675 * deleted) */
44676static UA_StatusCode
44677autoDeleteChildren(UA_Server *server, UA_Session *session, RefTree *refTree,
44678 const UA_ReferenceTypeSet *hierarchRefsSet, const UA_NodeHead *head){
44679 struct DeleteChildrenContext ctx;
44680 ctx.server = server;
44681 ctx.hierarchRefsSet = hierarchRefsSet;
44682 ctx.refTree = refTree;
44683 ctx.res = UA_STATUSCODE_GOOD;
44684
44685 for(size_t i = 0; i < head->referencesSize; ++i) {
44686 /* Check if the ReferenceType is hierarchical */
44687 UA_NodeReferenceKind *rk = &head->references[i];
44688 if(!UA_ReferenceTypeSet_contains(set: hierarchRefsSet, index: rk->referenceTypeIndex))
44689 continue;
44690
44691 /* Check if the references are forward (to a child) */
44692 if(rk->isInverse)
44693 continue;
44694
44695 /* Loop over the references */
44696 UA_NodeReferenceKind_iterate(rk, callback: deleteChildrenCallback, context: &ctx);
44697 if(ctx.res != UA_STATUSCODE_GOOD)
44698 return ctx.res;
44699 }
44700 return UA_STATUSCODE_GOOD;
44701}
44702
44703/* Build up an ordered set (tree) of all nodes that can be deleted. Step through
44704 * the ordered set in order to avoid recursion. */
44705static UA_StatusCode
44706buildDeleteNodeSet(UA_Server *server, UA_Session *session,
44707 const UA_ReferenceTypeSet *hierarchRefsSet,
44708 const UA_NodeId *initial, UA_Boolean removeTargetRefs,
44709 RefTree *refTree) {
44710 /* Add the initial node to delete */
44711 UA_StatusCode res = RefTree_addNodeId(rt: refTree, target: initial, NULL);
44712 if(res != UA_STATUSCODE_GOOD)
44713 return res;
44714
44715 /* Find out which hierarchical children should also be deleted. We know
44716 * there are no "external" ExpandedNodeId in the RefTree. */
44717 size_t pos = 0;
44718 while(pos < refTree->size) {
44719 const UA_Node *member = UA_NODESTORE_GET(server, nodeId: &refTree->targets[pos].nodeId);
44720 pos++;
44721 if(!member)
44722 continue;
44723 res |= autoDeleteChildren(server, session, refTree, hierarchRefsSet, head: &member->head);
44724 UA_NODESTORE_RELEASE(server, member);
44725 }
44726 return res;
44727}
44728
44729static void
44730deleteNodeSet(UA_Server *server, UA_Session *session,
44731 const UA_ReferenceTypeSet *hierarchRefsSet,
44732 UA_Boolean removeTargetRefs, RefTree *refTree) {
44733 /* Delete the nodes based on the RefTree entries */
44734 for(size_t i = refTree->size; i > 0; --i) {
44735 const UA_Node *member = UA_NODESTORE_GET(server, nodeId: &refTree->targets[i-1].nodeId);
44736 if(!member)
44737 continue;
44738 UA_NODESTORE_RELEASE(server, member);
44739 if(removeTargetRefs)
44740 removeIncomingReferences(server, session, head: &member->head);
44741 UA_NODESTORE_REMOVE(server, &member->head.nodeId);
44742 }
44743}
44744
44745static void
44746deleteNodeOperation(UA_Server *server, UA_Session *session, void *context,
44747 const UA_DeleteNodesItem *item, UA_StatusCode *result) {
44748 UA_LOCK_ASSERT(&server->serviceMutex, 1);
44749
44750 /* Do not check access for server */
44751 if(session != &server->adminSession && server->config.accessControl.allowDeleteNode) {
44752 if(!server->config.accessControl.
44753 allowDeleteNode(server, &server->config.accessControl,
44754 &session->sessionId, session->sessionHandle, item)) {
44755 *result = UA_STATUSCODE_BADUSERACCESSDENIED;
44756 return;
44757 }
44758 }
44759
44760 const UA_Node *node = UA_NODESTORE_GET(server, nodeId: &item->nodeId);
44761 if(!node) {
44762 *result = UA_STATUSCODE_BADNODEIDUNKNOWN;
44763 return;
44764 }
44765
44766 if(UA_Node_hasSubTypeOrInstances(head: &node->head)) {
44767 UA_LOG_NODEID_INFO(&node->head.nodeId,
44768 UA_LOG_INFO_SESSION(server->config.logging, session, "DeleteNode (%.*s): "
44769 "Cannot delete a type node with active instances or "
44770 "subtypes", (int)nodeIdStr.length, nodeIdStr.data));
44771 UA_NODESTORE_RELEASE(server, node);
44772 *result = UA_STATUSCODE_BADINTERNALERROR;
44773 return;
44774 }
44775
44776 /* TODO: Check if the information model consistency is violated */
44777 /* TODO: Check if the node is a mandatory child of a parent */
44778
44779 /* Relase the node. Don't access the pointer after this! */
44780 UA_NODESTORE_RELEASE(server, node);
44781
44782 /* A node can be referenced with hierarchical references from several
44783 * parents in the information model. (But not in a circular way.) The
44784 * hierarchical references are checked to see if a node can be deleted.
44785 * Getting the type hierarchy can fail in case of low RAM. In that case the
44786 * nodes are always deleted. */
44787 UA_ReferenceTypeSet hierarchRefsSet;
44788 UA_NodeId hr = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HIERARCHICALREFERENCES);
44789 *result = referenceTypeIndices(server, refType: &hr, indices: &hierarchRefsSet, true);
44790 if(*result != UA_STATUSCODE_GOOD)
44791 return;
44792
44793 /* The list of childs is needed for the deconstructing and deleting phase.
44794 * Within the processNodeLayer we generate a RefTree based set of childs
44795 * which can be deleted beside the parent node. */
44796 RefTree refTree;
44797 *result = RefTree_init(rt: &refTree);
44798 if(*result != UA_STATUSCODE_GOOD)
44799 return;
44800 *result = buildDeleteNodeSet(server, session, hierarchRefsSet: &hierarchRefsSet, initial: &item->nodeId,
44801 removeTargetRefs: item->deleteTargetReferences, refTree: &refTree);
44802 if(*result != UA_STATUSCODE_GOOD) {
44803 UA_LOG_WARNING_SESSION(server->config.logging, session,
44804 "DeleteNode: Incomplete lookup of nodes. "
44805 "Still deleting what we have.");
44806 /* Continue, so the RefTree is cleaned up. Return the error message
44807 * anyway. */
44808 }
44809
44810 /* Deconstruct, then delete, then clean up the set */
44811 deconstructNodeSet(server, session, hierarchRefsSet: &hierarchRefsSet, refTree: &refTree);
44812 deleteNodeSet(server, session, hierarchRefsSet: &hierarchRefsSet,
44813 removeTargetRefs: item->deleteTargetReferences, refTree: &refTree);
44814 RefTree_clear(rt: &refTree);
44815}
44816
44817void
44818Service_DeleteNodes(UA_Server *server, UA_Session *session,
44819 const UA_DeleteNodesRequest *request,
44820 UA_DeleteNodesResponse *response) {
44821 UA_LOG_DEBUG_SESSION(server->config.logging, session,
44822 "Processing DeleteNodesRequest");
44823 UA_LOCK_ASSERT(&server->serviceMutex, 1);
44824
44825 if(server->config.maxNodesPerNodeManagement != 0 &&
44826 request->nodesToDeleteSize > server->config.maxNodesPerNodeManagement) {
44827 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
44828 return;
44829 }
44830
44831 response->responseHeader.serviceResult =
44832 UA_Server_processServiceOperations(server, session,
44833 operationCallback: (UA_ServiceOperation)deleteNodeOperation,
44834 NULL, requestOperations: &request->nodesToDeleteSize,
44835 requestOperationsType: &UA_TYPES[UA_TYPES_DELETENODESITEM],
44836 responseOperations: &response->resultsSize,
44837 responseOperationsType: &UA_TYPES[UA_TYPES_STATUSCODE]);
44838}
44839
44840UA_StatusCode
44841UA_Server_deleteNode(UA_Server *server, const UA_NodeId nodeId,
44842 UA_Boolean deleteReferences) {
44843 lockServer(server);
44844 UA_StatusCode retval = deleteNode(server, nodeId, deleteReferences);
44845 unlockServer(server);
44846 return retval;
44847}
44848
44849UA_StatusCode
44850deleteNode(UA_Server *server, const UA_NodeId nodeId,
44851 UA_Boolean deleteReferences) {
44852 UA_LOCK_ASSERT(&server->serviceMutex, 1);
44853 UA_DeleteNodesItem item;
44854 item.deleteTargetReferences = deleteReferences;
44855 item.nodeId = nodeId;
44856 UA_StatusCode retval = UA_STATUSCODE_GOOD;
44857 deleteNodeOperation(server, session: &server->adminSession, NULL, item: &item, result: &retval);
44858 return retval;
44859}
44860
44861/******************/
44862/* Add References */
44863/******************/
44864
44865struct AddNodeInfo {
44866 UA_Byte refTypeIndex;
44867 UA_Boolean isForward;
44868 const UA_ExpandedNodeId *targetNodeId;
44869 UA_UInt32 targetBrowseNameHash;
44870};
44871
44872static UA_StatusCode
44873addOneWayReference(UA_Server *server, UA_Session *session, UA_Node *node,
44874 const struct AddNodeInfo *info) {
44875 return UA_Node_addReference(node, refTypeIndex: info->refTypeIndex, isForward: info->isForward,
44876 targetNodeId: info->targetNodeId, targetBrowseNameHash: info->targetBrowseNameHash);
44877}
44878
44879static UA_StatusCode
44880deleteOneWayReference(UA_Server *server, UA_Session *session, UA_Node *node,
44881 const UA_DeleteReferencesItem *item) {
44882 const UA_Node *refType = UA_NODESTORE_GET(server, nodeId: &item->referenceTypeId);
44883 if(!refType)
44884 return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
44885 if(refType->head.nodeClass != UA_NODECLASS_REFERENCETYPE) {
44886 UA_NODESTORE_RELEASE(server, refType);
44887 return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
44888 }
44889 UA_Byte refTypeIndex = refType->referenceTypeNode.referenceTypeIndex;
44890 UA_NODESTORE_RELEASE(server, refType);
44891 return UA_Node_deleteReference(node, refTypeIndex, isForward: item->isForward, targetNodeId: &item->targetNodeId);
44892}
44893
44894static void
44895Operation_addReference(UA_Server *server, UA_Session *session, void *context,
44896 const UA_AddReferencesItem *item, UA_StatusCode *retval) {
44897 (void)context;
44898 UA_assert(session);
44899 UA_LOCK_ASSERT(&server->serviceMutex, 1);
44900
44901 /* Check access rights */
44902 if(session != &server->adminSession && server->config.accessControl.allowAddReference) {
44903 if (!server->config.accessControl.
44904 allowAddReference(server, &server->config.accessControl,
44905 &session->sessionId, session->sessionHandle, item)) {
44906 *retval = UA_STATUSCODE_BADUSERACCESSDENIED;
44907 return;
44908 }
44909 }
44910
44911 /* TODO: Currently no expandednodeids are allowed */
44912 if(item->targetServerUri.length > 0) {
44913 *retval = UA_STATUSCODE_BADNOTIMPLEMENTED;
44914 return;
44915 }
44916
44917 /* Check the ReferenceType and get the index */
44918 const UA_Node *refType = UA_NODESTORE_GET(server, nodeId: &item->referenceTypeId);
44919 if(!refType) {
44920 UA_LOG_NODEID_DEBUG(&item->referenceTypeId,
44921 UA_LOG_DEBUG_SESSION(server->config.logging, session,
44922 "Cannot add reference - ReferenceType %.*s unknown",
44923 (int)nodeIdStr.length, nodeIdStr.data));
44924 *retval = UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
44925 return;
44926 }
44927 if(refType->head.nodeClass != UA_NODECLASS_REFERENCETYPE) {
44928 UA_LOG_NODEID_DEBUG(&item->referenceTypeId,
44929 UA_LOG_DEBUG_SESSION(server->config.logging, session,
44930 "Cannot add reference - ReferenceType %.*s with wrong NodeClass",
44931 (int)nodeIdStr.length, nodeIdStr.data));
44932 UA_NODESTORE_RELEASE(server, refType);
44933 *retval = UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
44934 return;
44935 }
44936 UA_Byte refTypeIndex = refType->referenceTypeNode.referenceTypeIndex;
44937 UA_NODESTORE_RELEASE(server, refType);
44938
44939 /* Get the source and target node BrowseName hash */
44940 const UA_Node *targetNode = UA_NODESTORE_GET(server, nodeId: &item->targetNodeId.nodeId);
44941 if(!targetNode) {
44942 UA_LOG_NODEID_DEBUG(&item->targetNodeId.nodeId,
44943 UA_LOG_DEBUG_SESSION(server->config.logging, session,
44944 "Cannot add reference - target %.*s does not exist",
44945 (int)nodeIdStr.length, nodeIdStr.data));
44946 *retval = UA_STATUSCODE_BADTARGETNODEIDINVALID;
44947 return;
44948 }
44949 UA_UInt32 targetNameHash = UA_QualifiedName_hash(q: &targetNode->head.browseName);
44950 UA_NODESTORE_RELEASE(server, targetNode);
44951
44952 const UA_Node *sourceNode = UA_NODESTORE_GET(server, nodeId: &item->sourceNodeId);
44953 if(!sourceNode) {
44954 *retval = UA_STATUSCODE_BADSOURCENODEIDINVALID;
44955 return;
44956 }
44957 UA_UInt32 sourceNameHash = UA_QualifiedName_hash(q: &sourceNode->head.browseName);
44958 UA_NODESTORE_RELEASE(server, sourceNode);
44959
44960 /* Compute the BrowseName hash and release the target */
44961 struct AddNodeInfo info;
44962 info.refTypeIndex = refTypeIndex;
44963 info.targetNodeId = &item->targetNodeId;
44964 info.isForward = item->isForward;
44965 info.targetBrowseNameHash = targetNameHash;
44966
44967 /* Add the first direction */
44968 *retval = UA_Server_editNode(server, session, nodeId: &item->sourceNodeId,
44969 callback: (UA_EditNodeCallback)addOneWayReference, data: &info);
44970 UA_Boolean firstExisted = false;
44971 if(*retval == UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED) {
44972 *retval = UA_STATUSCODE_GOOD;
44973 firstExisted = true;
44974 }
44975 if(*retval != UA_STATUSCODE_GOOD)
44976 return;
44977
44978 /* Add the second direction */
44979 UA_ExpandedNodeId target2;
44980 UA_ExpandedNodeId_init(p: &target2);
44981 target2.nodeId = item->sourceNodeId;
44982 info.targetNodeId = &target2;
44983 info.isForward = !info.isForward;
44984 info.targetBrowseNameHash = sourceNameHash;
44985 *retval = UA_Server_editNode(server, session, nodeId: &item->targetNodeId.nodeId,
44986 callback: (UA_EditNodeCallback)addOneWayReference, data: &info);
44987
44988 /* Second direction existed already */
44989 if(*retval == UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED) {
44990 /* Calculate common duplicate reference not allowed result and set bad
44991 * result if BOTH directions already existed */
44992 if(UA_NodeId_equal(p1: &item->sourceNodeId, p2: &item->targetNodeId.nodeId)) {
44993 *retval = UA_STATUSCODE_GOOD;
44994 UA_LOG_INFO_SESSION(server->config.logging, session, "The source node and the target node are identical. The check for duplicate references is skipped.");
44995 }
44996 else if(firstExisted) {
44997 *retval = UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED;
44998 return;
44999 }
45000 *retval = UA_STATUSCODE_GOOD;
45001 }
45002
45003 /* Remove first direction if the second direction failed */
45004 if(*retval != UA_STATUSCODE_GOOD && !firstExisted) {
45005 UA_DeleteReferencesItem deleteItem;
45006 deleteItem.sourceNodeId = item->sourceNodeId;
45007 deleteItem.referenceTypeId = item->referenceTypeId;
45008 deleteItem.isForward = item->isForward;
45009 deleteItem.targetNodeId = item->targetNodeId;
45010 deleteItem.deleteBidirectional = false;
45011 /* Ignore status code */
45012 UA_Server_editNode(server, session, nodeId: &item->sourceNodeId,
45013 callback: (UA_EditNodeCallback)deleteOneWayReference, data: &deleteItem);
45014 }
45015}
45016
45017void
45018Service_AddReferences(UA_Server *server, UA_Session *session,
45019 const UA_AddReferencesRequest *request,
45020 UA_AddReferencesResponse *response) {
45021 UA_LOG_DEBUG_SESSION(server->config.logging, session,
45022 "Processing AddReferencesRequest");
45023 UA_LOCK_ASSERT(&server->serviceMutex, 1);
45024 UA_assert(session);
45025
45026 if(server->config.maxNodesPerNodeManagement != 0 &&
45027 request->referencesToAddSize > server->config.maxNodesPerNodeManagement) {
45028 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
45029 return;
45030 }
45031
45032 response->responseHeader.serviceResult =
45033 UA_Server_processServiceOperations(server, session,
45034 operationCallback: (UA_ServiceOperation)Operation_addReference,
45035 NULL, requestOperations: &request->referencesToAddSize,
45036 requestOperationsType: &UA_TYPES[UA_TYPES_ADDREFERENCESITEM],
45037 responseOperations: &response->resultsSize,
45038 responseOperationsType: &UA_TYPES[UA_TYPES_STATUSCODE]);
45039}
45040
45041UA_StatusCode
45042UA_Server_addReference(UA_Server *server, const UA_NodeId sourceId,
45043 const UA_NodeId refTypeId,
45044 const UA_ExpandedNodeId targetId,
45045 UA_Boolean isForward) {
45046 UA_AddReferencesItem item;
45047 UA_AddReferencesItem_init(p: &item);
45048 item.sourceNodeId = sourceId;
45049 item.referenceTypeId = refTypeId;
45050 item.isForward = isForward;
45051 item.targetNodeId = targetId;
45052
45053 UA_StatusCode retval = UA_STATUSCODE_GOOD;
45054 lockServer(server);
45055 Operation_addReference(server, session: &server->adminSession, NULL, item: &item, retval: &retval);
45056 unlockServer(server);
45057 return retval;
45058}
45059
45060/*********************/
45061/* Delete References */
45062/*********************/
45063
45064static void
45065Operation_deleteReference(UA_Server *server, UA_Session *session, void *context,
45066 const UA_DeleteReferencesItem *item, UA_StatusCode *retval) {
45067 /* Do not check access for server */
45068 if(session != &server->adminSession &&
45069 server->config.accessControl.allowDeleteReference) {
45070 UA_LOCK_ASSERT(&server->serviceMutex, 1);
45071 if (!server->config.accessControl.
45072 allowDeleteReference(server, &server->config.accessControl,
45073 &session->sessionId, session->sessionHandle, item)){
45074 *retval = UA_STATUSCODE_BADUSERACCESSDENIED;
45075 return;
45076 }
45077 }
45078
45079 // TODO: Check consistency constraints, remove the references.
45080 *retval = UA_Server_editNode(server, session, nodeId: &item->sourceNodeId,
45081 callback: (UA_EditNodeCallback)deleteOneWayReference,
45082 /* cast away const qualifier because callback
45083 * uses it anyway */
45084 data: (UA_DeleteReferencesItem *)(uintptr_t)item);
45085 if(*retval != UA_STATUSCODE_GOOD)
45086 return;
45087
45088 if(!item->deleteBidirectional || item->targetNodeId.serverIndex != 0)
45089 return;
45090
45091 UA_DeleteReferencesItem secondItem;
45092 UA_DeleteReferencesItem_init(p: &secondItem);
45093 secondItem.isForward = !item->isForward;
45094 secondItem.sourceNodeId = item->targetNodeId.nodeId;
45095 secondItem.targetNodeId.nodeId = item->sourceNodeId;
45096 secondItem.referenceTypeId = item->referenceTypeId;
45097 *retval = UA_Server_editNode(server, session, nodeId: &secondItem.sourceNodeId,
45098 callback: (UA_EditNodeCallback)deleteOneWayReference,
45099 data: &secondItem);
45100}
45101
45102void
45103Service_DeleteReferences(UA_Server *server, UA_Session *session,
45104 const UA_DeleteReferencesRequest *request,
45105 UA_DeleteReferencesResponse *response) {
45106 UA_LOG_DEBUG_SESSION(server->config.logging, session,
45107 "Processing DeleteReferencesRequest");
45108 UA_LOCK_ASSERT(&server->serviceMutex, 1);
45109
45110 if(server->config.maxNodesPerNodeManagement != 0 &&
45111 request->referencesToDeleteSize > server->config.maxNodesPerNodeManagement) {
45112 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS;
45113 return;
45114 }
45115
45116 response->responseHeader.serviceResult =
45117 UA_Server_processServiceOperations(server, session,
45118 operationCallback: (UA_ServiceOperation)Operation_deleteReference,
45119 NULL, requestOperations: &request->referencesToDeleteSize,
45120 requestOperationsType: &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM],
45121 responseOperations: &response->resultsSize,
45122 responseOperationsType: &UA_TYPES[UA_TYPES_STATUSCODE]);
45123}
45124
45125UA_StatusCode
45126deleteReference(UA_Server *server, const UA_NodeId sourceNodeId,
45127 const UA_NodeId referenceTypeId, UA_Boolean isForward,
45128 const UA_ExpandedNodeId targetNodeId,
45129 UA_Boolean deleteBidirectional) {
45130 UA_DeleteReferencesItem item;
45131 item.sourceNodeId = sourceNodeId;
45132 item.referenceTypeId = referenceTypeId;
45133 item.isForward = isForward;
45134 item.targetNodeId = targetNodeId;
45135 item.deleteBidirectional = deleteBidirectional;
45136
45137 UA_StatusCode retval = UA_STATUSCODE_GOOD;
45138 Operation_deleteReference(server, session: &server->adminSession, NULL, item: &item, retval: &retval);
45139 return retval;
45140}
45141
45142UA_StatusCode
45143UA_Server_deleteReference(UA_Server *server, const UA_NodeId sourceNodeId,
45144 const UA_NodeId referenceTypeId, UA_Boolean isForward,
45145 const UA_ExpandedNodeId targetNodeId,
45146 UA_Boolean deleteBidirectional) {
45147 lockServer(server);
45148 UA_StatusCode res = deleteReference(server, sourceNodeId, referenceTypeId,
45149 isForward, targetNodeId, deleteBidirectional);
45150 unlockServer(server);
45151 return res;
45152}
45153
45154/**********************/
45155/* Set Value Callback */
45156/**********************/
45157
45158static UA_StatusCode
45159setValueCallback(UA_Server *server, UA_Session *session,
45160 UA_VariableNode *node, const UA_ValueCallback *callback) {
45161 if(node->head.nodeClass != UA_NODECLASS_VARIABLE)
45162 return UA_STATUSCODE_BADNODECLASSINVALID;
45163 node->value.data.callback = *callback;
45164 return UA_STATUSCODE_GOOD;
45165}
45166
45167UA_StatusCode
45168setVariableNode_valueCallback(UA_Server *server, const UA_NodeId nodeId,
45169 const UA_ValueCallback callback) {
45170 return UA_Server_editNode(server, session: &server->adminSession, nodeId: &nodeId,
45171 callback: (UA_EditNodeCallback)setValueCallback,
45172 /* cast away const because
45173 * callback uses const anyway */
45174 data: (UA_ValueCallback *)(uintptr_t) &callback);
45175}
45176
45177UA_StatusCode
45178UA_Server_setVariableNode_valueCallback(UA_Server *server,
45179 const UA_NodeId nodeId,
45180 const UA_ValueCallback callback) {
45181 lockServer(server);
45182 UA_StatusCode retval = UA_Server_editNode(server, session: &server->adminSession, nodeId: &nodeId,
45183 callback: (UA_EditNodeCallback)setValueCallback,
45184 /* cast away const because
45185 * callback uses const anyway */
45186 data: (UA_ValueCallback *)(uintptr_t) &callback);
45187 unlockServer(server);
45188 return retval;
45189}
45190
45191/***************************************************/
45192/* Special Handling of Variables with Data Sources */
45193/***************************************************/
45194
45195UA_StatusCode
45196UA_Server_addDataSourceVariableNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
45197 const UA_NodeId parentNodeId,
45198 const UA_NodeId referenceTypeId,
45199 const UA_QualifiedName browseName,
45200 const UA_NodeId typeDefinition,
45201 const UA_VariableAttributes attr,
45202 const UA_DataSource dataSource,
45203 void *nodeContext, UA_NodeId *outNewNodeId) {
45204 UA_AddNodesItem item;
45205 UA_AddNodesItem_init(p: &item);
45206 item.nodeClass = UA_NODECLASS_VARIABLE;
45207 item.requestedNewNodeId.nodeId = requestedNewNodeId;
45208 item.browseName = browseName;
45209 UA_ExpandedNodeId typeDefinitionId;
45210 UA_ExpandedNodeId_init(p: &typeDefinitionId);
45211 typeDefinitionId.nodeId = typeDefinition;
45212 item.typeDefinition = typeDefinitionId;
45213 UA_ExtensionObject_setValueNoDelete(eo: &item.nodeAttributes, p: (void*)(uintptr_t)&attr,
45214 type: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES]);
45215 UA_NodeId newNodeId;
45216 if(!outNewNodeId) {
45217 newNodeId = UA_NODEID_NULL;
45218 outNewNodeId = &newNodeId;
45219 }
45220
45221 lockServer(server);
45222
45223 /* Create the node and add it to the nodestore */
45224 UA_StatusCode retval = addNode_raw(server, session: &server->adminSession, nodeContext,
45225 item: &item, outNewNodeId);
45226 if(retval != UA_STATUSCODE_GOOD)
45227 goto cleanup;
45228
45229 /* Set the data source */
45230 retval = setVariableNode_dataSource(server, nodeId: *outNewNodeId, dataSource);
45231 if(retval != UA_STATUSCODE_GOOD)
45232 goto cleanup;
45233
45234 /* Typecheck and add references to parent and type definition */
45235 retval = addNode_addRefs(server, session: &server->adminSession, nodeId: outNewNodeId, parentNodeId: &parentNodeId,
45236 referenceTypeId: &referenceTypeId, typeDefinitionId: &typeDefinition);
45237 if(retval != UA_STATUSCODE_GOOD)
45238 goto cleanup;
45239
45240 /* Call the constructors */
45241 retval = addNode_finish(server, session: &server->adminSession, nodeId: outNewNodeId);
45242
45243 cleanup:
45244 unlockServer(server);
45245 if(outNewNodeId == &newNodeId)
45246 UA_NodeId_clear(p: &newNodeId);
45247
45248 return retval;
45249}
45250
45251static UA_StatusCode
45252setDataSource(UA_Server *server, UA_Session *session,
45253 UA_VariableNode *node, const UA_DataSource *dataSource) {
45254 if(node->head.nodeClass != UA_NODECLASS_VARIABLE)
45255 return UA_STATUSCODE_BADNODECLASSINVALID;
45256 if(node->valueSource == UA_VALUESOURCE_DATA)
45257 UA_DataValue_clear(p: &node->value.data.value);
45258 node->value.dataSource = *dataSource;
45259 node->valueSource = UA_VALUESOURCE_DATASOURCE;
45260 return UA_STATUSCODE_GOOD;
45261}
45262
45263UA_StatusCode
45264setVariableNode_dataSource(UA_Server *server, const UA_NodeId nodeId,
45265 const UA_DataSource dataSource) {
45266 UA_LOCK_ASSERT(&server->serviceMutex, 1);
45267 return UA_Server_editNode(server, session: &server->adminSession, nodeId: &nodeId,
45268 callback: (UA_EditNodeCallback)setDataSource,
45269 /* casting away const because callback casts it back anyway */
45270 data: (UA_DataSource *) (uintptr_t)&dataSource);
45271}
45272
45273UA_StatusCode
45274UA_Server_setVariableNode_dataSource(UA_Server *server, const UA_NodeId nodeId,
45275 const UA_DataSource dataSource) {
45276 lockServer(server);
45277 UA_StatusCode retval = setVariableNode_dataSource(server, nodeId, dataSource);
45278 unlockServer(server);
45279 return retval;
45280}
45281
45282/******************************/
45283/* Set External Value Source */
45284/******************************/
45285static UA_StatusCode
45286setExternalValueSource(UA_Server *server, UA_Session *session,
45287 UA_VariableNode *node, const UA_ValueBackend *externalValueSource) {
45288 if(node->head.nodeClass != UA_NODECLASS_VARIABLE)
45289 return UA_STATUSCODE_BADNODECLASSINVALID;
45290 node->valueBackend.backendType = UA_VALUEBACKENDTYPE_EXTERNAL;
45291 node->valueBackend.backend.external.value =
45292 externalValueSource->backend.external.value;
45293 node->valueBackend.backend.external.callback.notificationRead =
45294 externalValueSource->backend.external.callback.notificationRead;
45295 node->valueBackend.backend.external.callback.userWrite =
45296 externalValueSource->backend.external.callback.userWrite;
45297 return UA_STATUSCODE_GOOD;
45298}
45299
45300/****************************/
45301/* Set Data Source Callback */
45302/****************************/
45303static UA_StatusCode
45304setDataSourceCallback(UA_Server *server, UA_Session *session,
45305 UA_VariableNode *node, const UA_DataSource *dataSource) {
45306 if(node->head.nodeClass != UA_NODECLASS_VARIABLE)
45307 return UA_STATUSCODE_BADNODECLASSINVALID;
45308 node->valueBackend.backendType = UA_VALUEBACKENDTYPE_DATA_SOURCE_CALLBACK;
45309 node->valueBackend.backend.dataSource.read = dataSource->read;
45310 node->valueBackend.backend.dataSource.write = dataSource->write;
45311 return UA_STATUSCODE_GOOD;
45312}
45313
45314/**********************/
45315/* Set Value Backend */
45316/**********************/
45317
45318UA_StatusCode
45319UA_Server_setVariableNode_valueBackend(UA_Server *server, const UA_NodeId nodeId,
45320 const UA_ValueBackend valueBackend){
45321 UA_StatusCode retval = UA_STATUSCODE_GOOD;
45322 lockServer(server);
45323 switch(valueBackend.backendType){
45324 case UA_VALUEBACKENDTYPE_NONE:
45325 unlockServer(server);
45326 return UA_STATUSCODE_BADCONFIGURATIONERROR;
45327 case UA_VALUEBACKENDTYPE_DATA_SOURCE_CALLBACK:
45328 retval = UA_Server_editNode(server, session: &server->adminSession, nodeId: &nodeId,
45329 callback: (UA_EditNodeCallback) setDataSourceCallback,
45330 data: (UA_DataSource *)(uintptr_t) &valueBackend.backend.dataSource);
45331 break;
45332 case UA_VALUEBACKENDTYPE_INTERNAL:
45333 break;
45334 case UA_VALUEBACKENDTYPE_EXTERNAL:
45335 retval = UA_Server_editNode(server, session: &server->adminSession, nodeId: &nodeId,
45336 callback: (UA_EditNodeCallback) setExternalValueSource,
45337 /* cast away const because callback uses const anyway */
45338 data: (UA_ValueCallback *)(uintptr_t) &valueBackend);
45339 break;
45340 }
45341
45342
45343 // UA_StatusCode retval = UA_Server_editNode(server, &server->adminSession, &nodeId,
45344 // (UA_EditNodeCallback)setValueCallback,
45345 /* cast away const because callback uses const anyway */
45346 // (UA_ValueCallback *)(uintptr_t) &callback);
45347
45348
45349 unlockServer(server);
45350 return retval;
45351}
45352
45353
45354/************************************/
45355/* Special Handling of Method Nodes */
45356/************************************/
45357
45358#ifdef UA_ENABLE_METHODCALLS
45359
45360static const UA_NodeId hasproperty = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASPROPERTY}};
45361static const UA_NodeId propertytype = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_PROPERTYTYPE}};
45362
45363static UA_StatusCode
45364UA_Server_addMethodNodeEx_finish(UA_Server *server, const UA_NodeId nodeId,
45365 UA_MethodCallback method,
45366 const size_t inputArgumentsSize,
45367 const UA_Argument *inputArguments,
45368 const UA_NodeId inputArgumentsRequestedNewNodeId,
45369 UA_NodeId *inputArgumentsOutNewNodeId,
45370 const size_t outputArgumentsSize,
45371 const UA_Argument *outputArguments,
45372 const UA_NodeId outputArgumentsRequestedNewNodeId,
45373 UA_NodeId *outputArgumentsOutNewNodeId) {
45374 /* Browse to see which argument nodes exist */
45375 UA_BrowseDescription bd;
45376 UA_BrowseDescription_init(p: &bd);
45377 bd.nodeId = nodeId;
45378 bd.referenceTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY);
45379 bd.includeSubtypes = false;
45380 bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;
45381 bd.nodeClassMask = UA_NODECLASS_VARIABLE;
45382 bd.resultMask = UA_BROWSERESULTMASK_BROWSENAME;
45383
45384 UA_BrowseResult br;
45385 UA_BrowseResult_init(p: &br);
45386 UA_UInt32 maxrefs = 0;
45387 Operation_Browse(server, session: &server->adminSession, maxrefs: &maxrefs, descr: &bd, result: &br);
45388
45389 UA_StatusCode retval = br.statusCode;
45390 if(retval != UA_STATUSCODE_GOOD) {
45391 deleteNode(server, nodeId, true);
45392 UA_BrowseResult_clear(p: &br);
45393 return retval;
45394 }
45395
45396 /* Filter out the argument nodes */
45397 UA_NodeId inputArgsId = UA_NODEID_NULL;
45398 UA_NodeId outputArgsId = UA_NODEID_NULL;
45399 const UA_QualifiedName inputArgsName = UA_QUALIFIEDNAME(nsIndex: 0, chars: "InputArguments");
45400 const UA_QualifiedName outputArgsName = UA_QUALIFIEDNAME(nsIndex: 0, chars: "OutputArguments");
45401 for(size_t i = 0; i < br.referencesSize; i++) {
45402 UA_ReferenceDescription *rd = &br.references[i];
45403 if(rd->browseName.namespaceIndex == 0 &&
45404 UA_String_equal(p1: &rd->browseName.name, p2: &inputArgsName.name))
45405 inputArgsId = rd->nodeId.nodeId;
45406 else if(rd->browseName.namespaceIndex == 0 &&
45407 UA_String_equal(p1: &rd->browseName.name, p2: &outputArgsName.name))
45408 outputArgsId = rd->nodeId.nodeId;
45409 }
45410
45411 /* Add the Input Arguments VariableNode */
45412 if(inputArgumentsSize > 0 && UA_NodeId_isNull(p: &inputArgsId)) {
45413 UA_VariableAttributes attr = UA_VariableAttributes_default;
45414 char *name = "InputArguments";
45415 attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: name);
45416 attr.dataType = UA_TYPES[UA_TYPES_ARGUMENT].typeId;
45417 attr.valueRank = UA_VALUERANK_ONE_DIMENSION;
45418 UA_UInt32 inputArgsSize32 = (UA_UInt32)inputArgumentsSize;
45419 attr.arrayDimensions = &inputArgsSize32;
45420 attr.arrayDimensionsSize = 1;
45421 UA_Variant_setArray(v: &attr.value, array: (void *)(uintptr_t)inputArguments,
45422 arraySize: inputArgumentsSize, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
45423 retval = addNode(server, nodeClass: UA_NODECLASS_VARIABLE, requestedNewNodeId: inputArgumentsRequestedNewNodeId,
45424 parentNodeId: nodeId, referenceTypeId: hasproperty, browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: name),
45425 typeDefinition: propertytype, attr: &attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],
45426 NULL, outNewNodeId: &inputArgsId);
45427 if(retval != UA_STATUSCODE_GOOD)
45428 goto error;
45429 }
45430
45431 /* Add the Output Arguments VariableNode */
45432 if(outputArgumentsSize > 0 && UA_NodeId_isNull(p: &outputArgsId)) {
45433 UA_VariableAttributes attr = UA_VariableAttributes_default;
45434 char *name = "OutputArguments";
45435 attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: name);
45436 attr.dataType = UA_TYPES[UA_TYPES_ARGUMENT].typeId;
45437 attr.valueRank = UA_VALUERANK_ONE_DIMENSION;
45438 UA_UInt32 outputArgsSize32 = (UA_UInt32)outputArgumentsSize;
45439 attr.arrayDimensions = &outputArgsSize32;
45440 attr.arrayDimensionsSize = 1;
45441 UA_Variant_setArray(v: &attr.value, array: (void *)(uintptr_t)outputArguments,
45442 arraySize: outputArgumentsSize, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
45443 retval = addNode(server, nodeClass: UA_NODECLASS_VARIABLE, requestedNewNodeId: outputArgumentsRequestedNewNodeId,
45444 parentNodeId: nodeId, referenceTypeId: hasproperty, browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: name),
45445 typeDefinition: propertytype, attr: &attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],
45446 NULL, outNewNodeId: &outputArgsId);
45447 if(retval != UA_STATUSCODE_GOOD)
45448 goto error;
45449 }
45450
45451 retval = setMethodNode_callback(server, methodNodeId: nodeId, methodCallback: method);
45452 if(retval != UA_STATUSCODE_GOOD)
45453 goto error;
45454
45455 /* Call finish to add the parent reference */
45456 retval = addNode_finish(server, session: &server->adminSession, nodeId: &nodeId);
45457 if(retval != UA_STATUSCODE_GOOD)
45458 goto error;
45459
45460 if(inputArgumentsOutNewNodeId != NULL) {
45461 UA_NodeId_copy(src: &inputArgsId, dst: inputArgumentsOutNewNodeId);
45462 }
45463 if(outputArgumentsOutNewNodeId != NULL) {
45464 UA_NodeId_copy(src: &outputArgsId, dst: outputArgumentsOutNewNodeId);
45465 }
45466 UA_BrowseResult_clear(p: &br);
45467 return retval;
45468
45469error:
45470 deleteNode(server, nodeId, true);
45471 deleteNode(server, nodeId: inputArgsId, true);
45472 deleteNode(server, nodeId: outputArgsId, true);
45473 UA_BrowseResult_clear(p: &br);
45474 return retval;
45475}
45476
45477UA_StatusCode
45478UA_Server_addMethodNode_finish(UA_Server *server, const UA_NodeId nodeId,
45479 UA_MethodCallback method,
45480 size_t inputArgumentsSize,
45481 const UA_Argument* inputArguments,
45482 size_t outputArgumentsSize,
45483 const UA_Argument* outputArguments) {
45484 lockServer(server);
45485 UA_StatusCode retval =
45486 UA_Server_addMethodNodeEx_finish(server, nodeId, method,
45487 inputArgumentsSize, inputArguments,
45488 inputArgumentsRequestedNewNodeId: UA_NODEID_NULL, NULL,
45489 outputArgumentsSize, outputArguments,
45490 outputArgumentsRequestedNewNodeId: UA_NODEID_NULL, NULL);
45491 unlockServer(server);
45492 return retval;
45493}
45494
45495UA_StatusCode
45496addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
45497 const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
45498 const UA_QualifiedName browseName,
45499 const UA_MethodAttributes *attr, UA_MethodCallback method,
45500 size_t inputArgumentsSize, const UA_Argument *inputArguments,
45501 const UA_NodeId inputArgumentsRequestedNewNodeId,
45502 UA_NodeId *inputArgumentsOutNewNodeId,
45503 size_t outputArgumentsSize, const UA_Argument *outputArguments,
45504 const UA_NodeId outputArgumentsRequestedNewNodeId,
45505 UA_NodeId *outputArgumentsOutNewNodeId,
45506 void *nodeContext, UA_NodeId *outNewNodeId) {
45507 UA_AddNodesItem item;
45508 UA_AddNodesItem_init(p: &item);
45509 item.nodeClass = UA_NODECLASS_METHOD;
45510 item.requestedNewNodeId.nodeId = requestedNewNodeId;
45511 item.browseName = browseName;
45512 UA_ExtensionObject_setValueNoDelete(eo: &item.nodeAttributes, p: (void*)(uintptr_t)attr,
45513 type: &UA_TYPES[UA_TYPES_METHODATTRIBUTES]);
45514 UA_NodeId newId;
45515 if(!outNewNodeId) {
45516 UA_NodeId_init(p: &newId);
45517 outNewNodeId = &newId;
45518 }
45519 UA_StatusCode retval = Operation_addNode_begin(server, session: &server->adminSession,
45520 nodeContext, item: &item, parentNodeId: &parentNodeId,
45521 referenceTypeId: &referenceTypeId, outNewNodeId);
45522 if(retval != UA_STATUSCODE_GOOD)
45523 return retval;
45524
45525 retval = UA_Server_addMethodNodeEx_finish(server, nodeId: *outNewNodeId, method,
45526 inputArgumentsSize, inputArguments,
45527 inputArgumentsRequestedNewNodeId,
45528 inputArgumentsOutNewNodeId,
45529 outputArgumentsSize, outputArguments,
45530 outputArgumentsRequestedNewNodeId,
45531 outputArgumentsOutNewNodeId);
45532 if(outNewNodeId == &newId)
45533 UA_NodeId_clear(p: &newId);
45534 return retval;
45535}
45536
45537UA_StatusCode
45538UA_Server_addMethodNodeEx(UA_Server *server, const UA_NodeId requestedNewNodeId,
45539 const UA_NodeId parentNodeId,
45540 const UA_NodeId referenceTypeId,
45541 const UA_QualifiedName browseName,
45542 const UA_MethodAttributes attr, UA_MethodCallback method,
45543 size_t inputArgumentsSize, const UA_Argument *inputArguments,
45544 const UA_NodeId inputArgumentsRequestedNewNodeId,
45545 UA_NodeId *inputArgumentsOutNewNodeId,
45546 size_t outputArgumentsSize, const UA_Argument *outputArguments,
45547 const UA_NodeId outputArgumentsRequestedNewNodeId,
45548 UA_NodeId *outputArgumentsOutNewNodeId,
45549 void *nodeContext, UA_NodeId *outNewNodeId) {
45550 lockServer(server);
45551 UA_StatusCode res = addMethodNode(server, requestedNewNodeId,
45552 parentNodeId, referenceTypeId,
45553 browseName, attr: &attr, method,
45554 inputArgumentsSize, inputArguments,
45555 inputArgumentsRequestedNewNodeId,
45556 inputArgumentsOutNewNodeId,
45557 outputArgumentsSize,
45558 outputArguments,
45559 outputArgumentsRequestedNewNodeId,
45560 outputArgumentsOutNewNodeId,
45561 nodeContext, outNewNodeId);
45562 unlockServer(server);
45563 return res;
45564}
45565
45566static UA_StatusCode
45567editMethodCallback(UA_Server *server, UA_Session* session,
45568 UA_Node *node, UA_MethodCallback methodCallback) {
45569 if(node->head.nodeClass != UA_NODECLASS_METHOD)
45570 return UA_STATUSCODE_BADNODECLASSINVALID;
45571 node->methodNode.method = methodCallback;
45572 return UA_STATUSCODE_GOOD;
45573}
45574
45575UA_StatusCode
45576setMethodNode_callback(UA_Server *server,
45577 const UA_NodeId methodNodeId,
45578 UA_MethodCallback methodCallback) {
45579 UA_LOCK_ASSERT(&server->serviceMutex, 1);
45580 return UA_Server_editNode(server, session: &server->adminSession, nodeId: &methodNodeId,
45581 callback: (UA_EditNodeCallback)editMethodCallback,
45582 data: (void*)(uintptr_t)methodCallback);
45583}
45584
45585UA_StatusCode
45586UA_Server_setMethodNodeCallback(UA_Server *server,
45587 const UA_NodeId methodNodeId,
45588 UA_MethodCallback methodCallback) {
45589 lockServer(server);
45590 UA_StatusCode retVal = setMethodNode_callback(server, methodNodeId, methodCallback);
45591 unlockServer(server);
45592 return retVal;
45593}
45594
45595UA_StatusCode
45596UA_Server_getMethodNodeCallback(UA_Server *server,
45597 const UA_NodeId methodNodeId,
45598 UA_MethodCallback *outMethodCallback) {
45599 lockServer(server);
45600 const UA_Node *node = UA_NODESTORE_GET(server, nodeId: &methodNodeId);
45601 if(!node) {
45602 unlockServer(server);
45603 return UA_STATUSCODE_BADNODEIDUNKNOWN;
45604 }
45605
45606 if(node->head.nodeClass != UA_NODECLASS_METHOD) {
45607 UA_NODESTORE_RELEASE(server, node);
45608 unlockServer(server);
45609 return UA_STATUSCODE_BADNODECLASSINVALID;
45610 }
45611
45612 *outMethodCallback = node->methodNode.method;
45613 UA_NODESTORE_RELEASE(server, node);
45614 unlockServer(server);
45615 return UA_STATUSCODE_GOOD;
45616}
45617
45618#endif
45619
45620/************************/
45621/* Lifecycle Management */
45622/************************/
45623
45624void UA_EXPORT
45625UA_Server_setAdminSessionContext(UA_Server *server,
45626 void *context) {
45627 server->adminSession.sessionHandle = context;
45628}
45629
45630static UA_StatusCode
45631setNodeTypeLifecycleCallback(UA_Server *server, UA_Session *session,
45632 UA_Node *node, UA_NodeTypeLifecycle *lifecycle) {
45633 if(node->head.nodeClass == UA_NODECLASS_OBJECTTYPE) {
45634 node->objectTypeNode.lifecycle = *lifecycle;
45635 } else if(node->head.nodeClass == UA_NODECLASS_VARIABLETYPE) {
45636 node->variableTypeNode.lifecycle = *lifecycle;
45637 } else {
45638 return UA_STATUSCODE_BADNODECLASSINVALID;
45639 }
45640 return UA_STATUSCODE_GOOD;
45641}
45642
45643UA_StatusCode
45644setNodeTypeLifecycle(UA_Server *server, UA_NodeId nodeId,
45645 UA_NodeTypeLifecycle lifecycle) {
45646 return UA_Server_editNode(server, session: &server->adminSession, nodeId: &nodeId,
45647 callback: (UA_EditNodeCallback)setNodeTypeLifecycleCallback,
45648 data: &lifecycle);
45649}
45650
45651UA_StatusCode
45652UA_Server_setNodeTypeLifecycle(UA_Server *server, UA_NodeId nodeId,
45653 UA_NodeTypeLifecycle lifecycle) {
45654 lockServer(server);
45655 UA_StatusCode retval = setNodeTypeLifecycle(server, nodeId, lifecycle);
45656 unlockServer(server);
45657 return retval;
45658}
45659
45660/**** amalgamated original file "/src/pubsub/ua_pubsub_networkmessage.c" ****/
45661
45662/* This Source Code Form is subject to the terms of the Mozilla Public
45663 * License, v. 2.0. If a copy of the MPL was not distributed with this
45664 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
45665 *
45666 * Copyright (c) 2017 - 2018 Fraunhofer IOSB (Author: Tino Bischoff)
45667 * Copyright (c) 2019 Fraunhofer IOSB (Author: Andreas Ebner)
45668 */
45669
45670
45671
45672#ifdef UA_ENABLE_PUBSUB /* conditional compilation */
45673
45674const UA_Byte NM_VERSION_MASK = 15;
45675const UA_Byte NM_PUBLISHER_ID_ENABLED_MASK = 16;
45676const UA_Byte NM_GROUP_HEADER_ENABLED_MASK = 32;
45677const UA_Byte NM_PAYLOAD_HEADER_ENABLED_MASK = 64;
45678const UA_Byte NM_EXTENDEDFLAGS1_ENABLED_MASK = 128;
45679const UA_Byte NM_PUBLISHER_ID_MASK = 7;
45680const UA_Byte NM_DATASET_CLASSID_ENABLED_MASK = 8;
45681const UA_Byte NM_SECURITY_ENABLED_MASK = 16;
45682const UA_Byte NM_TIMESTAMP_ENABLED_MASK = 32;
45683const UA_Byte NM_PICOSECONDS_ENABLED_MASK = 64;
45684const UA_Byte NM_EXTENDEDFLAGS2_ENABLED_MASK = 128;
45685const UA_Byte NM_NETWORK_MSG_TYPE_MASK = 28;
45686const UA_Byte NM_CHUNK_MESSAGE_MASK = 1;
45687const UA_Byte NM_PROMOTEDFIELDS_ENABLED_MASK = 2;
45688const UA_Byte GROUP_HEADER_WRITER_GROUPID_ENABLED = 1;
45689const UA_Byte GROUP_HEADER_GROUP_VERSION_ENABLED = 2;
45690const UA_Byte GROUP_HEADER_NM_NUMBER_ENABLED = 4;
45691const UA_Byte GROUP_HEADER_SEQUENCE_NUMBER_ENABLED = 8;
45692const UA_Byte SECURITY_HEADER_NM_SIGNED = 1;
45693const UA_Byte SECURITY_HEADER_NM_ENCRYPTED = 2;
45694const UA_Byte SECURITY_HEADER_SEC_FOOTER_ENABLED = 4;
45695const UA_Byte SECURITY_HEADER_FORCE_KEY_RESET = 8;
45696const UA_Byte DS_MESSAGEHEADER_DS_MSG_VALID = 1;
45697const UA_Byte DS_MESSAGEHEADER_FIELD_ENCODING_MASK = 6;
45698const UA_Byte DS_MESSAGEHEADER_SEQ_NR_ENABLED_MASK = 8;
45699const UA_Byte DS_MESSAGEHEADER_STATUS_ENABLED_MASK = 16;
45700const UA_Byte DS_MESSAGEHEADER_CONFIGMAJORVERSION_ENABLED_MASK = 32;
45701const UA_Byte DS_MESSAGEHEADER_CONFIGMINORVERSION_ENABLED_MASK = 64;
45702const UA_Byte DS_MESSAGEHEADER_FLAGS2_ENABLED_MASK = 128;
45703const UA_Byte DS_MESSAGEHEADER_DS_MESSAGE_TYPE_MASK = 15;
45704const UA_Byte DS_MESSAGEHEADER_TIMESTAMP_ENABLED_MASK = 16;
45705const UA_Byte DS_MESSAGEHEADER_PICOSECONDS_INCLUDED_MASK = 32;
45706const UA_Byte NM_SHIFT_LEN = 2;
45707const UA_Byte DS_MH_SHIFT_LEN = 1;
45708
45709static UA_Boolean UA_NetworkMessage_ExtendedFlags1Enabled(const UA_NetworkMessage* src);
45710static UA_Boolean UA_NetworkMessage_ExtendedFlags2Enabled(const UA_NetworkMessage* src);
45711static UA_Boolean UA_DataSetMessageHeader_DataSetFlags2Enabled(const UA_DataSetMessageHeader* src);
45712
45713UA_StatusCode
45714UA_NetworkMessage_updateBufferedMessage(UA_NetworkMessageOffsetBuffer *buffer) {
45715 UA_StatusCode rv = UA_STATUSCODE_GOOD;
45716 const UA_Byte *bufEnd = &buffer->buffer.data[buffer->buffer.length];
45717 for(size_t i = 0; i < buffer->offsetsSize; ++i) {
45718 UA_NetworkMessageOffset *nmo = &buffer->offsets[i];
45719 UA_Byte *bufPos = &buffer->buffer.data[nmo->offset];
45720 switch(nmo->contentType) {
45721 case UA_PUBSUB_OFFSETTYPE_DATASETMESSAGE_SEQUENCENUMBER:
45722 case UA_PUBSUB_OFFSETTYPE_NETWORKMESSAGE_SEQUENCENUMBER:
45723 rv = UA_UInt16_encodeBinary(src: &nmo->content.sequenceNumber, bufPos: &bufPos, bufEnd);
45724 nmo->content.sequenceNumber++;
45725 break;
45726 case UA_PUBSUB_OFFSETTYPE_PAYLOAD_DATAVALUE:
45727 rv = UA_DataValue_encodeBinary(src: &nmo->content.value, bufPos: &bufPos, bufEnd);
45728 break;
45729 case UA_PUBSUB_OFFSETTYPE_PAYLOAD_DATAVALUE_EXTERNAL:
45730 rv = UA_DataValue_encodeBinary(src: *nmo->content.externalValue, bufPos: &bufPos, bufEnd);
45731 break;
45732 case UA_PUBSUB_OFFSETTYPE_PAYLOAD_VARIANT:
45733 rv = UA_Variant_encodeBinary(src: &nmo->content.value.value, bufPos: &bufPos, bufEnd);
45734 break;
45735 case UA_PUBSUB_OFFSETTYPE_PAYLOAD_VARIANT_EXTERNAL:
45736 rv = UA_Variant_encodeBinary(src: &(*nmo->content.externalValue)->value, bufPos: &bufPos, bufEnd);
45737 break;
45738 case UA_PUBSUB_OFFSETTYPE_PAYLOAD_RAW:
45739 rv = UA_encodeBinaryInternal(src: nmo->content.value.value.data,
45740 type: nmo->content.value.value.type,
45741 bufPos: &bufPos, bufEnd: &bufEnd, NULL, NULL);
45742 break;
45743 case UA_PUBSUB_OFFSETTYPE_PAYLOAD_RAW_EXTERNAL:
45744 rv = UA_encodeBinaryInternal(src: (*nmo->content.externalValue)->value.data,
45745 type: (*nmo->content.externalValue)->value.type,
45746 bufPos: &bufPos, bufEnd: &bufEnd, NULL, NULL);
45747 break;
45748 default:
45749 break; /* The other fields are assumed to not change between messages.
45750 * Only used for RT decoding (not encoding). */
45751 }
45752 }
45753 return rv;
45754}
45755
45756UA_StatusCode
45757UA_NetworkMessage_updateBufferedNwMessage(UA_NetworkMessageOffsetBuffer *buffer,
45758 const UA_ByteString *src, size_t *bufferPosition) {
45759 /* The offset buffer was not prepared */
45760 UA_NetworkMessage *nm = buffer->nm;
45761 if(!nm)
45762 return UA_STATUSCODE_BADINTERNALERROR;
45763
45764 /* The source string is too short */
45765 if(src->length < buffer->buffer.length + *bufferPosition)
45766 return UA_STATUSCODE_BADDECODINGERROR;
45767
45768 /* If this remains at UA_UINT32_MAX, then no raw fields are contained */
45769 size_t smallestRawOffset = UA_UINT32_MAX;
45770
45771 /* Considering one DSM in RT TODO: Clarify multiple DSM */
45772 UA_DataSetMessage* dsm = nm->payload.dataSetPayload.dataSetMessages;
45773
45774 size_t pos = 0;
45775 size_t payloadCounter = 0;
45776 UA_DataSetMessageHeader header;
45777 UA_StatusCode rv = UA_STATUSCODE_GOOD;
45778 for(size_t i = 0; i < buffer->offsetsSize; ++i) {
45779 pos = buffer->offsets[i].offset + *bufferPosition;
45780 switch(buffer->offsets[i].contentType) {
45781 case UA_PUBSUB_OFFSETTYPE_NETWORKMESSAGE_FIELDENCDODING:
45782 rv = UA_DataSetMessageHeader_decodeBinary(src, offset: &pos, dst: &header);
45783 break;
45784 case UA_PUBSUB_OFFSETTYPE_PUBLISHERID:
45785 switch(nm->publisherIdType) {
45786 case UA_PUBLISHERIDTYPE_BYTE:
45787 rv = UA_Byte_decodeBinary(src, offset: &pos, dst: &nm->publisherId.byte);
45788 break;
45789 case UA_PUBLISHERIDTYPE_UINT16:
45790 rv = UA_UInt16_decodeBinary(src, offset: &pos, dst: &nm->publisherId.uint16);
45791 break;
45792 case UA_PUBLISHERIDTYPE_UINT32:
45793 rv = UA_UInt32_decodeBinary(src, offset: &pos, dst: &nm->publisherId.uint32);
45794 break;
45795 case UA_PUBLISHERIDTYPE_UINT64:
45796 rv = UA_UInt64_decodeBinary(src, offset: &pos, dst: &nm->publisherId.uint64);
45797 break;
45798 default:
45799 /* UA_PUBLISHERIDTYPE_STRING is not supported because of
45800 * UA_PUBSUB_RT_FIXED_SIZE */
45801 return UA_STATUSCODE_BADNOTSUPPORTED;
45802 }
45803 break;
45804 case UA_PUBSUB_OFFSETTYPE_WRITERGROUPID:
45805 rv = UA_UInt16_decodeBinary(src, offset: &pos, dst: &nm->groupHeader.writerGroupId);
45806 break;
45807 case UA_PUBSUB_OFFSETTYPE_DATASETWRITERID:
45808 rv = UA_UInt16_decodeBinary(src, offset: &pos,
45809 dst: &nm->payloadHeader.dataSetPayloadHeader.dataSetWriterIds[0]); /* TODO */
45810 break;
45811 case UA_PUBSUB_OFFSETTYPE_NETWORKMESSAGE_SEQUENCENUMBER:
45812 rv = UA_UInt16_decodeBinary(src, offset: &pos, dst: &nm->groupHeader.sequenceNumber);
45813 break;
45814 case UA_PUBSUB_OFFSETTYPE_DATASETMESSAGE_SEQUENCENUMBER:
45815 rv = UA_UInt16_decodeBinary(src, offset: &pos, dst: &dsm->header.dataSetMessageSequenceNr);
45816 break;
45817 case UA_PUBSUB_OFFSETTYPE_PAYLOAD_DATAVALUE:
45818 UA_DataValue_clear(p: &dsm->data.keyFrameData.dataSetFields[payloadCounter]);
45819 rv = UA_DataValue_decodeBinary(src, offset: &pos,
45820 dst: &dsm->data.keyFrameData.dataSetFields[payloadCounter]);
45821 payloadCounter++;
45822 break;
45823 case UA_PUBSUB_OFFSETTYPE_PAYLOAD_VARIANT:
45824 UA_Variant_clear(p: &dsm->data.keyFrameData.dataSetFields[payloadCounter].value);
45825 rv = UA_Variant_decodeBinary(src, offset: &pos,
45826 dst: &dsm->data.keyFrameData.dataSetFields[payloadCounter].value);
45827 dsm->data.keyFrameData.dataSetFields[payloadCounter].hasValue =
45828 (rv == UA_STATUSCODE_GOOD);
45829 payloadCounter++;
45830 break;
45831 case UA_PUBSUB_OFFSETTYPE_PAYLOAD_RAW:
45832 /* We need only the start address of the raw fields */
45833 if(smallestRawOffset > pos){
45834 smallestRawOffset = pos;
45835 dsm->data.keyFrameData.rawFields.data = &src->data[pos];
45836 dsm->data.keyFrameData.rawFields.length = buffer->rawMessageLength;
45837 }
45838 payloadCounter++;
45839 break;
45840 default:
45841 return UA_STATUSCODE_BADNOTSUPPORTED;
45842 }
45843 UA_CHECK_STATUS(rv, return rv);
45844 }
45845
45846 /* Check if the frame is of type "raw" payload. If yes, set the new buffer
45847 * position to the start position of the raw fields plus the length of the
45848 * raw fields. */
45849 if(smallestRawOffset != UA_UINT32_MAX) {
45850 *bufferPosition = smallestRawOffset + buffer->rawMessageLength;
45851 } else {
45852 *bufferPosition = pos;
45853 }
45854
45855 return rv;
45856}
45857
45858static UA_StatusCode
45859UA_NetworkMessageHeader_encodeBinary(const UA_NetworkMessage *src, UA_Byte **bufPos,
45860 const UA_Byte *bufEnd) {
45861 /* UADPVersion + UADP Flags */
45862 UA_Byte v = src->version;
45863 if(src->publisherIdEnabled)
45864 v |= NM_PUBLISHER_ID_ENABLED_MASK;
45865
45866 if(src->groupHeaderEnabled)
45867 v |= NM_GROUP_HEADER_ENABLED_MASK;
45868
45869 if(src->payloadHeaderEnabled)
45870 v |= NM_PAYLOAD_HEADER_ENABLED_MASK;
45871
45872 if(UA_NetworkMessage_ExtendedFlags1Enabled(src))
45873 v |= NM_EXTENDEDFLAGS1_ENABLED_MASK;
45874
45875 UA_StatusCode rv = UA_Byte_encodeBinary(src: &v, bufPos, bufEnd);
45876 UA_CHECK_STATUS(rv, return rv);
45877 // ExtendedFlags1
45878 if(UA_NetworkMessage_ExtendedFlags1Enabled(src)) {
45879 v = (UA_Byte)src->publisherIdType;
45880
45881 if(src->dataSetClassIdEnabled)
45882 v |= NM_DATASET_CLASSID_ENABLED_MASK;
45883
45884 if(src->securityEnabled)
45885 v |= NM_SECURITY_ENABLED_MASK;
45886
45887 if(src->timestampEnabled)
45888 v |= NM_TIMESTAMP_ENABLED_MASK;
45889
45890 if(src->picosecondsEnabled)
45891 v |= NM_PICOSECONDS_ENABLED_MASK;
45892
45893 if(UA_NetworkMessage_ExtendedFlags2Enabled(src))
45894 v |= NM_EXTENDEDFLAGS2_ENABLED_MASK;
45895
45896 rv = UA_Byte_encodeBinary(src: &v, bufPos, bufEnd);
45897 UA_CHECK_STATUS(rv, return rv);
45898
45899 // ExtendedFlags2
45900 if(UA_NetworkMessage_ExtendedFlags2Enabled(src)) {
45901 v = (UA_Byte)src->networkMessageType;
45902 // shift left 2 bit
45903 v = (UA_Byte) (v << NM_SHIFT_LEN);
45904
45905 if(src->chunkMessage)
45906 v |= NM_CHUNK_MESSAGE_MASK;
45907
45908 if(src->promotedFieldsEnabled)
45909 v |= NM_PROMOTEDFIELDS_ENABLED_MASK;
45910
45911 rv = UA_Byte_encodeBinary(src: &v, bufPos, bufEnd);
45912 UA_CHECK_STATUS(rv, return rv);
45913 }
45914 }
45915
45916 // PublisherId
45917 if(src->publisherIdEnabled) {
45918 switch (src->publisherIdType) {
45919 case UA_PUBLISHERIDTYPE_BYTE:
45920 rv = UA_Byte_encodeBinary(src: &src->publisherId.byte, bufPos, bufEnd);
45921 break;
45922
45923 case UA_PUBLISHERIDTYPE_UINT16:
45924 rv = UA_UInt16_encodeBinary(src: &src->publisherId.uint16, bufPos, bufEnd);
45925 break;
45926
45927 case UA_PUBLISHERIDTYPE_UINT32:
45928 rv = UA_UInt32_encodeBinary(src: &src->publisherId.uint32, bufPos, bufEnd);
45929 break;
45930
45931 case UA_PUBLISHERIDTYPE_UINT64:
45932 rv = UA_UInt64_encodeBinary(src: &src->publisherId.uint64, bufPos, bufEnd);
45933 break;
45934
45935 case UA_PUBLISHERIDTYPE_STRING:
45936 rv = UA_String_encodeBinary(src: &src->publisherId.string, bufPos, bufEnd);
45937 break;
45938
45939 default:
45940 rv = UA_STATUSCODE_BADINTERNALERROR;
45941 break;
45942 }
45943 UA_CHECK_STATUS(rv, return rv);
45944 }
45945
45946 // DataSetClassId
45947 if(src->dataSetClassIdEnabled) {
45948 rv = UA_Guid_encodeBinary(src: &src->dataSetClassId, bufPos, bufEnd);
45949 UA_CHECK_STATUS(rv, return rv);
45950 }
45951 return UA_STATUSCODE_GOOD;
45952}
45953
45954static UA_StatusCode
45955UA_GroupHeader_encodeBinary(const UA_NetworkMessage* src, UA_Byte **bufPos,
45956 const UA_Byte *bufEnd) {
45957 UA_Byte v = 0;
45958 if(src->groupHeader.writerGroupIdEnabled)
45959 v |= GROUP_HEADER_WRITER_GROUPID_ENABLED;
45960
45961 if(src->groupHeader.groupVersionEnabled)
45962 v |= GROUP_HEADER_GROUP_VERSION_ENABLED;
45963
45964 if(src->groupHeader.networkMessageNumberEnabled)
45965 v |= GROUP_HEADER_NM_NUMBER_ENABLED;
45966
45967 if(src->groupHeader.sequenceNumberEnabled)
45968 v |= GROUP_HEADER_SEQUENCE_NUMBER_ENABLED;
45969
45970 UA_StatusCode rv = UA_Byte_encodeBinary(src: &v, bufPos, bufEnd);
45971
45972 if(src->groupHeader.writerGroupIdEnabled)
45973 rv |= UA_UInt16_encodeBinary(src: &src->groupHeader.writerGroupId, bufPos, bufEnd);
45974
45975 if(src->groupHeader.groupVersionEnabled)
45976 rv |= UA_UInt32_encodeBinary(src: &src->groupHeader.groupVersion, bufPos, bufEnd);
45977
45978 if(src->groupHeader.networkMessageNumberEnabled)
45979 rv |= UA_UInt16_encodeBinary(src: &src->groupHeader.networkMessageNumber, bufPos, bufEnd);
45980
45981 if(src->groupHeader.sequenceNumberEnabled)
45982 rv |= UA_UInt16_encodeBinary(src: &src->groupHeader.sequenceNumber, bufPos, bufEnd);
45983
45984 return rv;
45985}
45986
45987static UA_StatusCode
45988UA_PayloadHeader_encodeBinary(const UA_NetworkMessage* src, UA_Byte **bufPos,
45989 const UA_Byte *bufEnd) {
45990 if(src->networkMessageType != UA_NETWORKMESSAGE_DATASET)
45991 return UA_STATUSCODE_BADNOTIMPLEMENTED;
45992
45993 if(src->payloadHeader.dataSetPayloadHeader.dataSetWriterIds == NULL)
45994 return UA_STATUSCODE_BADENCODINGERROR;
45995
45996 UA_Byte count = src->payloadHeader.dataSetPayloadHeader.count;
45997
45998 UA_StatusCode rv = UA_Byte_encodeBinary(src: &count, bufPos, bufEnd);
45999
46000 for(UA_Byte i = 0; i < count; i++) {
46001 UA_UInt16 dswId = src->payloadHeader.dataSetPayloadHeader.dataSetWriterIds[i];
46002 rv |= UA_UInt16_encodeBinary(src: &dswId, bufPos, bufEnd);
46003 }
46004
46005 return rv;
46006}
46007
46008static UA_StatusCode
46009UA_ExtendedNetworkMessageHeader_encodeBinary(const UA_NetworkMessage* src, UA_Byte **bufPos,
46010 const UA_Byte *bufEnd) {
46011 UA_StatusCode rv = UA_STATUSCODE_GOOD;
46012 if(src->timestampEnabled)
46013 rv |= UA_DateTime_encodeBinary(src: &src->timestamp, bufPos, bufEnd);
46014
46015 if(src->picosecondsEnabled)
46016 rv |= UA_UInt16_encodeBinary(src: &src->picoseconds, bufPos, bufEnd);
46017
46018 if(src->promotedFieldsEnabled) {
46019 /* Size (calculate & encode) */
46020 UA_UInt16 pfSize = 0;
46021 for(UA_UInt16 i = 0; i < src->promotedFieldsSize; i++)
46022 pfSize = (UA_UInt16)(pfSize + UA_Variant_calcSizeBinary(src: &src->promotedFields[i]));
46023 rv |= UA_UInt16_encodeBinary(src: &pfSize, bufPos, bufEnd);
46024
46025 for(UA_UInt16 i = 0; i < src->promotedFieldsSize; i++)
46026 rv |= UA_Variant_encodeBinary(src: &src->promotedFields[i], bufPos, bufEnd);
46027 }
46028
46029 return rv;
46030}
46031
46032static UA_StatusCode
46033UA_SecurityHeader_encodeBinary(const UA_NetworkMessage* src, UA_Byte **bufPos,
46034 const UA_Byte *bufEnd) {
46035 /* SecurityFlags */
46036 UA_Byte v = 0;
46037 if(src->securityHeader.networkMessageSigned)
46038 v |= SECURITY_HEADER_NM_SIGNED;
46039
46040 if(src->securityHeader.networkMessageEncrypted)
46041 v |= SECURITY_HEADER_NM_ENCRYPTED;
46042
46043 if(src->securityHeader.securityFooterEnabled)
46044 v |= SECURITY_HEADER_SEC_FOOTER_ENABLED;
46045
46046 if(src->securityHeader.forceKeyReset)
46047 v |= SECURITY_HEADER_FORCE_KEY_RESET;
46048
46049 UA_StatusCode rv = UA_Byte_encodeBinary(src: &v, bufPos, bufEnd);
46050
46051 /* SecurityTokenId */
46052 rv |= UA_UInt32_encodeBinary(src: &src->securityHeader.securityTokenId, bufPos, bufEnd);
46053
46054 /* NonceLength */
46055 UA_Byte nonceLength = (UA_Byte)src->securityHeader.messageNonceSize;
46056 rv |= UA_Byte_encodeBinary(src: &nonceLength, bufPos, bufEnd);
46057
46058 /* MessageNonce */
46059 for(size_t i = 0; i < src->securityHeader.messageNonceSize; i++) {
46060 rv |= UA_Byte_encodeBinary(src: &src->securityHeader.messageNonce[i],
46061 bufPos, bufEnd);
46062 }
46063
46064 /* SecurityFooterSize */
46065 if(src->securityHeader.securityFooterEnabled) {
46066 rv |= UA_UInt16_encodeBinary(src: &src->securityHeader.securityFooterSize,
46067 bufPos, bufEnd);
46068 }
46069
46070 return rv;
46071}
46072
46073UA_StatusCode
46074UA_NetworkMessage_encodeHeaders(const UA_NetworkMessage* src, UA_Byte **bufPos,
46075 const UA_Byte *bufEnd) {
46076 /* Message Header */
46077 UA_StatusCode rv = UA_NetworkMessageHeader_encodeBinary(src, bufPos, bufEnd);
46078
46079 /* Group Header */
46080 if(src->groupHeaderEnabled)
46081 rv |= UA_GroupHeader_encodeBinary(src, bufPos, bufEnd);
46082
46083 /* Payload Header */
46084 if(src->payloadHeaderEnabled)
46085 rv |= UA_PayloadHeader_encodeBinary(src, bufPos, bufEnd);
46086
46087 /* Extended Network Message Header */
46088 rv |= UA_ExtendedNetworkMessageHeader_encodeBinary(src, bufPos, bufEnd);
46089
46090 /* SecurityHeader */
46091 if(src->securityEnabled)
46092 rv |= UA_SecurityHeader_encodeBinary(src, bufPos, bufEnd);
46093
46094 return rv;
46095}
46096
46097
46098UA_StatusCode
46099UA_NetworkMessage_encodePayload(const UA_NetworkMessage* src, UA_Byte **bufPos,
46100 const UA_Byte *bufEnd) {
46101 UA_StatusCode rv;
46102
46103 // Payload
46104 if(src->networkMessageType != UA_NETWORKMESSAGE_DATASET)
46105 return UA_STATUSCODE_BADNOTIMPLEMENTED;
46106
46107 UA_Byte count = 1;
46108
46109 if(src->payloadHeaderEnabled) {
46110 count = src->payloadHeader.dataSetPayloadHeader.count;
46111 if(count > 1) {
46112 for(UA_Byte i = 0; i < count; i++) {
46113 /* Calculate the size, if not specified */
46114 UA_UInt16 sz = 0;
46115 if((src->payload.dataSetPayload.sizes != NULL) &&
46116 (src->payload.dataSetPayload.sizes[i] != 0)) {
46117 sz = src->payload.dataSetPayload.sizes[i];
46118 } else {
46119 UA_DataSetMessage *dsm = &src->payload.dataSetPayload.dataSetMessages[i];
46120 sz = (UA_UInt16)UA_DataSetMessage_calcSizeBinary(p: dsm, NULL, currentOffset: 0);
46121 }
46122
46123 rv = UA_UInt16_encodeBinary(src: &sz, bufPos, bufEnd);
46124 UA_CHECK_STATUS(rv, return rv);
46125 }
46126 }
46127 }
46128
46129 for(UA_Byte i = 0; i < count; i++) {
46130 UA_DataSetMessage *dsm = &src->payload.dataSetPayload.dataSetMessages[i];
46131 rv = UA_DataSetMessage_encodeBinary(src: dsm, bufPos, bufEnd);
46132 UA_CHECK_STATUS(rv, return rv);
46133 }
46134
46135 return UA_STATUSCODE_GOOD;
46136}
46137
46138UA_StatusCode
46139UA_NetworkMessage_encodeFooters(const UA_NetworkMessage* src, UA_Byte **bufPos,
46140 const UA_Byte *bufEnd) {
46141 UA_StatusCode rv = UA_STATUSCODE_GOOD;
46142 if(src->securityEnabled &&
46143 src->securityHeader.securityFooterEnabled) {
46144 for(size_t i = 0; i < src->securityHeader.securityFooterSize; i++) {
46145 rv |= UA_Byte_encodeBinary(src: &src->securityFooter.data[i], bufPos, bufEnd);
46146 }
46147 }
46148 return rv;
46149}
46150
46151UA_StatusCode
46152UA_NetworkMessage_encodeBinary(const UA_NetworkMessage* src, UA_Byte **bufPos,
46153 const UA_Byte *bufEnd, UA_Byte **dataToEncryptStart) {
46154 UA_StatusCode rv = UA_NetworkMessage_encodeHeaders(src, bufPos, bufEnd);
46155
46156 if(dataToEncryptStart)
46157 *dataToEncryptStart = *bufPos;
46158
46159 rv |= UA_NetworkMessage_encodePayload(src, bufPos, bufEnd);
46160 rv |= UA_NetworkMessage_encodeFooters(src, bufPos, bufEnd);
46161 return rv;
46162}
46163
46164UA_StatusCode
46165UA_NetworkMessageHeader_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NetworkMessage *dst) {
46166 UA_Byte decoded = 0;
46167 UA_StatusCode rv = UA_Byte_decodeBinary(src, offset, dst: &decoded);
46168 UA_CHECK_STATUS(rv, return rv);
46169
46170 dst->version = decoded & NM_VERSION_MASK;
46171
46172 if((decoded & NM_PUBLISHER_ID_ENABLED_MASK) != 0)
46173 dst->publisherIdEnabled = true;
46174
46175 if((decoded & NM_GROUP_HEADER_ENABLED_MASK) != 0)
46176 dst->groupHeaderEnabled = true;
46177
46178 if((decoded & NM_PAYLOAD_HEADER_ENABLED_MASK) != 0)
46179 dst->payloadHeaderEnabled = true;
46180
46181 if((decoded & NM_EXTENDEDFLAGS1_ENABLED_MASK) != 0) {
46182 decoded = 0;
46183 rv = UA_Byte_decodeBinary(src, offset, dst: &decoded);
46184 UA_CHECK_STATUS(rv, return rv);
46185
46186 dst->publisherIdType = (UA_PublisherIdType)(decoded & NM_PUBLISHER_ID_MASK);
46187 if((decoded & NM_DATASET_CLASSID_ENABLED_MASK) != 0)
46188 dst->dataSetClassIdEnabled = true;
46189
46190 if((decoded & NM_SECURITY_ENABLED_MASK) != 0)
46191 dst->securityEnabled = true;
46192
46193 if((decoded & NM_TIMESTAMP_ENABLED_MASK) != 0)
46194 dst->timestampEnabled = true;
46195
46196 if((decoded & NM_PICOSECONDS_ENABLED_MASK) != 0)
46197 dst->picosecondsEnabled = true;
46198
46199 if((decoded & NM_EXTENDEDFLAGS2_ENABLED_MASK) != 0) {
46200 decoded = 0;
46201 rv = UA_Byte_decodeBinary(src, offset, dst: &decoded);
46202 UA_CHECK_STATUS(rv, return rv);
46203
46204 if((decoded & NM_CHUNK_MESSAGE_MASK) != 0)
46205 dst->chunkMessage = true;
46206
46207 if((decoded & NM_PROMOTEDFIELDS_ENABLED_MASK) != 0)
46208 dst->promotedFieldsEnabled = true;
46209
46210 decoded = decoded & NM_NETWORK_MSG_TYPE_MASK;
46211 decoded = (UA_Byte) (decoded >> NM_SHIFT_LEN);
46212 dst->networkMessageType = (UA_NetworkMessageType)decoded;
46213 }
46214 }
46215
46216 if(dst->publisherIdEnabled) {
46217 switch (dst->publisherIdType) {
46218 case UA_PUBLISHERIDTYPE_BYTE:
46219 rv = UA_Byte_decodeBinary(src, offset, dst: &dst->publisherId.byte);
46220 break;
46221
46222 case UA_PUBLISHERIDTYPE_UINT16:
46223 rv = UA_UInt16_decodeBinary(src, offset, dst: &dst->publisherId.uint16);
46224 break;
46225
46226 case UA_PUBLISHERIDTYPE_UINT32:
46227 rv = UA_UInt32_decodeBinary(src, offset, dst: &dst->publisherId.uint32);
46228 break;
46229
46230 case UA_PUBLISHERIDTYPE_UINT64:
46231 rv = UA_UInt64_decodeBinary(src, offset, dst: &dst->publisherId.uint64);
46232 break;
46233
46234 case UA_PUBLISHERIDTYPE_STRING:
46235 rv = UA_String_decodeBinary(src, offset, dst: &dst->publisherId.string);
46236 break;
46237
46238 default:
46239 rv = UA_STATUSCODE_BADINTERNALERROR;
46240 break;
46241 }
46242 UA_CHECK_STATUS(rv, return rv);
46243 }
46244
46245 if(dst->dataSetClassIdEnabled) {
46246 rv = UA_Guid_decodeBinary(src, offset, dst: &dst->dataSetClassId);
46247 UA_CHECK_STATUS(rv, return rv);
46248 }
46249 return UA_STATUSCODE_GOOD;
46250}
46251
46252static UA_StatusCode
46253UA_GroupHeader_decodeBinary(const UA_ByteString *src, size_t *offset,
46254 UA_NetworkMessage* dst) {
46255 UA_Byte decoded = 0;
46256 UA_StatusCode rv = UA_Byte_decodeBinary(src, offset, dst: &decoded);
46257
46258 if((decoded & GROUP_HEADER_WRITER_GROUPID_ENABLED) != 0) {
46259 dst->groupHeader.writerGroupIdEnabled = true;
46260 rv |= UA_UInt16_decodeBinary(src, offset, dst: &dst->groupHeader.writerGroupId);
46261 }
46262
46263 if((decoded & GROUP_HEADER_GROUP_VERSION_ENABLED) != 0) {
46264 dst->groupHeader.groupVersionEnabled = true;
46265 rv |= UA_UInt32_decodeBinary(src, offset, dst: &dst->groupHeader.groupVersion);
46266 }
46267
46268 if((decoded & GROUP_HEADER_NM_NUMBER_ENABLED) != 0) {
46269 dst->groupHeader.networkMessageNumberEnabled = true;
46270 rv |= UA_UInt16_decodeBinary(src, offset, dst: &dst->groupHeader.networkMessageNumber);
46271 }
46272
46273 if((decoded & GROUP_HEADER_SEQUENCE_NUMBER_ENABLED) != 0) {
46274 dst->groupHeader.sequenceNumberEnabled = true;
46275 rv |= UA_UInt16_decodeBinary(src, offset, dst: &dst->groupHeader.sequenceNumber);
46276 }
46277
46278 return rv;
46279}
46280
46281static UA_StatusCode
46282UA_PayloadHeader_decodeBinary(const UA_ByteString *src, size_t *offset,
46283 UA_NetworkMessage* dst) {
46284
46285 if(dst->networkMessageType != UA_NETWORKMESSAGE_DATASET)
46286 return UA_STATUSCODE_BADNOTIMPLEMENTED;
46287
46288 UA_StatusCode rv = UA_Byte_decodeBinary(src, offset, dst: &dst->payloadHeader.dataSetPayloadHeader.count);
46289 UA_CHECK_STATUS(rv, return rv);
46290
46291 dst->payloadHeader.dataSetPayloadHeader.dataSetWriterIds =
46292 (UA_UInt16 *)UA_Array_new(size: dst->payloadHeader.dataSetPayloadHeader.count,
46293 type: &UA_TYPES[UA_TYPES_UINT16]);
46294 for(UA_Byte i = 0; i < dst->payloadHeader.dataSetPayloadHeader.count; i++) {
46295 rv = UA_UInt16_decodeBinary(src, offset,
46296 dst: &dst->payloadHeader.dataSetPayloadHeader.dataSetWriterIds[i]);
46297 UA_CHECK_STATUS(rv, return rv);
46298 }
46299 return UA_STATUSCODE_GOOD;
46300}
46301
46302static UA_StatusCode
46303UA_ExtendedNetworkMessageHeader_decodeBinary(const UA_ByteString *src, size_t *offset,
46304 UA_NetworkMessage* dst) {
46305 UA_StatusCode rv;
46306
46307 // Timestamp
46308 if(dst->timestampEnabled) {
46309 rv = UA_DateTime_decodeBinary(src, offset, dst: &dst->timestamp);
46310 UA_CHECK_STATUS(rv, goto error);
46311 }
46312
46313 // Picoseconds
46314 if(dst->picosecondsEnabled) {
46315 rv = UA_UInt16_decodeBinary(src, offset, dst: &dst->picoseconds);
46316 UA_CHECK_STATUS(rv, goto error);
46317 }
46318
46319 // PromotedFields
46320 if(dst->promotedFieldsEnabled) {
46321 // Size
46322 UA_UInt16 promotedFieldsSize = 0;
46323 rv = UA_UInt16_decodeBinary(src, offset, dst: &promotedFieldsSize);
46324 UA_CHECK_STATUS(rv, goto error);
46325
46326 // promotedFieldsSize: here size in Byte, not the number of objects!
46327 if(promotedFieldsSize > 0) {
46328 // store offset, later compared with promotedFieldsSize
46329 size_t offsetEnd = (*offset) + promotedFieldsSize;
46330
46331 unsigned int counter = 0;
46332 do {
46333 if(counter == 0) {
46334 dst->promotedFields = (UA_Variant*)UA_malloc(size: UA_TYPES[UA_TYPES_VARIANT].memSize);
46335 UA_CHECK_MEM(dst->promotedFields,
46336 return UA_STATUSCODE_BADOUTOFMEMORY);
46337 // set promotedFieldsSize to the number of objects
46338 dst->promotedFieldsSize = (UA_UInt16) (counter + 1);
46339 } else {
46340 dst->promotedFields = (UA_Variant*)
46341 UA_realloc(ptr: dst->promotedFields,
46342 size: (size_t) UA_TYPES[UA_TYPES_VARIANT].memSize * (counter + 1));
46343 UA_CHECK_MEM(dst->promotedFields,
46344 return UA_STATUSCODE_BADOUTOFMEMORY);
46345 // set promotedFieldsSize to the number of objects
46346 dst->promotedFieldsSize = (UA_UInt16) (counter + 1);
46347 }
46348
46349 UA_Variant_init(p: &dst->promotedFields[counter]);
46350 rv = UA_Variant_decodeBinary(src, offset, dst: &dst->promotedFields[counter]);
46351 UA_CHECK_STATUS(rv, goto error);
46352
46353 counter++;
46354 } while ((*offset) < offsetEnd);
46355 }
46356 }
46357 return UA_STATUSCODE_GOOD;
46358
46359error:
46360 if(dst->promotedFields) {
46361 UA_free(ptr: dst->promotedFields);
46362 dst->promotedFields = NULL;
46363 }
46364 return rv;
46365}
46366
46367static UA_StatusCode
46368UA_SecurityHeader_decodeBinary(const UA_ByteString *src, size_t *offset,
46369 UA_NetworkMessage* dst) {
46370 UA_Byte decoded = 0;
46371 // SecurityFlags
46372 decoded = 0;
46373 UA_StatusCode rv = UA_Byte_decodeBinary(src, offset, dst: &decoded);
46374 UA_CHECK_STATUS(rv, return rv);
46375
46376 if((decoded & SECURITY_HEADER_NM_SIGNED) != 0)
46377 dst->securityHeader.networkMessageSigned = true;
46378
46379 if((decoded & SECURITY_HEADER_NM_ENCRYPTED) != 0)
46380 dst->securityHeader.networkMessageEncrypted = true;
46381
46382 if((decoded & SECURITY_HEADER_SEC_FOOTER_ENABLED) != 0)
46383 dst->securityHeader.securityFooterEnabled = true;
46384
46385 if((decoded & SECURITY_HEADER_FORCE_KEY_RESET) != 0)
46386 dst->securityHeader.forceKeyReset = true;
46387
46388 // SecurityTokenId
46389 rv = UA_UInt32_decodeBinary(src, offset, dst: &dst->securityHeader.securityTokenId);
46390 UA_CHECK_STATUS(rv, return rv);
46391
46392 // MessageNonce
46393 UA_Byte nonceLength;
46394 rv = UA_Byte_decodeBinary(src, offset, dst: &nonceLength);
46395 UA_CHECK_STATUS(rv, return rv);
46396 if(nonceLength > UA_NETWORKMESSAGE_MAX_NONCE_LENGTH)
46397 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
46398 if(nonceLength > 0) {
46399 dst->securityHeader.messageNonceSize = nonceLength;
46400 for(UA_Byte i = 0; i < nonceLength; i++) {
46401 rv = UA_Byte_decodeBinary(src, offset,
46402 dst: &dst->securityHeader.messageNonce[i]);
46403 UA_CHECK_STATUS(rv, return rv);
46404 }
46405 }
46406
46407 // SecurityFooterSize
46408 if(dst->securityHeader.securityFooterEnabled) {
46409 rv = UA_UInt16_decodeBinary(src, offset, dst: &dst->securityHeader.securityFooterSize);
46410 UA_CHECK_STATUS(rv, return rv);
46411 }
46412 return UA_STATUSCODE_GOOD;
46413}
46414
46415UA_StatusCode
46416UA_NetworkMessage_decodeHeaders(const UA_ByteString *src, size_t *offset, UA_NetworkMessage *dst) {
46417
46418 UA_StatusCode rv = UA_NetworkMessageHeader_decodeBinary(src, offset, dst);
46419 UA_CHECK_STATUS(rv, return rv);
46420
46421 if(dst->groupHeaderEnabled) {
46422 rv = UA_GroupHeader_decodeBinary(src, offset, dst);
46423 UA_CHECK_STATUS(rv, return rv);
46424 }
46425
46426 if(dst->payloadHeaderEnabled) {
46427 rv = UA_PayloadHeader_decodeBinary(src, offset, dst);
46428 UA_CHECK_STATUS(rv, return rv);
46429 }
46430
46431 rv = UA_ExtendedNetworkMessageHeader_decodeBinary(src, offset, dst);
46432 UA_CHECK_STATUS(rv, return rv);
46433
46434 if(dst->securityEnabled) {
46435 rv = UA_SecurityHeader_decodeBinary(src, offset, dst);
46436 UA_CHECK_STATUS(rv, return rv);
46437 }
46438
46439 return UA_STATUSCODE_GOOD;
46440}
46441
46442UA_StatusCode
46443UA_NetworkMessage_decodePayload(const UA_ByteString *src, size_t *offset, UA_NetworkMessage *dst, const UA_DataTypeArray *customTypes, UA_DataSetMetaDataType *dsm) {
46444
46445 // Payload
46446 if(dst->networkMessageType != UA_NETWORKMESSAGE_DATASET)
46447 return UA_STATUSCODE_BADNOTIMPLEMENTED;
46448
46449 UA_StatusCode rv;
46450
46451 UA_Byte count = 1;
46452 if(dst->payloadHeaderEnabled) {
46453 count = dst->payloadHeader.dataSetPayloadHeader.count;
46454 if(count > 1) {
46455 dst->payload.dataSetPayload.sizes = (UA_UInt16 *)UA_Array_new(size: count, type: &UA_TYPES[UA_TYPES_UINT16]);
46456 for(UA_Byte i = 0; i < count; i++) {
46457 rv = UA_UInt16_decodeBinary(src, offset, dst: &dst->payload.dataSetPayload.sizes[i]);
46458 UA_CHECK_STATUS(rv, return rv);
46459 }
46460 }
46461 }
46462
46463 dst->payload.dataSetPayload.dataSetMessages = (UA_DataSetMessage*)
46464 UA_calloc(nmemb: count, size: sizeof(UA_DataSetMessage));
46465 UA_CHECK_MEM(dst->payload.dataSetPayload.dataSetMessages,
46466 return UA_STATUSCODE_BADOUTOFMEMORY);
46467
46468 if(count == 1)
46469 rv = UA_DataSetMessage_decodeBinary(src, offset,
46470 dst: &dst->payload.dataSetPayload.dataSetMessages[0],
46471 dsmSize: 0, customTypes, dsm);
46472 else {
46473 for(UA_Byte i = 0; i < count; i++) {
46474 rv = UA_DataSetMessage_decodeBinary(src, offset,
46475 dst: &dst->payload.dataSetPayload.dataSetMessages[i],
46476 dsmSize: dst->payload.dataSetPayload.sizes[i], customTypes,
46477 dsm);
46478 }
46479 }
46480 UA_CHECK_STATUS(rv, return rv);
46481
46482 return UA_STATUSCODE_GOOD;
46483
46484 /**
46485 * TODO: check if making the cleanup to free its own allocated memory is better,
46486 * currently the free happens in a parent context
46487 */
46488}
46489
46490UA_StatusCode
46491UA_NetworkMessage_decodeFooters(const UA_ByteString *src, size_t *offset,
46492 UA_NetworkMessage *dst) {
46493 if(!dst->securityEnabled)
46494 return UA_STATUSCODE_GOOD;
46495
46496 // SecurityFooter
46497 UA_StatusCode rv = UA_STATUSCODE_GOOD;
46498 if(dst->securityHeader.securityFooterEnabled &&
46499 dst->securityHeader.securityFooterSize > 0) {
46500 rv = UA_ByteString_allocBuffer(bs: &dst->securityFooter,
46501 length: dst->securityHeader.securityFooterSize);
46502 UA_CHECK_STATUS(rv, return rv);
46503
46504 for(UA_UInt16 i = 0; i < dst->securityHeader.securityFooterSize; i++) {
46505 rv |= UA_Byte_decodeBinary(src, offset, dst: &dst->securityFooter.data[i]);
46506 }
46507 }
46508 return rv;
46509}
46510
46511UA_StatusCode
46512UA_NetworkMessage_decodeBinary(const UA_ByteString *src, size_t *offset,
46513 UA_NetworkMessage* dst, const UA_DataTypeArray *customTypes) {
46514 /* headers only need to be decoded when not in encryption mode
46515 * because headers are already decoded when encryption mode is enabled
46516 * to check for security parameters and decrypt/verify
46517 *
46518 * TODO: check if there is a workaround to use this function
46519 * also when encryption is enabled
46520 */
46521 // #ifndef UA_ENABLE_PUBSUB_ENCRYPTION
46522 // if(*offset == 0) {
46523 // rv = UA_NetworkMessage_decodeHeaders(src, offset, dst);
46524 // UA_CHECK_STATUS(rv, return rv);
46525 // }
46526 // #endif
46527
46528 UA_StatusCode rv = UA_NetworkMessage_decodeHeaders(src, offset, dst);
46529 UA_CHECK_STATUS(rv, return rv);
46530
46531 rv = UA_NetworkMessage_decodePayload(src, offset, dst, customTypes, NULL);
46532 UA_CHECK_STATUS(rv, return rv);
46533
46534 rv = UA_NetworkMessage_decodeFooters(src, offset, dst);
46535 UA_CHECK_STATUS(rv, return rv);
46536
46537 return UA_STATUSCODE_GOOD;
46538}
46539
46540static UA_Boolean
46541increaseOffsetArray(UA_NetworkMessageOffsetBuffer *offsetBuffer) {
46542 UA_NetworkMessageOffset *tmpOffsets = (UA_NetworkMessageOffset *)
46543 UA_realloc(ptr: offsetBuffer->offsets, size: sizeof(UA_NetworkMessageOffset) * (offsetBuffer->offsetsSize + (size_t)1));
46544 UA_CHECK_MEM(tmpOffsets, return false);
46545 memset(s: &tmpOffsets[offsetBuffer->offsetsSize], c: 0, n: sizeof(UA_NetworkMessageOffset));
46546 offsetBuffer->offsets = tmpOffsets;
46547 offsetBuffer->offsetsSize++;
46548 return true;
46549}
46550
46551size_t
46552UA_NetworkMessage_calcSizeBinary(UA_NetworkMessage *p,
46553 UA_NetworkMessageOffsetBuffer *offsetBuffer) {
46554 size_t size = 1; /* byte */
46555 if(UA_NetworkMessage_ExtendedFlags1Enabled(src: p)) {
46556 size += 1; /* byte */
46557 if(UA_NetworkMessage_ExtendedFlags2Enabled(src: p))
46558 size += 1; /* byte */
46559 }
46560
46561 if(p->publisherIdEnabled) {
46562 if(offsetBuffer) {
46563 size_t pos = offsetBuffer->offsetsSize;
46564 if(!increaseOffsetArray(offsetBuffer))
46565 return 0;
46566
46567 offsetBuffer->offsets[pos].offset = size;
46568 offsetBuffer->offsets[pos].contentType = UA_PUBSUB_OFFSETTYPE_PUBLISHERID;
46569 }
46570
46571 switch(p->publisherIdType) {
46572 case UA_PUBLISHERIDTYPE_BYTE:
46573 size += 1; /* byte */
46574 break;
46575 case UA_PUBLISHERIDTYPE_UINT16:
46576 size += 2; /* uint16 */
46577 break;
46578 case UA_PUBLISHERIDTYPE_UINT32:
46579 size += 4; /* uint32 */
46580 break;
46581 case UA_PUBLISHERIDTYPE_UINT64:
46582 size += 8; /* uint64 */
46583 break;
46584 case UA_PUBLISHERIDTYPE_STRING:
46585 size += UA_String_calcSizeBinary(src: &p->publisherId.string);
46586 break;
46587 }
46588 }
46589
46590 if(p->dataSetClassIdEnabled)
46591 size += 16; /* guid */
46592
46593 // Group Header
46594 if(p->groupHeaderEnabled) {
46595 size += 1; /* byte */
46596
46597 if(p->groupHeader.writerGroupIdEnabled) {
46598 if(offsetBuffer) {
46599 size_t pos = offsetBuffer->offsetsSize;
46600 if(!increaseOffsetArray(offsetBuffer))
46601 return 0;
46602
46603 offsetBuffer->offsets[pos].offset = size;
46604 offsetBuffer->offsets[pos].contentType = UA_PUBSUB_OFFSETTYPE_WRITERGROUPID;
46605 }
46606 size += 2; /* UA_UInt16_calcSizeBinary(&p->groupHeader.writerGroupId) */
46607 }
46608
46609 if(p->groupHeader.groupVersionEnabled)
46610 size += 4; /* UA_UInt32_calcSizeBinary(&p->groupHeader.groupVersion) */
46611
46612 if(p->groupHeader.networkMessageNumberEnabled) {
46613 size += 2; /* UA_UInt16_calcSizeBinary(&p->groupHeader.networkMessageNumber) */
46614 }
46615
46616 if(p->groupHeader.sequenceNumberEnabled){
46617 if(offsetBuffer){
46618 size_t pos = offsetBuffer->offsetsSize;
46619 if(!increaseOffsetArray(offsetBuffer))
46620 return 0;
46621 offsetBuffer->offsets[pos].offset = size;
46622 offsetBuffer->offsets[pos].content.sequenceNumber =
46623 p->groupHeader.sequenceNumber;
46624 offsetBuffer->offsets[pos].contentType =
46625 UA_PUBSUB_OFFSETTYPE_NETWORKMESSAGE_SEQUENCENUMBER;
46626 }
46627 size += 2; /* UA_UInt16_calcSizeBinary(&p->groupHeader.sequenceNumber) */
46628 }
46629 }
46630
46631 // Payload Header
46632 if(p->payloadHeaderEnabled) {
46633 if(p->networkMessageType != UA_NETWORKMESSAGE_DATASET)
46634 return 0; /* not implemented */
46635 if(!p->payloadHeader.dataSetPayloadHeader.dataSetWriterIds)
46636 return 0; /* no dataSetWriterIds given! */
46637 size += 1; /* p->payloadHeader.dataSetPayloadHeader.count */
46638 if(offsetBuffer) {
46639 size_t pos = offsetBuffer->offsetsSize;
46640 if(!increaseOffsetArray(offsetBuffer))
46641 return 0;
46642 offsetBuffer->offsets[pos].offset = size;
46643 offsetBuffer->offsets[pos].contentType = UA_PUBSUB_OFFSETTYPE_DATASETWRITERID;
46644 }
46645 size += (size_t)(2LU * p->payloadHeader.dataSetPayloadHeader.count); /* uint16 */
46646 }
46647
46648 if(p->timestampEnabled) {
46649 if(offsetBuffer){
46650 size_t pos = offsetBuffer->offsetsSize;
46651 if(!increaseOffsetArray(offsetBuffer))
46652 return 0;
46653 offsetBuffer->offsets[pos].offset = size;
46654 offsetBuffer->offsets[pos].contentType = UA_PUBSUB_OFFSETTYPE_TIMESTAMP;
46655 }
46656 size += 8; /* UA_DateTime_calcSizeBinary(&p->timestamp) */
46657 }
46658
46659 if(p->picosecondsEnabled){
46660 if(offsetBuffer) {
46661 size_t pos = offsetBuffer->offsetsSize;
46662 if(!increaseOffsetArray(offsetBuffer))
46663 return 0;
46664 offsetBuffer->offsets[pos].offset = size;
46665 offsetBuffer->offsets[pos].contentType = UA_PUBSUB_OFFSETTYPE_TIMESTAMP_PICOSECONDS;
46666 }
46667 size += 2; /* UA_UInt16_calcSizeBinary(&p->picoseconds) */
46668 }
46669
46670 if(p->promotedFieldsEnabled) {
46671 size += 2; /* UA_UInt16_calcSizeBinary(&p->promotedFieldsSize) */
46672 for(UA_UInt16 i = 0; i < p->promotedFieldsSize; i++)
46673 size += UA_Variant_calcSizeBinary(src: &p->promotedFields[i]);
46674 }
46675
46676 if(p->securityEnabled) {
46677 size += 1; /* UA_Byte_calcSizeBinary(&byte) */
46678 size += 4; /* UA_UInt32_calcSizeBinary(&p->securityHeader.securityTokenId) */
46679 size += 1; /* UA_Byte_calcSizeBinary(&p->securityHeader.nonceLength) */
46680 size += p->securityHeader.messageNonceSize;
46681 if(p->securityHeader.securityFooterEnabled)
46682 size += 2; /* UA_UInt16_calcSizeBinary(&p->securityHeader.securityFooterSize) */
46683 }
46684
46685 /* Encode the payload */
46686 if(p->networkMessageType != UA_NETWORKMESSAGE_DATASET)
46687 return 0; /* not implemented */
46688 UA_Byte count = 1;
46689 if(p->payloadHeaderEnabled) {
46690 count = p->payloadHeader.dataSetPayloadHeader.count;
46691 if(count > 1)
46692 size += (size_t)(2LU * count); /* uint16 */
46693 }
46694 for(size_t i = 0; i < count; i++) {
46695 UA_DataSetMessage *dsm = &p->payload.dataSetPayload.dataSetMessages[i];
46696 size = UA_DataSetMessage_calcSizeBinary(p: dsm, offsetBuffer, currentOffset: size);
46697 }
46698
46699 if(p->securityEnabled && p->securityHeader.securityFooterEnabled)
46700 size += p->securityHeader.securityFooterSize;
46701
46702 return size;
46703}
46704
46705void
46706UA_NetworkMessage_clear(UA_NetworkMessage* p) {
46707 if(p->promotedFieldsEnabled) {
46708 UA_Array_delete(p: p->promotedFields, size: p->promotedFieldsSize,
46709 type: &UA_TYPES[UA_TYPES_VARIANT]);
46710 }
46711
46712 if(p->networkMessageType == UA_NETWORKMESSAGE_DATASET) {
46713 if(p->payloadHeader.dataSetPayloadHeader.dataSetWriterIds &&
46714 p->payloadHeader.dataSetPayloadHeader.dataSetWriterIds != UA_EMPTY_ARRAY_SENTINEL)
46715 UA_free(ptr: p->payloadHeader.dataSetPayloadHeader.dataSetWriterIds);
46716
46717 if(p->payload.dataSetPayload.sizes)
46718 UA_free(ptr: p->payload.dataSetPayload.sizes);
46719
46720 if(p->payload.dataSetPayload.dataSetMessages) {
46721 UA_Byte count = 1;
46722 if(p->payloadHeaderEnabled)
46723 count = p->payloadHeader.dataSetPayloadHeader.count;
46724 for(size_t i = 0; i < count; i++)
46725 UA_DataSetMessage_clear(p: &p->payload.dataSetPayload.dataSetMessages[i]);
46726 UA_free(ptr: p->payload.dataSetPayload.dataSetMessages);
46727 }
46728 }
46729
46730 UA_ByteString_clear(p: &p->securityFooter);
46731 UA_String_clear(p: &p->messageId);
46732
46733 if(p->publisherIdEnabled &&
46734 p->publisherIdType == UA_PUBLISHERIDTYPE_STRING)
46735 UA_String_clear(p: &p->publisherId.string);
46736
46737 memset(s: p, c: 0, n: sizeof(UA_NetworkMessage));
46738}
46739
46740UA_Boolean
46741UA_NetworkMessage_ExtendedFlags1Enabled(const UA_NetworkMessage* src) {
46742 if(src->publisherIdType != UA_PUBLISHERIDTYPE_BYTE ||
46743 src->dataSetClassIdEnabled || src->securityEnabled ||
46744 src->timestampEnabled || src->picosecondsEnabled ||
46745 UA_NetworkMessage_ExtendedFlags2Enabled(src))
46746 return true;
46747 return false;
46748}
46749
46750UA_Boolean
46751UA_NetworkMessage_ExtendedFlags2Enabled(const UA_NetworkMessage* src) {
46752 if(src->chunkMessage || src->promotedFieldsEnabled ||
46753 src->networkMessageType != UA_NETWORKMESSAGE_DATASET)
46754 return true;
46755 return false;
46756}
46757
46758UA_Boolean
46759UA_DataSetMessageHeader_DataSetFlags2Enabled(const UA_DataSetMessageHeader* src) {
46760 if(src->dataSetMessageType != UA_DATASETMESSAGE_DATAKEYFRAME ||
46761 src->timestampEnabled || src->picoSecondsIncluded)
46762 return true;
46763 return false;
46764}
46765
46766UA_StatusCode
46767UA_DataSetMessageHeader_encodeBinary(const UA_DataSetMessageHeader* src, UA_Byte **bufPos,
46768 const UA_Byte *bufEnd) {
46769 UA_Byte v;
46770 // DataSetFlags1
46771 v = (UA_Byte)src->fieldEncoding;
46772 // shift left 1 bit
46773 v = (UA_Byte)(v << DS_MH_SHIFT_LEN);
46774
46775 if(src->dataSetMessageValid)
46776 v |= DS_MESSAGEHEADER_DS_MSG_VALID;
46777
46778 if(src->dataSetMessageSequenceNrEnabled)
46779 v |= DS_MESSAGEHEADER_SEQ_NR_ENABLED_MASK;
46780
46781 if(src->statusEnabled)
46782 v |= DS_MESSAGEHEADER_STATUS_ENABLED_MASK;
46783
46784 if(src->configVersionMajorVersionEnabled)
46785 v |= DS_MESSAGEHEADER_CONFIGMAJORVERSION_ENABLED_MASK;
46786
46787 if(src->configVersionMinorVersionEnabled)
46788 v |= DS_MESSAGEHEADER_CONFIGMINORVERSION_ENABLED_MASK;
46789
46790 if(UA_DataSetMessageHeader_DataSetFlags2Enabled(src))
46791 v |= DS_MESSAGEHEADER_FLAGS2_ENABLED_MASK;
46792
46793 UA_StatusCode rv = UA_Byte_encodeBinary(src: &v, bufPos, bufEnd);
46794 UA_CHECK_STATUS(rv, return rv);
46795
46796 // DataSetFlags2
46797 if(UA_DataSetMessageHeader_DataSetFlags2Enabled(src)) {
46798 v = (UA_Byte)src->dataSetMessageType;
46799
46800 if(src->timestampEnabled)
46801 v |= DS_MESSAGEHEADER_TIMESTAMP_ENABLED_MASK;
46802
46803 if(src->picoSecondsIncluded)
46804 v |= DS_MESSAGEHEADER_PICOSECONDS_INCLUDED_MASK;
46805
46806 rv = UA_Byte_encodeBinary(src: &v, bufPos, bufEnd);
46807 UA_CHECK_STATUS(rv, return rv);
46808 }
46809
46810 // DataSetMessageSequenceNr
46811 if(src->dataSetMessageSequenceNrEnabled) {
46812 rv = UA_UInt16_encodeBinary(src: &src->dataSetMessageSequenceNr, bufPos, bufEnd);
46813 UA_CHECK_STATUS(rv, return rv);
46814 }
46815
46816 // Timestamp
46817 if(src->timestampEnabled) {
46818 rv = UA_DateTime_encodeBinary(src: &src->timestamp, bufPos, bufEnd); /* UtcTime */
46819 UA_CHECK_STATUS(rv, return rv);
46820 }
46821
46822 // PicoSeconds
46823 if(src->picoSecondsIncluded) {
46824 rv = UA_UInt16_encodeBinary(src: &src->picoSeconds, bufPos, bufEnd);
46825 UA_CHECK_STATUS(rv, return rv);
46826 }
46827
46828 // Status
46829 if(src->statusEnabled) {
46830 rv = UA_UInt16_encodeBinary(src: &src->status, bufPos, bufEnd);
46831 UA_CHECK_STATUS(rv, return rv);
46832 }
46833
46834 // ConfigVersionMajorVersion
46835 if(src->configVersionMajorVersionEnabled) {
46836 rv = UA_UInt32_encodeBinary(src: &src->configVersionMajorVersion, bufPos, bufEnd);
46837 UA_CHECK_STATUS(rv, return rv);
46838 }
46839
46840 // ConfigVersionMinorVersion
46841 if(src->configVersionMinorVersionEnabled) {
46842 rv = UA_UInt32_encodeBinary(src: &src->configVersionMinorVersion, bufPos, bufEnd);
46843 UA_CHECK_STATUS(rv, return rv);
46844 }
46845
46846 return UA_STATUSCODE_GOOD;
46847}
46848
46849#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
46850
46851UA_StatusCode
46852UA_NetworkMessage_signEncrypt(UA_NetworkMessage *nm, UA_MessageSecurityMode securityMode,
46853 UA_PubSubSecurityPolicy *policy, void *policyContext,
46854 UA_Byte *messageStart, UA_Byte *encryptStart,
46855 UA_Byte *sigStart) {
46856 UA_StatusCode res = UA_STATUSCODE_GOOD;
46857
46858 /* Encrypt the payload */
46859 if(securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
46860 /* Set the temporary MessageNonce in the SecurityPolicy */
46861 const UA_ByteString nonce = {
46862 (size_t)nm->securityHeader.messageNonceSize,
46863 nm->securityHeader.messageNonce
46864 };
46865 res = policy->setMessageNonce(policyContext, &nonce);
46866 UA_CHECK_STATUS(res, return res);
46867
46868 /* The encryption is done in-place, no need to encode again */
46869 UA_ByteString encryptBuf;
46870 encryptBuf.data = encryptStart;
46871 encryptBuf.length = (uintptr_t)sigStart - (uintptr_t)encryptStart;
46872 res = policy->symmetricModule.cryptoModule.encryptionAlgorithm.
46873 encrypt(policyContext, &encryptBuf);
46874 UA_CHECK_STATUS(res, return res);
46875 }
46876
46877 /* Sign the entire message */
46878 if(securityMode == UA_MESSAGESECURITYMODE_SIGN ||
46879 securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
46880 UA_ByteString sigBuf;
46881 sigBuf.length = (uintptr_t)sigStart - (uintptr_t)messageStart;
46882 sigBuf.data = messageStart;
46883 size_t sigSize = policy->symmetricModule.cryptoModule.
46884 signatureAlgorithm.getLocalSignatureSize(policyContext);
46885 UA_ByteString sig = {sigSize, sigStart};
46886 res = policy->symmetricModule.cryptoModule.
46887 signatureAlgorithm.sign(policyContext, &sigBuf, &sig);
46888 }
46889
46890 return res;
46891}
46892#endif
46893
46894UA_StatusCode
46895UA_DataSetMessageHeader_decodeBinary(const UA_ByteString *src, size_t *offset,
46896 UA_DataSetMessageHeader* dst) {
46897 memset(s: dst, c: 0, n: sizeof(UA_DataSetMessageHeader));
46898 UA_Byte v = 0;
46899 UA_StatusCode rv = UA_Byte_decodeBinary(src, offset, dst: &v);
46900 UA_CHECK_STATUS(rv, return rv);
46901
46902 UA_Byte v2 = v & DS_MESSAGEHEADER_FIELD_ENCODING_MASK;
46903 v2 = (UA_Byte)(v2 >> DS_MH_SHIFT_LEN);
46904 dst->fieldEncoding = (UA_FieldEncoding)v2;
46905
46906 if((v & DS_MESSAGEHEADER_DS_MSG_VALID) != 0)
46907 dst->dataSetMessageValid = true;
46908
46909 if((v & DS_MESSAGEHEADER_SEQ_NR_ENABLED_MASK) != 0)
46910 dst->dataSetMessageSequenceNrEnabled = true;
46911
46912 if((v & DS_MESSAGEHEADER_STATUS_ENABLED_MASK) != 0)
46913 dst->statusEnabled = true;
46914
46915 if((v & DS_MESSAGEHEADER_CONFIGMAJORVERSION_ENABLED_MASK) != 0)
46916 dst->configVersionMajorVersionEnabled = true;
46917
46918 if((v & DS_MESSAGEHEADER_CONFIGMINORVERSION_ENABLED_MASK) != 0)
46919 dst->configVersionMinorVersionEnabled = true;
46920
46921 if((v & DS_MESSAGEHEADER_FLAGS2_ENABLED_MASK) != 0) {
46922 v = 0;
46923 rv = UA_Byte_decodeBinary(src, offset, dst: &v);
46924 UA_CHECK_STATUS(rv, return rv);
46925
46926 dst->dataSetMessageType = (UA_DataSetMessageType)(v & DS_MESSAGEHEADER_DS_MESSAGE_TYPE_MASK);
46927
46928 if((v & DS_MESSAGEHEADER_TIMESTAMP_ENABLED_MASK) != 0)
46929 dst->timestampEnabled = true;
46930
46931 if((v & DS_MESSAGEHEADER_PICOSECONDS_INCLUDED_MASK) != 0)
46932 dst->picoSecondsIncluded = true;
46933 } else {
46934 dst->dataSetMessageType = UA_DATASETMESSAGE_DATAKEYFRAME;
46935 dst->picoSecondsIncluded = false;
46936 }
46937
46938 if(dst->dataSetMessageSequenceNrEnabled) {
46939 rv = UA_UInt16_decodeBinary(src, offset, dst: &dst->dataSetMessageSequenceNr);
46940 UA_CHECK_STATUS(rv, return rv);
46941 } else {
46942 dst->dataSetMessageSequenceNr = 0;
46943 }
46944
46945 if(dst->timestampEnabled) {
46946 rv = UA_DateTime_decodeBinary(src, offset, dst: &dst->timestamp); /* UtcTime */
46947 UA_CHECK_STATUS(rv, return rv);
46948 } else {
46949 dst->timestamp = 0;
46950 }
46951
46952 if(dst->picoSecondsIncluded) {
46953 rv = UA_UInt16_decodeBinary(src, offset, dst: &dst->picoSeconds);
46954 UA_CHECK_STATUS(rv, return rv);
46955 } else {
46956 dst->picoSeconds = 0;
46957 }
46958
46959 if(dst->statusEnabled) {
46960 rv = UA_UInt16_decodeBinary(src, offset, dst: &dst->status);
46961 UA_CHECK_STATUS(rv, return rv);
46962 } else {
46963 dst->status = 0;
46964 }
46965
46966 if(dst->configVersionMajorVersionEnabled) {
46967 rv = UA_UInt32_decodeBinary(src, offset, dst: &dst->configVersionMajorVersion);
46968 UA_CHECK_STATUS(rv, return rv);
46969 } else {
46970 dst->configVersionMajorVersion = 0;
46971 }
46972
46973 if(dst->configVersionMinorVersionEnabled) {
46974 rv = UA_UInt32_decodeBinary(src, offset, dst: &dst->configVersionMinorVersion);
46975 UA_CHECK_STATUS(rv, return rv);
46976 } else {
46977 dst->configVersionMinorVersion = 0;
46978 }
46979
46980 return UA_STATUSCODE_GOOD;
46981}
46982
46983UA_StatusCode
46984UA_DataSetMessage_encodeBinary(const UA_DataSetMessage* src, UA_Byte **bufPos,
46985 const UA_Byte *bufEnd) {
46986 UA_StatusCode rv = UA_DataSetMessageHeader_encodeBinary(src: &src->header, bufPos, bufEnd);
46987 UA_CHECK_STATUS(rv, return rv);
46988
46989 if(src->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) {
46990 /* Heartbeat: "DataSetMessage is a key frame that only contains header
46991 * information" */
46992 if(src->data.keyFrameData.fieldCount == 0)
46993 return rv;
46994
46995 if(src->header.fieldEncoding != UA_FIELDENCODING_RAWDATA) {
46996 rv = UA_UInt16_encodeBinary(src: &src->data.keyFrameData.fieldCount,
46997 bufPos, bufEnd);
46998 UA_CHECK_STATUS(rv, return rv);
46999 }
47000
47001 for(UA_UInt16 i = 0; i < src->data.keyFrameData.fieldCount; i++) {
47002 const UA_DataValue *v = &src->data.keyFrameData.dataSetFields[i];
47003
47004 if(src->header.fieldEncoding == UA_FIELDENCODING_VARIANT) {
47005 rv = UA_Variant_encodeBinary(src: &v->value, bufPos, bufEnd);
47006 } else if(src->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) {
47007 UA_FieldMetaData *fmd =
47008 &src->data.keyFrameData.dataSetMetaDataType->fields[i];
47009 if(fmd->maxStringLength != 0 &&
47010 (v->value.type->typeKind == UA_DATATYPEKIND_STRING ||
47011 v->value.type->typeKind == UA_DATATYPEKIND_BYTESTRING)){
47012 rv = UA_encodeBinaryInternal(src: v->value.data, type: v->value.type,
47013 bufPos, bufEnd: &bufEnd, NULL, NULL);
47014 size_t lengthDifference = fmd->maxStringLength -
47015 ((UA_String *)v->value.data)->length;
47016 memset(s: *bufPos, c: 0, n: lengthDifference);
47017 *bufPos += lengthDifference;
47018 } else {
47019 /* padding not yet supported for strings as part of structures */
47020 rv = UA_encodeBinaryInternal(src: v->value.data, type: v->value.type,
47021 bufPos, bufEnd: &bufEnd, NULL, NULL);
47022 }
47023 } else if(src->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) {
47024 rv = UA_DataValue_encodeBinary(src: v, bufPos, bufEnd);
47025 }
47026
47027 UA_CHECK_STATUS(rv, return rv);
47028 }
47029 } else if(src->header.dataSetMessageType == UA_DATASETMESSAGE_DATADELTAFRAME) {
47030 // Encode Delta Frame
47031 // Here the FieldCount is always present
47032 rv = UA_UInt16_encodeBinary(src: &src->data.deltaFrameData.fieldCount, bufPos, bufEnd);
47033 UA_CHECK_STATUS(rv, return rv);
47034
47035 if(src->header.fieldEncoding == UA_FIELDENCODING_VARIANT) {
47036 for(UA_UInt16 i = 0; i < src->data.deltaFrameData.fieldCount; i++) {
47037 rv = UA_UInt16_encodeBinary(src: &src->data.deltaFrameData.deltaFrameFields[i].fieldIndex, bufPos, bufEnd);
47038 UA_CHECK_STATUS(rv, return rv);
47039
47040 rv = UA_Variant_encodeBinary(src: &src->data.deltaFrameData.deltaFrameFields[i].fieldValue.value, bufPos, bufEnd);
47041 UA_CHECK_STATUS(rv, return rv);
47042 }
47043 } else if(src->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) {
47044 return UA_STATUSCODE_BADNOTIMPLEMENTED;
47045 } else if(src->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) {
47046 for(UA_UInt16 i = 0; i < src->data.deltaFrameData.fieldCount; i++) {
47047 rv = UA_UInt16_encodeBinary(src: &src->data.deltaFrameData.deltaFrameFields[i].fieldIndex, bufPos, bufEnd);
47048 UA_CHECK_STATUS(rv, return rv);
47049
47050 rv = UA_DataValue_encodeBinary(src: &src->data.deltaFrameData.deltaFrameFields[i].fieldValue, bufPos, bufEnd);
47051 UA_CHECK_STATUS(rv, return rv);
47052 }
47053 }
47054 } else if(src->header.dataSetMessageType != UA_DATASETMESSAGE_KEEPALIVE) {
47055 return UA_STATUSCODE_BADNOTIMPLEMENTED;
47056 }
47057
47058 /* if the configuredSize is set -> padd the message with 0. */
47059 if(src->configuredSize > 0 && src->header.dataSetMessageValid) {
47060 size_t padding = (size_t)(bufEnd - *bufPos);
47061 /* Set the bytes to 0*/
47062 memset(s: *bufPos, c: 0, n: padding);
47063 /* move the bufpos accordingly*/
47064 *bufPos += padding;
47065 }
47066 /* Keep-Alive Message contains no Payload Data */
47067 return UA_STATUSCODE_GOOD;
47068}
47069
47070UA_StatusCode
47071UA_DataSetMessage_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DataSetMessage* dst, UA_UInt16 dsmSize, const UA_DataTypeArray *customTypes, UA_DataSetMetaDataType *dsm) {
47072 size_t initialOffset = *offset;
47073 memset(s: dst, c: 0, n: sizeof(UA_DataSetMessage));
47074 UA_StatusCode rv = UA_DataSetMessageHeader_decodeBinary(src, offset, dst: &dst->header);
47075 UA_CHECK_STATUS(rv, return rv);
47076
47077 if(dst->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) {
47078 if(*offset == src->length) {
47079 /* Messages ends after the header --> Heartbeat */
47080 return rv;
47081 }
47082
47083 switch(dst->header.fieldEncoding) {
47084 case UA_FIELDENCODING_VARIANT:
47085 rv = UA_UInt16_decodeBinary(src, offset, dst: &dst->data.keyFrameData.fieldCount);
47086 UA_CHECK_STATUS(rv, return rv);
47087 dst->data.keyFrameData.dataSetFields =
47088 (UA_DataValue *)UA_Array_new(size: dst->data.keyFrameData.fieldCount, type: &UA_TYPES[UA_TYPES_DATAVALUE]);
47089 for(UA_UInt16 i = 0; i < dst->data.keyFrameData.fieldCount; i++) {
47090 UA_DataValue_init(p: &dst->data.keyFrameData.dataSetFields[i]);
47091 rv = UA_decodeBinaryInternal(src, offset, dst: &dst->data.keyFrameData.dataSetFields[i].value, type: &UA_TYPES[UA_TYPES_VARIANT], customTypes);
47092 UA_CHECK_STATUS(rv, return rv);
47093
47094 dst->data.keyFrameData.dataSetFields[i].hasValue = true;
47095 }
47096 break;
47097 case UA_FIELDENCODING_DATAVALUE:
47098 rv = UA_UInt16_decodeBinary(src, offset, dst: &dst->data.keyFrameData.fieldCount);
47099 UA_CHECK_STATUS(rv, return rv);
47100 dst->data.keyFrameData.dataSetFields =
47101 (UA_DataValue *)UA_Array_new(size: dst->data.keyFrameData.fieldCount, type: &UA_TYPES[UA_TYPES_DATAVALUE]);
47102 for(UA_UInt16 i = 0; i < dst->data.keyFrameData.fieldCount; i++) {
47103 rv = UA_decodeBinaryInternal(src, offset,
47104 dst: &dst->data.keyFrameData.dataSetFields[i],
47105 type: &UA_TYPES[UA_TYPES_DATAVALUE], customTypes);
47106 UA_CHECK_STATUS(rv, return rv);
47107 }
47108 break;
47109 case UA_FIELDENCODING_RAWDATA:
47110 dst->data.keyFrameData.rawFields.data = &src->data[*offset];
47111 dst->data.keyFrameData.rawFields.length = dsmSize;
47112 if(dsmSize == 0){
47113 if(dsm != NULL) {
47114 size_t tmpOffset = 0;
47115 // calculate the length of the DSM-Payload for a single DSM
47116 dst->data.keyFrameData.fieldCount = (UA_UInt16)dsm->fieldsSize;
47117 for(size_t i = 0; i < dsm->fieldsSize; i++) {
47118 /* TODO The datatype reference should be part of the internal
47119 * pubsub configuration to avoid the time-expensive lookup */
47120 const UA_DataType *type =
47121 UA_findDataTypeWithCustom(typeId: &dsm->fields[i].dataType,
47122 customTypes);
47123 dst->data.keyFrameData.rawFields.length += type->memSize;
47124 UA_STACKARRAY(UA_Byte, value, type->memSize);
47125 rv = UA_decodeBinaryInternal(src: &dst->data.keyFrameData.rawFields,
47126 offset: &tmpOffset, dst: value, type, NULL);
47127 UA_CHECK_STATUS(rv, return rv);
47128 if(dsm->fields[i].maxStringLength != 0) {
47129 if(type->typeKind == UA_DATATYPEKIND_STRING ||
47130 type->typeKind == UA_DATATYPEKIND_BYTESTRING) {
47131 UA_ByteString *bs = (UA_ByteString *) value;
47132 //check if length < maxStringLength, The types ByteString and String are equal in their base definition
47133 size_t lengthDifference = dsm->fields[i].maxStringLength - bs->length;
47134 tmpOffset += lengthDifference;
47135 dst->data.keyFrameData.rawFields.length += lengthDifference;
47136 }
47137 }
47138 }
47139 *offset += tmpOffset;
47140 } else {
47141 //TODO calculate the length of the DSM-Payload for a single DSM
47142 //Problem: Size is not set and MetaData information are needed.
47143 //Increase offset to avoid endless chunk loop. Needs to be fixed when
47144 //pubsub security footer and signatur is enabled.
47145 *offset += 1500;
47146 }
47147 } else {
47148 *offset += (dsmSize - (*offset - initialOffset));
47149 }
47150 break;
47151 default:
47152 return UA_STATUSCODE_BADINTERNALERROR;
47153 }
47154 } else if(dst->header.dataSetMessageType == UA_DATASETMESSAGE_DATADELTAFRAME) {
47155 switch(dst->header.fieldEncoding) {
47156 case UA_FIELDENCODING_VARIANT: {
47157 rv = UA_UInt16_decodeBinary(src, offset, dst: &dst->data.deltaFrameData.fieldCount);
47158 UA_CHECK_STATUS(rv, return rv);
47159 size_t memsize = sizeof(UA_DataSetMessage_DeltaFrameField) * dst->data.deltaFrameData.fieldCount;
47160 dst->data.deltaFrameData.deltaFrameFields = (UA_DataSetMessage_DeltaFrameField*)UA_malloc(size: memsize);
47161 for(UA_UInt16 i = 0; i < dst->data.deltaFrameData.fieldCount; i++) {
47162 rv = UA_UInt16_decodeBinary(src, offset, dst: &dst->data.deltaFrameData.deltaFrameFields[i].fieldIndex);
47163 UA_CHECK_STATUS(rv, return rv);
47164
47165 UA_DataValue_init(p: &dst->data.deltaFrameData.deltaFrameFields[i].fieldValue);
47166 rv = UA_decodeBinaryInternal(src, offset, dst: &dst->data.deltaFrameData.deltaFrameFields[i].fieldValue.value, type: &UA_TYPES[UA_TYPES_VARIANT], customTypes);
47167 UA_CHECK_STATUS(rv, return rv);
47168
47169 dst->data.deltaFrameData.deltaFrameFields[i].fieldValue.hasValue = true;
47170 }
47171 break;
47172 }
47173 case UA_FIELDENCODING_DATAVALUE: {
47174 rv = UA_UInt16_decodeBinary(src, offset, dst: &dst->data.deltaFrameData.fieldCount);
47175 UA_CHECK_STATUS(rv, return rv);
47176 size_t memsize = sizeof(UA_DataSetMessage_DeltaFrameField) * dst->data.deltaFrameData.fieldCount;
47177 dst->data.deltaFrameData.deltaFrameFields = (UA_DataSetMessage_DeltaFrameField*)UA_malloc(size: memsize);
47178 for(UA_UInt16 i = 0; i < dst->data.deltaFrameData.fieldCount; i++) {
47179 rv = UA_UInt16_decodeBinary(src, offset, dst: &dst->data.deltaFrameData.deltaFrameFields[i].fieldIndex);
47180 UA_CHECK_STATUS(rv, return rv);
47181
47182 rv = UA_decodeBinaryInternal(src, offset,
47183 dst: &dst->data.deltaFrameData.deltaFrameFields[i].fieldValue,
47184 type: &UA_TYPES[UA_TYPES_DATAVALUE], customTypes);
47185
47186 UA_CHECK_STATUS(rv, return rv);
47187 }
47188 break;
47189 }
47190 case UA_FIELDENCODING_RAWDATA: {
47191 return UA_STATUSCODE_BADNOTIMPLEMENTED;
47192 }
47193 default:
47194 return UA_STATUSCODE_BADINTERNALERROR;
47195 }
47196 } else if(dst->header.dataSetMessageType != UA_DATASETMESSAGE_KEEPALIVE) {
47197 return UA_STATUSCODE_BADNOTIMPLEMENTED;
47198 }
47199
47200 /* Keep-Alive Message contains no Payload Data */
47201 return UA_STATUSCODE_GOOD;
47202}
47203
47204size_t
47205UA_DataSetMessage_calcSizeBinary(UA_DataSetMessage* p,
47206 UA_NetworkMessageOffsetBuffer *offsetBuffer,
47207 size_t currentOffset) {
47208 size_t size = currentOffset;
47209
47210 if(offsetBuffer) {
47211 size_t pos = offsetBuffer->offsetsSize;
47212 if(!increaseOffsetArray(offsetBuffer))
47213 return 0;
47214 offsetBuffer->offsets[pos].offset = size;
47215 UA_DataValue_init(p: &offsetBuffer->offsets[pos].content.value);
47216 UA_Variant_setScalar(v: &offsetBuffer->offsets[pos].content.value.value,
47217 p: &p->header.fieldEncoding, type: &UA_TYPES[UA_TYPES_UINT32]);
47218 offsetBuffer->offsets[pos].contentType =
47219 UA_PUBSUB_OFFSETTYPE_NETWORKMESSAGE_FIELDENCDODING;
47220 }
47221
47222 size += 1; /* byte: DataSetMessage Type + Flags */
47223 if(UA_DataSetMessageHeader_DataSetFlags2Enabled(src: &p->header))
47224 size += 1; /* byte */
47225
47226 if(p->header.dataSetMessageSequenceNrEnabled) {
47227 if(offsetBuffer) {
47228 size_t pos = offsetBuffer->offsetsSize;
47229 if(!increaseOffsetArray(offsetBuffer))
47230 return 0;
47231 offsetBuffer->offsets[pos].offset = size;
47232 offsetBuffer->offsets[pos].content.sequenceNumber =
47233 p->header.dataSetMessageSequenceNr;
47234 offsetBuffer->offsets[pos].contentType =
47235 UA_PUBSUB_OFFSETTYPE_DATASETMESSAGE_SEQUENCENUMBER;
47236 }
47237 size += 2; /* UA_UInt16_calcSizeBinary(&p->header.dataSetMessageSequenceNr) */
47238 }
47239
47240 if(p->header.timestampEnabled)
47241 size += 8; /* UA_DateTime_calcSizeBinary(&p->header.timestamp) */
47242
47243 if(p->header.picoSecondsIncluded)
47244 size += 2; /* UA_UInt16_calcSizeBinary(&p->header.picoSeconds) */
47245
47246 if(p->header.statusEnabled)
47247 size += 2; /* UA_UInt16_calcSizeBinary(&p->header.status) */
47248
47249 if(p->header.configVersionMajorVersionEnabled)
47250 size += 4; /* UA_UInt32_calcSizeBinary(&p->header.configVersionMajorVersion) */
47251
47252 if(p->header.configVersionMinorVersionEnabled)
47253 size += 4; /* UA_UInt32_calcSizeBinary(&p->header.configVersionMinorVersion) */
47254
47255 /* Keyframe with no fields is a heartbeat */
47256 if(p->header.dataSetMessageType == UA_DATASETMESSAGE_KEEPALIVE ||
47257 (p->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME &&
47258 p->data.keyFrameData.fieldCount == 0))
47259 return size;
47260
47261 if(p->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) {
47262 if(p->header.fieldEncoding != UA_FIELDENCODING_RAWDATA)
47263 size += 2; /* p->data.keyFrameData.fieldCount */
47264
47265 for(UA_UInt16 i = 0; i < p->data.keyFrameData.fieldCount; i++){
47266 UA_NetworkMessageOffset *nmo = NULL;
47267 const UA_DataValue *v = &p->data.keyFrameData.dataSetFields[i];
47268 if(offsetBuffer) {
47269 size_t pos = offsetBuffer->offsetsSize;
47270 if(!increaseOffsetArray(offsetBuffer))
47271 return 0;
47272 nmo = &offsetBuffer->offsets[pos];
47273 nmo->offset = size;
47274 }
47275
47276 if(p->header.fieldEncoding == UA_FIELDENCODING_VARIANT) {
47277 if(offsetBuffer)
47278 nmo->contentType = UA_PUBSUB_OFFSETTYPE_PAYLOAD_VARIANT;
47279 size += UA_calcSizeBinary(p: &v->value, type: &UA_TYPES[UA_TYPES_VARIANT]);
47280 } else if(p->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) {
47281 if(p->data.keyFrameData.dataSetFields != NULL) {
47282 if(offsetBuffer) {
47283 if(!v->value.type->pointerFree)
47284 return 0; /* only integer types for now */
47285 /* Count the memory size of the specific field */
47286 offsetBuffer->rawMessageLength += v->value.type->memSize;
47287 nmo->contentType = UA_PUBSUB_OFFSETTYPE_PAYLOAD_RAW;
47288 }
47289 size += UA_calcSizeBinary(p: v->value.data, type: v->value.type);
47290
47291 /* Handle zero-padding for strings with max-string-length.
47292 * Currently not supported for strings that are a part of larger
47293 * structures. */
47294 UA_FieldMetaData *fmd =
47295 &p->data.keyFrameData.dataSetMetaDataType->fields[i];
47296 if(fmd->maxStringLength != 0 &&
47297 (v->value.type->typeKind == UA_DATATYPEKIND_STRING ||
47298 v->value.type->typeKind == UA_DATATYPEKIND_BYTESTRING)) {
47299 /* Check if length < maxStringLength, The types ByteString
47300 * and String are equal in their base definition */
47301 size_t lengthDifference = fmd->maxStringLength -
47302 ((UA_String *)v->value.data)->length;
47303 size += lengthDifference;
47304 }
47305 } else {
47306 /* get length calculated in UA_DataSetMessage_decodeBinary */
47307 if(offsetBuffer) {
47308 offsetBuffer->rawMessageLength = p->data.keyFrameData.rawFields.length;
47309 nmo->contentType = UA_PUBSUB_OFFSETTYPE_PAYLOAD_RAW;
47310 }
47311 size += p->data.keyFrameData.rawFields.length;
47312 /* no iteration needed */
47313 break;
47314 }
47315 } else if(p->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) {
47316 if(offsetBuffer)
47317 nmo->contentType = UA_PUBSUB_OFFSETTYPE_PAYLOAD_DATAVALUE;
47318 size += UA_calcSizeBinary(p: v, type: &UA_TYPES[UA_TYPES_DATAVALUE]);
47319 }
47320 }
47321 } else if(p->header.dataSetMessageType == UA_DATASETMESSAGE_DATADELTAFRAME) {
47322 if(offsetBuffer)
47323 return 0; /* Not supported for RT */
47324
47325 if(p->header.fieldEncoding == UA_FIELDENCODING_RAWDATA)
47326 return 0; /* not supported */
47327
47328 size += 2; /* p->data.deltaFrameData.fieldCount */
47329 size += (size_t)(2LU * p->data.deltaFrameData.fieldCount); /* fieldIndex per field */
47330
47331 for(UA_UInt16 i = 0; i < p->data.deltaFrameData.fieldCount; i++) {
47332 const UA_DataValue *v = &p->data.deltaFrameData.deltaFrameFields[i].fieldValue;
47333 if(p->header.fieldEncoding == UA_FIELDENCODING_VARIANT)
47334 size += UA_calcSizeBinary(p: &v->value, type: &UA_TYPES[UA_TYPES_VARIANT]);
47335 else if(p->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE)
47336 size += UA_calcSizeBinary(p: v, type: &UA_TYPES[UA_TYPES_DATAVALUE]);
47337 }
47338 } else {
47339 return 0;
47340 }
47341
47342 if(p->configuredSize > 0) {
47343 /* If the message is larger than the configuredSize, it shall be set to not valid */
47344 if(p->configuredSize < size)
47345 p->header.dataSetMessageValid = UA_FALSE;
47346
47347 size = p->configuredSize;
47348 }
47349
47350 /* KeepAlive-Message contains no Payload Data */
47351 return size;
47352}
47353
47354void
47355UA_DataSetMessage_clear(UA_DataSetMessage* p) {
47356 if(p->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) {
47357 if(p->data.keyFrameData.dataSetFields) {
47358 UA_Array_delete(p: p->data.keyFrameData.dataSetFields,
47359 size: p->data.keyFrameData.fieldCount,
47360 type: &UA_TYPES[UA_TYPES_DATAVALUE]);
47361 }
47362
47363 /* Json keys */
47364 if(p->data.keyFrameData.fieldNames){
47365 UA_Array_delete(p: p->data.keyFrameData.fieldNames,
47366 size: p->data.keyFrameData.fieldCount,
47367 type: &UA_TYPES[UA_TYPES_STRING]);
47368 }
47369 } else if(p->header.dataSetMessageType == UA_DATASETMESSAGE_DATADELTAFRAME) {
47370 if(p->data.deltaFrameData.deltaFrameFields) {
47371 for(UA_UInt16 i = 0; i < p->data.deltaFrameData.fieldCount; i++) {
47372 UA_DataSetMessage_DeltaFrameField *f =
47373 &p->data.deltaFrameData.deltaFrameFields[i];
47374 UA_DataValue_clear(p: &f->fieldValue);
47375 }
47376 UA_free(ptr: p->data.deltaFrameData.deltaFrameFields);
47377 }
47378 }
47379
47380 memset(s: p, c: 0, n: sizeof(UA_DataSetMessage));
47381}
47382
47383void
47384UA_NetworkMessageOffsetBuffer_clear(UA_NetworkMessageOffsetBuffer *nmob) {
47385 UA_ByteString_clear(p: &nmob->buffer);
47386
47387 if(nmob->nm) {
47388 UA_NetworkMessage_clear(p: nmob->nm);
47389 UA_free(ptr: nmob->nm);
47390 }
47391
47392#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
47393 UA_ByteString_clear(&nmob->encryptBuffer);
47394#endif
47395
47396 if(nmob->offsetsSize == 0)
47397 return;
47398
47399 for(size_t i = 0; i < nmob->offsetsSize; i++) {
47400 UA_NetworkMessageOffset *offset = &nmob->offsets[i];
47401 if(offset->contentType == UA_PUBSUB_OFFSETTYPE_PAYLOAD_VARIANT ||
47402 offset->contentType == UA_PUBSUB_OFFSETTYPE_PAYLOAD_DATAVALUE ||
47403 offset->contentType == UA_PUBSUB_OFFSETTYPE_PAYLOAD_RAW) {
47404 UA_DataValue_clear(p: &offset->content.value);
47405 continue;
47406 }
47407
47408 if(offset->contentType == UA_PUBSUB_OFFSETTYPE_NETWORKMESSAGE_FIELDENCDODING) {
47409 offset->content.value.value.data = NULL;
47410 UA_DataValue_clear(p: &offset->content.value);
47411 }
47412 }
47413
47414 UA_free(ptr: nmob->offsets);
47415
47416 memset(s: nmob, c: 0, n: sizeof(UA_NetworkMessageOffsetBuffer));
47417}
47418
47419#endif /* UA_ENABLE_PUBSUB */
47420
47421/**** amalgamated original file "/src/pubsub/ua_pubsub_eventloop.c" ****/
47422
47423/* This Source Code Form is subject to the terms of the Mozilla Public
47424 * License, v. 2.0. If a copy of the MPL was not distributed with this
47425 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
47426 *
47427 * Copyright (c) 2023 Fraunhofer IOSB (Author: Julius Pfrommer)
47428 */
47429
47430
47431#ifdef UA_ENABLE_PUBSUB /* conditional compilation */
47432
47433/********************/
47434/* PubSubConnection */
47435/********************/
47436
47437static UA_StatusCode
47438UA_PubSubConnection_connectUDP(UA_Server *server, UA_PubSubConnection *c,
47439 UA_Boolean validate);
47440
47441static UA_StatusCode
47442UA_PubSubConnection_connectETH(UA_Server *server, UA_PubSubConnection *c,
47443 UA_Boolean validate);
47444
47445static UA_StatusCode
47446UA_ReaderGroup_connectMQTT(UA_Server *server, UA_ReaderGroup *rg,
47447 UA_Boolean validate);
47448
47449static UA_StatusCode
47450UA_WriterGroup_connectMQTT(UA_Server *server, UA_WriterGroup *wg,
47451 UA_Boolean validate);
47452
47453static UA_StatusCode
47454UA_WriterGroup_connectUDPUnicast(UA_Server *server, UA_WriterGroup *wg,
47455 UA_Boolean validate);
47456
47457#define UA_PUBSUB_PROFILES_SIZE 4
47458
47459typedef struct {
47460 UA_String profileURI;
47461 UA_String protocol;
47462 UA_Boolean json;
47463 UA_StatusCode (*connect)(UA_Server *server, UA_PubSubConnection *c,
47464 UA_Boolean validate);
47465 UA_StatusCode (*connectWriterGroup)(UA_Server *server, UA_WriterGroup *wg,
47466 UA_Boolean validate);
47467 UA_StatusCode (*connectReaderGroup)(UA_Server *server, UA_ReaderGroup *rg,
47468 UA_Boolean validate);
47469} ProfileMapping;
47470
47471static ProfileMapping transportProfiles[UA_PUBSUB_PROFILES_SIZE] = {
47472 {UA_STRING_STATIC("http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp"),
47473 UA_STRING_STATIC("udp"), false, UA_PubSubConnection_connectUDP,
47474 UA_WriterGroup_connectUDPUnicast, NULL},
47475 {UA_STRING_STATIC("http://opcfoundation.org/UA-Profile/Transport/pubsub-mqtt-uadp"),
47476 UA_STRING_STATIC("mqtt"), false, NULL,
47477 UA_WriterGroup_connectMQTT, UA_ReaderGroup_connectMQTT},
47478 {UA_STRING_STATIC("http://opcfoundation.org/UA-Profile/Transport/pubsub-mqtt-json"),
47479 UA_STRING_STATIC("mqtt"), true, NULL,
47480 UA_WriterGroup_connectMQTT, UA_ReaderGroup_connectMQTT},
47481 {UA_STRING_STATIC("http://opcfoundation.org/UA-Profile/Transport/pubsub-eth-uadp"),
47482 UA_STRING_STATIC("eth"), false, UA_PubSubConnection_connectETH, NULL, NULL}
47483};
47484
47485static ProfileMapping *
47486getProfile(UA_String profileUri) {
47487 for(size_t profile = 0; profile < UA_PUBSUB_PROFILES_SIZE; profile++) {
47488 if(UA_String_equal(p1: &profileUri, p2: &transportProfiles[profile].profileURI))
47489 return &transportProfiles[profile];
47490 }
47491 return NULL;
47492}
47493
47494static UA_ConnectionManager *
47495getCM(UA_EventLoop *el, UA_String protocol) {
47496 for(UA_EventSource *es = el->eventSources; es != NULL; es = es->next) {
47497 if(es->eventSourceType != UA_EVENTSOURCETYPE_CONNECTIONMANAGER)
47498 continue;
47499 UA_ConnectionManager *cm = (UA_ConnectionManager*)es;
47500 if(UA_String_equal(p1: &protocol, p2: &cm->protocol))
47501 return cm;
47502 }
47503 return NULL;
47504}
47505
47506static void
47507UA_PubSubConnection_removeConnection(UA_PubSubConnection *c,
47508 uintptr_t connectionId) {
47509 if(c->sendChannel == connectionId) {
47510 c->sendChannel = 0;
47511 return;
47512 }
47513 for(size_t i = 0; i < UA_PUBSUB_MAXCHANNELS; i++) {
47514 if(c->recvChannels[i] != connectionId)
47515 continue;
47516 c->recvChannels[i] = 0;
47517 c->recvChannelsSize--;
47518 return;
47519 }
47520}
47521
47522static UA_StatusCode
47523UA_PubSubConnection_addSendConnection(UA_PubSubConnection *c,
47524 uintptr_t connectionId) {
47525 if(c->sendChannel != 0 && c->sendChannel != connectionId)
47526 return UA_STATUSCODE_BADINTERNALERROR;
47527 c->sendChannel = connectionId;
47528 return UA_STATUSCODE_GOOD;
47529}
47530
47531static UA_StatusCode
47532UA_PubSubConnection_addRecvConnection(UA_PubSubConnection *c,
47533 uintptr_t connectionId) {
47534 for(size_t i = 0; i < UA_PUBSUB_MAXCHANNELS; i++) {
47535 if(c->recvChannels[i] == connectionId)
47536 return UA_STATUSCODE_GOOD;
47537 }
47538 if(c->recvChannelsSize >= UA_PUBSUB_MAXCHANNELS)
47539 return UA_STATUSCODE_BADINTERNALERROR;
47540 for(size_t i = 0; i < UA_PUBSUB_MAXCHANNELS; i++) {
47541 if(c->recvChannels[i] != 0)
47542 continue;
47543 c->recvChannels[i] = connectionId;
47544 c->recvChannelsSize++;
47545 break;
47546 }
47547 return UA_STATUSCODE_GOOD;
47548}
47549
47550void
47551UA_PubSubConnection_disconnect(UA_PubSubConnection *c) {
47552 if(!c->cm)
47553 return;
47554 if(c->sendChannel != 0)
47555 c->cm->closeConnection(c->cm, c->sendChannel);
47556 for(size_t i = 0; i < UA_PUBSUB_MAXCHANNELS; i++) {
47557 if(c->recvChannels[i] != 0)
47558 c->cm->closeConnection(c->cm, c->recvChannels[i]);
47559 }
47560}
47561
47562static void
47563PubSubChannelCallback(UA_ConnectionManager *cm, uintptr_t connectionId,
47564 void *application, void **connectionContext,
47565 UA_ConnectionState state, const UA_KeyValueMap *params,
47566 UA_ByteString msg, UA_Boolean recv) {
47567 if(!connectionContext)
47568 return;
47569
47570 /* Get the context pointers */
47571 UA_Server *server = (UA_Server*)application;
47572 UA_PubSubConnection *psc = (UA_PubSubConnection*)*connectionContext;
47573
47574 lockServer(server);
47575
47576 /* The connection is closing in the EventLoop. This is the last callback
47577 * from that connection. Clean up the SecureChannel in the client. */
47578 if(state == UA_CONNECTIONSTATE_CLOSING) {
47579 /* Reset the connection identifiers */
47580 UA_PubSubConnection_removeConnection(c: psc, connectionId);
47581
47582 /* PSC marked for deletion and the last EventLoop connection has closed */
47583 if(psc->deleteFlag && psc->recvChannelsSize == 0 && psc->sendChannel == 0) {
47584 UA_PubSubConnection_delete(server, c: psc);
47585 unlockServer(server);
47586 return;
47587 }
47588
47589 /* Reconnect automatically if the connection was operational. This sets
47590 * the connection state if connecting fails. Attention! If there are
47591 * several send or recv channels, then the connection is only reopened if
47592 * all of them close - which is usually the case. */
47593 if(psc->state == UA_PUBSUBSTATE_OPERATIONAL)
47594 UA_PubSubConnection_connect(server, c: psc, false);
47595
47596 unlockServer(server);
47597 return;
47598 }
47599
47600 /* Store the connectionId (if a new connection) */
47601 UA_StatusCode res = (recv) ?
47602 UA_PubSubConnection_addRecvConnection(c: psc, connectionId) :
47603 UA_PubSubConnection_addSendConnection(c: psc, connectionId);
47604 if(res != UA_STATUSCODE_GOOD) {
47605 UA_LOG_WARNING_CONNECTION(server->config.logging, psc,
47606 "No more space for an additional EventLoop connection");
47607 if(psc->cm)
47608 psc->cm->closeConnection(psc->cm, connectionId);
47609 unlockServer(server);
47610 return;
47611 }
47612
47613 /* No message received */
47614 if(!recv || msg.length == 0) {
47615 unlockServer(server);
47616 return;
47617 }
47618
47619 /* Connection open, set to operational if not already done */
47620 if(psc->state != UA_PUBSUBSTATE_OPERATIONAL)
47621 UA_PubSubConnection_setPubSubState(server, connection: psc, state: UA_PUBSUBSTATE_OPERATIONAL,
47622 UA_STATUSCODE_GOOD);
47623
47624 UA_NetworkMessage nm;
47625 memset(s: &nm, c: 0, n: sizeof(UA_NetworkMessage));
47626
47627 UA_Boolean nonRT = false;
47628 UA_Boolean processed = false;
47629
47630 /* Process buffer ReaderGroups */
47631 UA_ReaderGroup *rg;
47632 LIST_FOREACH(rg, &psc->readerGroups, listEntry) {
47633 if(rg->state != UA_PUBSUBSTATE_OPERATIONAL &&
47634 rg->state != UA_PUBSUBSTATE_PREOPERATIONAL)
47635 continue;
47636 if(rg->config.rtLevel & UA_PUBSUB_RT_FIXED_SIZE) {
47637 processed |= UA_ReaderGroup_decodeAndProcessRT(server, readerGroup: rg, buf: &msg);
47638 continue;
47639 }
47640
47641 if(!nonRT) {
47642 nonRT = true;
47643 /* Decode once for all nonRT ReaderGroups */
47644 if(rg->config.encodingMimeType == UA_PUBSUB_ENCODING_UADP) {
47645 size_t currentPosition = 0;
47646 res = decodeNetworkMessage(server, buffer: &msg, pos: &currentPosition, nm: &nm, connection: psc);
47647 } else { /* if(writerGroup->config.encodingMimeType == UA_PUBSUB_ENCODING_JSON) */
47648#ifdef UA_ENABLE_JSON_ENCODING
47649 res = UA_NetworkMessage_decodeJson(dst: &nm, src: &msg);
47650#else
47651 res = UA_STATUSCODE_BADNOTSUPPORTED;
47652#endif
47653 }
47654 if(res != UA_STATUSCODE_GOOD) {
47655 UA_LOG_WARNING_CONNECTION(server->config.logging, psc,
47656 "Verify, decrypt and decode network message failed");
47657 nonRT = false;
47658 }
47659 }
47660 }
47661
47662 /* Process the received message for the non-RT ReaderGroups */
47663 if(nonRT) {
47664 LIST_FOREACH(rg, &psc->readerGroups, listEntry) {
47665 if(rg->state != UA_PUBSUBSTATE_OPERATIONAL &&
47666 rg->state != UA_PUBSUBSTATE_PREOPERATIONAL)
47667 continue;
47668 if(rg->config.rtLevel & UA_PUBSUB_RT_FIXED_SIZE)
47669 continue;
47670 processed |= UA_ReaderGroup_process(server, readerGroup: rg, nm: &nm);
47671 }
47672 UA_NetworkMessage_clear(p: &nm);
47673 }
47674
47675 if(!processed) {
47676 UA_DateTime nowM = UA_DateTime_nowMonotonic();
47677 if(psc->silenceErrorUntil < nowM) {
47678 UA_LOG_WARNING_CONNECTION(server->config.logging, psc,
47679 "Message received that could not be processed. "
47680 "Check PublisherID, WriterGroupID and DatasetWriterID. "
47681 "(This error is now silenced for 10s.)");
47682 psc->silenceErrorUntil = nowM + (UA_DateTime)(10.0 * UA_DATETIME_SEC);
47683 }
47684 }
47685
47686 unlockServer(server);
47687}
47688
47689static void
47690PubSubRecvChannelCallback(UA_ConnectionManager *cm, uintptr_t connectionId,
47691 void *application, void **connectionContext,
47692 UA_ConnectionState state, const UA_KeyValueMap *params,
47693 UA_ByteString msg) {
47694 PubSubChannelCallback(cm, connectionId, application, connectionContext,
47695 state, params, msg, true);
47696}
47697
47698static void
47699PubSubSendChannelCallback(UA_ConnectionManager *cm, uintptr_t connectionId,
47700 void *application, void **connectionContext,
47701 UA_ConnectionState state, const UA_KeyValueMap *params,
47702 UA_ByteString msg) {
47703 PubSubChannelCallback(cm, connectionId, application, connectionContext,
47704 state, params, msg, false);
47705}
47706
47707static UA_StatusCode
47708UA_PubSubConnection_connectUDP(UA_Server *server, UA_PubSubConnection *c,
47709 UA_Boolean validate) {
47710 UA_LOCK_ASSERT(&server->serviceMutex, 1);
47711
47712 UA_NetworkAddressUrlDataType *addressUrl = (UA_NetworkAddressUrlDataType*)
47713 c->config.address.data;
47714
47715 /* Extract hostname and port */
47716 UA_String address;
47717 UA_UInt16 port;
47718 UA_StatusCode res = UA_parseEndpointUrl(endpointUrl: &addressUrl->url, outHostname: &address, outPort: &port, NULL);
47719 if(res != UA_STATUSCODE_GOOD) {
47720 UA_LOG_ERROR_CONNECTION(server->config.logging, c,
47721 "Could not parse the UDP network URL");
47722 return res;
47723 }
47724
47725 /* Detect a wildcard address for unicast receiving. The individual
47726 * DataSetWriters then contain additional target hostnames for sending.
47727 *
47728 * "localhost" and the empty hostname are used as a special "receive all"
47729 * wildcard for PubSub UDP. All other addresses (also the 127.0.0/8 and ::1
47730 * range) are handled differently. For them we only receive messages that
47731 * originate from these addresses.
47732 *
47733 * The EventLoop backend detects whether an address is multicast capable and
47734 * registers it for the multicast group in the background. */
47735 UA_String localhostAddr = UA_STRING_STATIC("localhost");
47736 UA_Boolean receive_all =
47737 (address.length == 0) || UA_String_equal(p1: &localhostAddr, p2: &address);
47738
47739 /* Set up the connection parameters */
47740 UA_Boolean listen = true;
47741 UA_Boolean reuse = true;
47742 UA_Boolean loopback = true;
47743 UA_KeyValuePair kvp[7];
47744 UA_KeyValueMap kvm = {5, kvp};
47745 kvp[0].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "port");
47746 UA_Variant_setScalar(v: &kvp[0].value, p: &port, type: &UA_TYPES[UA_TYPES_UINT16]);
47747 kvp[1].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "listen");
47748 UA_Variant_setScalar(v: &kvp[1].value, p: &listen, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
47749 kvp[2].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "validate");
47750 UA_Variant_setScalar(v: &kvp[2].value, p: &validate, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
47751 kvp[3].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "reuse");
47752 UA_Variant_setScalar(v: &kvp[3].value, p: &reuse, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
47753 kvp[4].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "loopback");
47754 UA_Variant_setScalar(v: &kvp[4].value, p: &loopback, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
47755 if(!receive_all) {
47756 /* The "receive all" wildcard is different in the eventloop UDP layer.
47757 * Omit the address entirely to receive all.*/
47758 kvp[5].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "address");
47759 UA_Variant_setScalar(v: &kvp[5].value, p: &address, type: &UA_TYPES[UA_TYPES_STRING]);
47760 kvm.mapSize++;
47761 }
47762 if(!UA_String_isEmpty(s: &addressUrl->networkInterface)) {
47763 kvp[kvm.mapSize].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "interface");
47764 UA_Variant_setScalar(v: &kvp[kvm.mapSize].value, p: &addressUrl->networkInterface,
47765 type: &UA_TYPES[UA_TYPES_STRING]);
47766 kvm.mapSize++;
47767 }
47768
47769 /* Open a recv connection */
47770 if(c->recvChannelsSize == 0) {
47771 /* Validate only if no ReaderGroup configured */
47772 validate = (c->readerGroupsSize == 0);
47773 if(validate) {
47774 UA_LOG_INFO_CONNECTION(server->config.logging, c,
47775 "No ReaderGroups configured. "
47776 "Only validate the connection parameters "
47777 "instead of opening a receiving channel.");
47778 }
47779
47780 res = c->cm->openConnection(c->cm, &kvm, server, c, PubSubRecvChannelCallback);
47781 if(res != UA_STATUSCODE_GOOD) {
47782 UA_LOG_ERROR_CONNECTION(server->config.logging, c,
47783 "Could not open an UDP channel for receiving");
47784 return res;
47785 }
47786 }
47787
47788 /* Receive all -- sending is handled in the DataSetWriter */
47789 if(receive_all) {
47790 UA_LOG_INFO_CONNECTION(server->config.logging, c,
47791 "Localhost address - don't open UDP send connection");
47792 return UA_STATUSCODE_GOOD;
47793 }
47794
47795 /* Open a send connection */
47796 if(c->sendChannel == 0) {
47797 /* Validate only if no WriterGroup configured */
47798 validate = (c->writerGroupsSize == 0);
47799 if(validate) {
47800 UA_LOG_INFO_CONNECTION(server->config.logging, c,
47801 "No WriterGroups configured. "
47802 "Only validate the connection parameters "
47803 "instead of opening a channel for sending.");
47804 }
47805
47806 listen = false;
47807 res = c->cm->openConnection(c->cm, &kvm, server, c, PubSubSendChannelCallback);
47808 if(res != UA_STATUSCODE_GOOD) {
47809 UA_LOG_ERROR_CONNECTION(server->config.logging, c,
47810 "Could not open an UDP recv channel");
47811 return res;
47812 }
47813 }
47814
47815 return UA_STATUSCODE_GOOD;
47816}
47817
47818static UA_StatusCode
47819UA_PubSubConnection_connectETH(UA_Server *server, UA_PubSubConnection *c,
47820 UA_Boolean validate) {
47821 UA_LOCK_ASSERT(&server->serviceMutex, 1);
47822
47823 UA_NetworkAddressUrlDataType *addressUrl = (UA_NetworkAddressUrlDataType*)
47824 c->config.address.data;
47825
47826 /* Extract hostname and port */
47827 UA_String address;
47828 UA_String vidPCP = UA_STRING_NULL;
47829 UA_StatusCode res = UA_parseEndpointUrl(endpointUrl: &addressUrl->url, outHostname: &address, NULL, outPath: &vidPCP);
47830 if(res != UA_STATUSCODE_GOOD) {
47831 UA_LOG_ERROR_CONNECTION(server->config.logging, c,
47832 "Could not parse the ETH network URL");
47833 return res;
47834 }
47835
47836 /* Set up the connection parameters.
47837 * TDOD: Complete the considered parameters. VID, PCP, etc. */
47838 UA_Boolean listen = true;
47839 UA_KeyValuePair kvp[4];
47840 UA_KeyValueMap kvm = {4, kvp};
47841 kvp[0].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "address");
47842 UA_Variant_setScalar(v: &kvp[0].value, p: &address, type: &UA_TYPES[UA_TYPES_STRING]);
47843 kvp[1].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "listen");
47844 UA_Variant_setScalar(v: &kvp[1].value, p: &listen, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
47845 kvp[2].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "interface");
47846 UA_Variant_setScalar(v: &kvp[2].value, p: &addressUrl->networkInterface,
47847 type: &UA_TYPES[UA_TYPES_STRING]);
47848 kvp[3].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "validate");
47849 UA_Variant_setScalar(v: &kvp[3].value, p: &validate, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
47850
47851 /* Open recv channels */
47852 if(c->recvChannelsSize == 0) {
47853 res = c->cm->openConnection(c->cm, &kvm, server, c, PubSubRecvChannelCallback);
47854 if(res != UA_STATUSCODE_GOOD) {
47855 UA_LOG_ERROR_CONNECTION(server->config.logging, c,
47856 "Could not open an ETH recv channel");
47857 return res;
47858 }
47859 }
47860
47861 /* Open send channels */
47862 if(c->sendChannel == 0) {
47863 listen = false;
47864 res = c->cm->openConnection(c->cm, &kvm, server, c, PubSubSendChannelCallback);
47865 if(res != UA_STATUSCODE_GOOD) {
47866 UA_LOG_ERROR_CONNECTION(server->config.logging, c,
47867 "Could not open an ETH channel for sending");
47868 }
47869 }
47870
47871 return res;
47872}
47873
47874static UA_Boolean
47875UA_PubSubConnection_isConnected(UA_PubSubConnection *c) {
47876 if(c->sendChannel == 0 && c->writerGroupsSize > 0)
47877 return false;
47878 if(c->recvChannelsSize == 0 && c->readerGroupsSize > 0)
47879 return false;
47880 return true;
47881}
47882
47883UA_StatusCode
47884UA_PubSubConnection_connect(UA_Server *server, UA_PubSubConnection *c,
47885 UA_Boolean validate) {
47886 UA_LOCK_ASSERT(&server->serviceMutex, 1);
47887
47888 /* Already connected -> success */
47889 if(UA_PubSubConnection_isConnected(c) && !validate)
47890 return UA_STATUSCODE_GOOD;
47891
47892 UA_EventLoop *el = UA_PubSubConnection_getEL(server, c);
47893 if(!el) {
47894 UA_LOG_ERROR_CONNECTION(server->config.logging, c, "No EventLoop configured");
47895 UA_PubSubConnection_setPubSubState(server, connection: c, state: UA_PUBSUBSTATE_ERROR,
47896 UA_STATUSCODE_BADINTERNALERROR);
47897 return UA_STATUSCODE_BADINTERNALERROR;;
47898 }
47899
47900 /* Look up the connection manager for the connection */
47901 ProfileMapping *profile = getProfile(profileUri: c->config.transportProfileUri);
47902 UA_ConnectionManager *cm = NULL;
47903 if(profile)
47904 cm = getCM(el, protocol: profile->protocol);
47905 if(!cm || (c->cm && cm != c->cm)) {
47906 UA_LOG_ERROR_CONNECTION(server->config.logging, c,
47907 "The requested protocol is not supported");
47908 UA_PubSubConnection_setPubSubState(server, connection: c, state: UA_PUBSUBSTATE_ERROR,
47909 UA_STATUSCODE_BADINTERNALERROR);
47910 return UA_STATUSCODE_BADINTERNALERROR;
47911 }
47912
47913 c->cm = cm;
47914 c->json = profile->json;
47915
47916 /* Check the configuration address type */
47917 if(!UA_Variant_hasScalarType(v: &c->config.address,
47918 type: &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE])) {
47919 UA_LOG_ERROR_CONNECTION(server->config.logging, c, "No NetworkAddressUrlDataType "
47920 "for the address configuration");
47921 return UA_STATUSCODE_BADINTERNALERROR;
47922 }
47923
47924 /* Connect */
47925 UA_StatusCode res = UA_STATUSCODE_GOOD;
47926 if(profile->connect)
47927 res = profile->connect(server, c, validate);
47928 if(res != UA_STATUSCODE_GOOD && !validate)
47929 UA_PubSubConnection_setPubSubState(server, connection: c, state: UA_PUBSUBSTATE_ERROR, cause: res);
47930 return res;
47931}
47932
47933/***************/
47934/* WriterGroup */
47935/***************/
47936
47937static void
47938WriterGroupChannelCallback(UA_ConnectionManager *cm, uintptr_t connectionId,
47939 void *application, void **connectionContext,
47940 UA_ConnectionState state, const UA_KeyValueMap *params,
47941 UA_ByteString msg) {
47942 if(!connectionContext)
47943 return;
47944
47945 /* Get the context pointers */
47946 UA_Server *server = (UA_Server*)application;
47947 UA_WriterGroup *wg = (UA_WriterGroup*)*connectionContext;
47948
47949 lockServer(server);
47950
47951 /* The connection is closing in the EventLoop. This is the last callback
47952 * from that connection. Clean up the SecureChannel in the client. */
47953 if(state == UA_CONNECTIONSTATE_CLOSING) {
47954 if(wg->sendChannel == connectionId) {
47955 /* Reset the connection channel */
47956 wg->sendChannel = 0;
47957
47958 /* PSC marked for deletion and the last EventLoop connection has closed */
47959 if(wg->deleteFlag) {
47960 UA_WriterGroup_remove(server, wg);
47961 unlockServer(server);
47962 return;
47963 }
47964 }
47965
47966 /* Reconnect automatically if the connection was operational. This sets
47967 * the connection state if connecting fails. Attention! If there are
47968 * several send or recv channels, then the connection is only reopened if
47969 * all of them close - which is usually the case. */
47970 if(wg->state == UA_PUBSUBSTATE_OPERATIONAL)
47971 UA_WriterGroup_connect(server, wg, false);
47972
47973 unlockServer(server);
47974 return;
47975 }
47976
47977 /* Store the connectionId (if a new connection) */
47978 if(wg->sendChannel && wg->sendChannel != connectionId) {
47979 UA_LOG_WARNING_WRITERGROUP(server->config.logging, wg,
47980 "WriterGroup is already bound to a different channel");
47981 unlockServer(server);
47982 return;
47983 }
47984 wg->sendChannel = connectionId;
47985
47986 /* Connection open, set to operational if not already done */
47987 if(wg->state != UA_PUBSUBSTATE_OPERATIONAL)
47988 UA_WriterGroup_setPubSubState(server, writerGroup: wg, state: UA_PUBSUBSTATE_OPERATIONAL,
47989 UA_STATUSCODE_GOOD);
47990
47991 /* Send-channels don't receive messages */
47992 unlockServer(server);
47993}
47994
47995static UA_StatusCode
47996UA_WriterGroup_connectUDPUnicast(UA_Server *server, UA_WriterGroup *wg,
47997 UA_Boolean validate) {
47998 UA_LOCK_ASSERT(&server->serviceMutex, 1);
47999
48000 /* Already connected? */
48001 if(wg->sendChannel != 0 && !validate)
48002 return UA_STATUSCODE_GOOD;
48003
48004 /* Check if address is available in TransportSettings */
48005 if(((wg->config.transportSettings.encoding == UA_EXTENSIONOBJECT_DECODED ||
48006 wg->config.transportSettings.encoding == UA_EXTENSIONOBJECT_DECODED_NODELETE) &&
48007 wg->config.transportSettings.content.decoded.type ==
48008 &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORTDATATYPE]))
48009 return UA_STATUSCODE_GOOD;
48010
48011 /* Unpack the TransportSettings */
48012 if((wg->config.transportSettings.encoding != UA_EXTENSIONOBJECT_DECODED &&
48013 wg->config.transportSettings.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) ||
48014 wg->config.transportSettings.content.decoded.type !=
48015 &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE]) {
48016 UA_LOG_ERROR_WRITERGROUP(server->config.logging, wg,
48017 "Invalid TransportSettings for a UDP Connection");
48018 return UA_STATUSCODE_BADINTERNALERROR;
48019 }
48020 UA_DatagramWriterGroupTransport2DataType *ts =
48021 (UA_DatagramWriterGroupTransport2DataType*)
48022 wg->config.transportSettings.content.decoded.data;
48023
48024 /* Unpack the address */
48025 if((ts->address.encoding != UA_EXTENSIONOBJECT_DECODED &&
48026 ts->address.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) ||
48027 ts->address.content.decoded.type != &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]) {
48028 UA_LOG_ERROR_WRITERGROUP(server->config.logging, wg,
48029 "Invalid TransportSettings Address for a UDP Connection");
48030 return UA_STATUSCODE_BADINTERNALERROR;
48031 }
48032 UA_NetworkAddressUrlDataType *addressUrl = (UA_NetworkAddressUrlDataType *)
48033 ts->address.content.decoded.data;
48034
48035 /* Extract hostname and port */
48036 UA_String address;
48037 UA_UInt16 port;
48038 UA_StatusCode res = UA_parseEndpointUrl(endpointUrl: &addressUrl->url, outHostname: &address, outPort: &port, NULL);
48039 if(res != UA_STATUSCODE_GOOD) {
48040 UA_LOG_ERROR_WRITERGROUP(server->config.logging, wg,
48041 "Could not parse the UDP network URL");
48042 return res;
48043 }
48044
48045 /* Set up the connection parameters */
48046 UA_Boolean listen = false;
48047 UA_KeyValuePair kvp[5];
48048 UA_KeyValueMap kvm = {4, kvp};
48049 kvp[0].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "address");
48050 UA_Variant_setScalar(v: &kvp[0].value, p: &address, type: &UA_TYPES[UA_TYPES_STRING]);
48051 kvp[1].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "port");
48052 UA_Variant_setScalar(v: &kvp[1].value, p: &port, type: &UA_TYPES[UA_TYPES_UINT16]);
48053 kvp[2].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "listen");
48054 UA_Variant_setScalar(v: &kvp[2].value, p: &listen, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
48055 kvp[3].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "validate");
48056 UA_Variant_setScalar(v: &kvp[3].value, p: &validate, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
48057 if(!UA_String_isEmpty(s: &addressUrl->networkInterface)) {
48058 kvp[4].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "interface");
48059 UA_Variant_setScalar(v: &kvp[4].value, p: &addressUrl->networkInterface,
48060 type: &UA_TYPES[UA_TYPES_STRING]);
48061 kvm.mapSize++;
48062 }
48063
48064 /* Connect */
48065 UA_ConnectionManager *cm = wg->linkedConnection->cm;
48066 res = cm->openConnection(cm, &kvm, server, wg, WriterGroupChannelCallback);
48067 if(res != UA_STATUSCODE_GOOD) {
48068 UA_LOG_ERROR_WRITERGROUP(server->config.logging, wg,
48069 "Could not open a UDP send channel");
48070 }
48071 return res;
48072}
48073
48074static UA_StatusCode
48075UA_WriterGroup_connectMQTT(UA_Server *server, UA_WriterGroup *wg,
48076 UA_Boolean validate) {
48077 UA_LOCK_ASSERT(&server->serviceMutex, 1);
48078
48079 UA_PubSubConnection *c = wg->linkedConnection;
48080 UA_NetworkAddressUrlDataType *addressUrl = (UA_NetworkAddressUrlDataType*)
48081 c->config.address.data;
48082
48083 /* Get the TransportSettings */
48084 UA_ExtensionObject *ts = &wg->config.transportSettings;
48085 if((ts->encoding != UA_EXTENSIONOBJECT_DECODED &&
48086 ts->encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) ||
48087 ts->content.decoded.type !=
48088 &UA_TYPES[UA_TYPES_BROKERWRITERGROUPTRANSPORTDATATYPE]) {
48089 UA_LOG_ERROR_WRITERGROUP(server->config.logging, wg,
48090 "Wrong TransportSettings type for MQTT");
48091 return UA_STATUSCODE_BADINTERNALERROR;
48092 }
48093 UA_BrokerWriterGroupTransportDataType *transportSettings =
48094 (UA_BrokerWriterGroupTransportDataType*)ts->content.decoded.data;
48095
48096 /* Extract hostname and port */
48097 UA_String address;
48098 UA_UInt16 port = 1883; /* Default */
48099 UA_StatusCode res = UA_parseEndpointUrl(endpointUrl: &addressUrl->url, outHostname: &address, outPort: &port, NULL);
48100 if(res != UA_STATUSCODE_GOOD) {
48101 UA_LOG_ERROR_CONNECTION(server->config.logging, c,
48102 "Could not parse the MQTT network URL");
48103 return res;
48104 }
48105
48106 /* Set up the connection parameters.
48107 * TODO: Complete the MQTT parameters. */
48108 UA_Boolean listen = false;
48109 UA_KeyValuePair kvp[5];
48110 UA_KeyValueMap kvm = {5, kvp};
48111 kvp[0].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "address");
48112 UA_Variant_setScalar(v: &kvp[0].value, p: &address, type: &UA_TYPES[UA_TYPES_STRING]);
48113 kvp[1].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "subscribe");
48114 UA_Variant_setScalar(v: &kvp[1].value, p: &listen, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
48115 kvp[2].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "port");
48116 UA_Variant_setScalar(v: &kvp[2].value, p: &port, type: &UA_TYPES[UA_TYPES_UINT16]);
48117 kvp[3].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "topic");
48118 UA_Variant_setScalar(v: &kvp[3].value, p: &transportSettings->queueName,
48119 type: &UA_TYPES[UA_TYPES_STRING]);
48120 kvp[4].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "validate");
48121 UA_Variant_setScalar(v: &kvp[4].value, p: &validate, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
48122
48123 /* Connect */
48124 res = c->cm->openConnection(c->cm, &kvm, server, wg, WriterGroupChannelCallback);
48125 if(res != UA_STATUSCODE_GOOD) {
48126 UA_LOG_ERROR_WRITERGROUP(server->config.logging, wg,
48127 "Could not open the MQTT connection");
48128 }
48129 return res;
48130}
48131
48132void
48133UA_WriterGroup_disconnect(UA_WriterGroup *wg) {
48134 if(wg->sendChannel == 0)
48135 return;
48136 UA_PubSubConnection *c = wg->linkedConnection;
48137 if(!c || !c->cm)
48138 return;
48139 c->cm->closeConnection(c->cm, wg->sendChannel);
48140}
48141
48142UA_StatusCode
48143UA_WriterGroup_connect(UA_Server *server, UA_WriterGroup *wg, UA_Boolean validate) {
48144 UA_LOCK_ASSERT(&server->serviceMutex, 1);
48145
48146 /* Already connected */
48147 if(wg->sendChannel != 0 && !validate)
48148 return UA_STATUSCODE_GOOD;
48149
48150 /* Is this a WriterGroup with custom TransportSettings beyond the
48151 * PubSubConnection? */
48152 if(wg->config.transportSettings.encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY)
48153 return UA_STATUSCODE_GOOD;
48154
48155 UA_EventLoop *el = UA_PubSubConnection_getEL(server, c: wg->linkedConnection);
48156 if(!el) {
48157 UA_LOG_ERROR_WRITERGROUP(server->config.logging, wg, "No EventLoop configured");
48158 UA_WriterGroup_setPubSubState(server, writerGroup: wg, state: UA_PUBSUBSTATE_ERROR,
48159 UA_STATUSCODE_BADINTERNALERROR);
48160 return UA_STATUSCODE_BADINTERNALERROR;;
48161 }
48162
48163 UA_PubSubConnection *c = wg->linkedConnection;
48164 if(!c)
48165 return UA_STATUSCODE_BADINTERNALERROR;
48166
48167 /* Look up the connection manager for the connection */
48168 ProfileMapping *profile = getProfile(profileUri: c->config.transportProfileUri);
48169 UA_ConnectionManager *cm = NULL;
48170 if(profile)
48171 cm = getCM(el, protocol: profile->protocol);
48172 if(!cm || (c->cm && cm != c->cm)) {
48173 UA_LOG_ERROR_CONNECTION(server->config.logging, c,
48174 "The requested protocol is not supported");
48175 UA_PubSubConnection_setPubSubState(server, connection: c, state: UA_PUBSUBSTATE_ERROR,
48176 UA_STATUSCODE_BADINTERNALERROR);
48177 return UA_STATUSCODE_BADINTERNALERROR;
48178 }
48179
48180 c->cm = cm;
48181 c->json = profile->json;
48182
48183 /* Connect */
48184 UA_StatusCode res = UA_STATUSCODE_GOOD;
48185 if(profile->connectWriterGroup)
48186 res = profile->connectWriterGroup(server, wg, validate);
48187 if(res != UA_STATUSCODE_GOOD && !validate) {
48188 UA_WriterGroup_setPubSubState(server, writerGroup: wg, state: UA_PUBSUBSTATE_ERROR, cause: res);
48189 return res;
48190 }
48191
48192 /* Set to preoperational. Set the state "manually" to avoid recursion. Also
48193 * this is the only place to set pre-operational for PubSubConnections. The
48194 * state will be set to operational in the network callback when the
48195 * connection has fully opened. */
48196 if(wg->state != UA_PUBSUBSTATE_OPERATIONAL && !validate)
48197 wg->state = UA_PUBSUBSTATE_PREOPERATIONAL;
48198
48199 return UA_STATUSCODE_GOOD;
48200}
48201
48202/***************/
48203/* ReaderGroup */
48204/***************/
48205
48206static void
48207UA_ReaderGroup_removeConnection(UA_ReaderGroup *rg,
48208 uintptr_t connectionId) {
48209 for(size_t i = 0; i < UA_PUBSUB_MAXCHANNELS; i++) {
48210 if(rg->recvChannels[i] != connectionId)
48211 continue;
48212 rg->recvChannels[i] = 0;
48213 rg->recvChannelsSize--;
48214 return;
48215 }
48216}
48217
48218static UA_StatusCode
48219UA_ReaderGroup_addRecvConnection(UA_ReaderGroup*c,
48220 uintptr_t connectionId) {
48221 for(size_t i = 0; i < UA_PUBSUB_MAXCHANNELS; i++) {
48222 if(c->recvChannels[i] == connectionId)
48223 return UA_STATUSCODE_GOOD;
48224 }
48225 if(c->recvChannelsSize >= UA_PUBSUB_MAXCHANNELS)
48226 return UA_STATUSCODE_BADINTERNALERROR;
48227 for(size_t i = 0; i < UA_PUBSUB_MAXCHANNELS; i++) {
48228 if(c->recvChannels[i] != 0)
48229 continue;
48230 c->recvChannels[i] = connectionId;
48231 c->recvChannelsSize++;
48232 break;
48233 }
48234 return UA_STATUSCODE_GOOD;
48235}
48236
48237static void
48238ReaderGroupChannelCallback(UA_ConnectionManager *cm, uintptr_t connectionId,
48239 void *application, void **connectionContext,
48240 UA_ConnectionState state, const UA_KeyValueMap *params,
48241 UA_ByteString msg) {
48242 if(!connectionContext)
48243 return;
48244
48245 /* Get the context pointers */
48246 UA_Server *server = (UA_Server*)application;
48247 UA_ReaderGroup *rg = (UA_ReaderGroup*)*connectionContext;
48248
48249 lockServer(server);
48250
48251 /* The connection is closing in the EventLoop. This is the last callback
48252 * from that connection. Clean up the SecureChannel in the client. */
48253 if(state == UA_CONNECTIONSTATE_CLOSING) {
48254 /* Reset the connection identifiers */
48255 UA_ReaderGroup_removeConnection(rg, connectionId);
48256
48257 /* PSC marked for deletion and the last EventLoop connection has closed */
48258 if(rg->deleteFlag && rg->recvChannelsSize == 0) {
48259 UA_ReaderGroup_remove(server, rg);
48260 unlockServer(server);
48261 return;
48262 }
48263
48264 /* Reconnect if still operational */
48265 UA_ReaderGroup_setPubSubState(server, readerGroup: rg, state: rg->state, UA_STATUSCODE_GOOD);
48266 unlockServer(server);
48267 return;
48268 }
48269
48270 /* Store the connectionId (if a new connection) */
48271 UA_StatusCode res = UA_ReaderGroup_addRecvConnection(c: rg, connectionId);
48272 if(res != UA_STATUSCODE_GOOD) {
48273 UA_LOG_WARNING_READERGROUP(server->config.logging, rg,
48274 "No more space for an additional EventLoop connection");
48275 UA_PubSubConnection *c = rg->linkedConnection;
48276 if(c && c->cm)
48277 c->cm->closeConnection(c->cm, connectionId);
48278 unlockServer(server);
48279 return;
48280 }
48281
48282 /* No message received */
48283 if(msg.length == 0) {
48284 unlockServer(server);
48285 return;
48286 }
48287
48288 /* Received the first message - set to operational */
48289 if(rg->state == UA_PUBSUBSTATE_PREOPERATIONAL) {
48290 rg->state = UA_PUBSUBSTATE_OPERATIONAL;
48291 UA_ServerConfig *config = &server->config;
48292 if(config->pubSubConfig.stateChangeCallback != 0) {
48293 config->pubSubConfig.stateChangeCallback(server, &rg->identifier,
48294 rg->state, UA_STATUSCODE_GOOD);
48295 }
48296 }
48297
48298 if(rg->state != UA_PUBSUBSTATE_OPERATIONAL) {
48299 UA_LOG_WARNING_READERGROUP(server->config.logging, rg,
48300 "Received a messaage for a non-operational ReaderGroup");
48301 unlockServer(server);
48302 return;
48303 }
48304
48305 /* ReaderGroup with realtime processing */
48306 if(rg->config.rtLevel & UA_PUBSUB_RT_FIXED_SIZE) {
48307 UA_ReaderGroup_decodeAndProcessRT(server, readerGroup: rg, buf: &msg);
48308 unlockServer(server);
48309 return;
48310 }
48311
48312 /* Decode message */
48313 UA_NetworkMessage nm;
48314 memset(s: &nm, c: 0, n: sizeof(UA_NetworkMessage));
48315 if(rg->config.encodingMimeType == UA_PUBSUB_ENCODING_UADP) {
48316 size_t currentPosition = 0;
48317 res = decodeNetworkMessage(server, buffer: &msg, pos: &currentPosition,
48318 nm: &nm, connection: rg->linkedConnection);
48319 } else { /* if(writerGroup->config.encodingMimeType == UA_PUBSUB_ENCODING_JSON) */
48320#ifdef UA_ENABLE_JSON_ENCODING
48321 res = UA_NetworkMessage_decodeJson(dst: &nm, src: &msg);
48322#else
48323 res = UA_STATUSCODE_BADNOTSUPPORTED;
48324#endif
48325 }
48326 if(res != UA_STATUSCODE_GOOD) {
48327 UA_LOG_WARNING_READERGROUP(server->config.logging, rg,
48328 "Verify, decrypt and decode network message failed");
48329 unlockServer(server);
48330 return;
48331 }
48332
48333 /* Process the decoded message */
48334 UA_ReaderGroup_process(server, readerGroup: rg, nm: &nm);
48335 UA_NetworkMessage_clear(p: &nm);
48336 unlockServer(server);
48337}
48338
48339static UA_StatusCode
48340UA_ReaderGroup_connectMQTT(UA_Server *server, UA_ReaderGroup *rg,
48341 UA_Boolean validate) {
48342 UA_LOCK_ASSERT(&server->serviceMutex, 1);
48343
48344 UA_PubSubConnection *c = rg->linkedConnection;
48345 UA_NetworkAddressUrlDataType *addressUrl = (UA_NetworkAddressUrlDataType*)
48346 c->config.address.data;
48347
48348 /* Get the TransportSettings */
48349 UA_ExtensionObject *ts = &rg->config.transportSettings;
48350 if((ts->encoding != UA_EXTENSIONOBJECT_DECODED &&
48351 ts->encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) ||
48352 ts->content.decoded.type !=
48353 &UA_TYPES[UA_TYPES_BROKERDATASETREADERTRANSPORTDATATYPE]) {
48354 UA_LOG_ERROR_READERGROUP(server->config.logging, rg,
48355 "Wrong TransportSettings type for MQTT");
48356 return UA_STATUSCODE_BADINTERNALERROR;
48357 }
48358 UA_BrokerDataSetReaderTransportDataType *transportSettings =
48359 (UA_BrokerDataSetReaderTransportDataType*)ts->content.decoded.data;
48360
48361 /* Extract hostname and port */
48362 UA_String address;
48363 UA_UInt16 port = 1883; /* Default */
48364 UA_StatusCode res = UA_parseEndpointUrl(endpointUrl: &addressUrl->url, outHostname: &address, outPort: &port, NULL);
48365 if(res != UA_STATUSCODE_GOOD) {
48366 UA_LOG_ERROR_CONNECTION(server->config.logging, c,
48367 "Could not parse the MQTT network URL");
48368 return res;
48369 }
48370
48371 /* Set up the connection parameters.
48372 * TODO: Complete the MQTT parameters. */
48373 UA_Boolean listen = true;
48374 UA_KeyValuePair kvp[5];
48375 UA_KeyValueMap kvm = {5, kvp};
48376 kvp[0].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "address");
48377 UA_Variant_setScalar(v: &kvp[0].value, p: &address, type: &UA_TYPES[UA_TYPES_STRING]);
48378 kvp[1].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "subscribe");
48379 UA_Variant_setScalar(v: &kvp[1].value, p: &listen, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
48380 kvp[2].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "port");
48381 UA_Variant_setScalar(v: &kvp[2].value, p: &port, type: &UA_TYPES[UA_TYPES_UINT16]);
48382 kvp[3].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "topic");
48383 UA_Variant_setScalar(v: &kvp[3].value, p: &transportSettings->queueName,
48384 type: &UA_TYPES[UA_TYPES_STRING]);
48385 kvp[4].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "validate");
48386 UA_Variant_setScalar(v: &kvp[4].value, p: &validate, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
48387
48388 /* Connect */
48389 res = c->cm->openConnection(c->cm, &kvm, server, rg, ReaderGroupChannelCallback);
48390 if(res != UA_STATUSCODE_GOOD) {
48391 UA_LOG_ERROR_READERGROUP(server->config.logging, rg,
48392 "Could not open the MQTT connection");
48393 }
48394 return res;
48395}
48396
48397void
48398UA_ReaderGroup_disconnect(UA_ReaderGroup *rg) {
48399 UA_PubSubConnection *c = rg->linkedConnection;
48400 if(!c)
48401 return;
48402 for(size_t i = 0; i < UA_PUBSUB_MAXCHANNELS; i++) {
48403 if(rg->recvChannels[i] != 0)
48404 c->cm->closeConnection(c->cm, rg->recvChannels[i]);
48405 }
48406}
48407
48408UA_StatusCode
48409UA_ReaderGroup_connect(UA_Server *server, UA_ReaderGroup *rg, UA_Boolean validate) {
48410 UA_LOCK_ASSERT(&server->serviceMutex, 1);
48411
48412 /* Already connected */
48413 if(rg->recvChannelsSize != 0 && !validate)
48414 return UA_STATUSCODE_GOOD;
48415
48416 /* Is this a ReaderGroup with custom TransportSettings beyond the
48417 * PubSubConnection? */
48418 if(rg->config.transportSettings.encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY)
48419 return UA_STATUSCODE_GOOD;
48420
48421 UA_EventLoop *el = UA_PubSubConnection_getEL(server, c: rg->linkedConnection);
48422 if(!el) {
48423 UA_LOG_ERROR_READERGROUP(server->config.logging, rg, "No EventLoop configured");
48424 UA_ReaderGroup_setPubSubState(server, readerGroup: rg, state: UA_PUBSUBSTATE_ERROR,
48425 UA_STATUSCODE_BADINTERNALERROR);
48426 return UA_STATUSCODE_BADINTERNALERROR;;
48427 }
48428
48429 UA_PubSubConnection *c = rg->linkedConnection;
48430 if(!c)
48431 return UA_STATUSCODE_BADINTERNALERROR;
48432
48433 /* Look up the connection manager for the connection */
48434 ProfileMapping *profile = getProfile(profileUri: c->config.transportProfileUri);
48435 UA_ConnectionManager *cm = NULL;
48436 if(profile)
48437 cm = getCM(el, protocol: profile->protocol);
48438 if(!cm || (c->cm && cm != c->cm)) {
48439 UA_LOG_ERROR_CONNECTION(server->config.logging, c,
48440 "The requested protocol is not supported");
48441 UA_PubSubConnection_setPubSubState(server, connection: c, state: UA_PUBSUBSTATE_ERROR,
48442 UA_STATUSCODE_BADINTERNALERROR);
48443 return UA_STATUSCODE_BADINTERNALERROR;
48444 }
48445
48446 c->cm = cm;
48447 c->json = profile->json;
48448
48449 /* Connect */
48450 UA_StatusCode res = UA_STATUSCODE_GOOD;
48451 if(profile->connectReaderGroup)
48452 res = profile->connectReaderGroup(server, rg, validate);
48453 if(res != UA_STATUSCODE_GOOD && !validate) {
48454 UA_ReaderGroup_setPubSubState(server, readerGroup: rg, state: UA_PUBSUBSTATE_ERROR, cause: res);
48455 return res;
48456 }
48457
48458 return UA_STATUSCODE_GOOD;
48459}
48460
48461#endif /* UA_ENABLE_PUBSUB */
48462
48463/**** amalgamated original file "/src/pubsub/ua_pubsub_connection.c" ****/
48464
48465/* This Source Code Form is subject to the terms of the Mozilla Public
48466 * License, v. 2.0. If a copy of the MPL was not distributed with this
48467 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
48468 *
48469 * Copyright (c) 2017-2022 Fraunhofer IOSB (Author: Andreas Ebner)
48470 * Copyright (c) 2019, 2022 Fraunhofer IOSB (Author: Julius Pfrommer)
48471 * Copyright (c) 2019 Kalycito Infotech Private Limited
48472 * Copyright (c) 2021 Fraunhofer IOSB (Author: Jan Hermes)
48473 * Copyright (c) 2022 Siemens AG (Author: Thomas Fischer)
48474 * Copyright (c) 2022 Fraunhofer IOSB (Author: Noel Graf)
48475 */
48476
48477
48478#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
48479#endif
48480
48481#ifdef UA_ENABLE_PUBSUB /* conditional compilation */
48482
48483UA_StatusCode
48484decodeNetworkMessage(UA_Server *server, UA_ByteString *buffer, size_t *pos,
48485 UA_NetworkMessage *nm, UA_PubSubConnection *connection) {
48486#ifdef UA_DEBUG_DUMP_PKGS
48487 UA_dump_hex_pkg(buffer->data, buffer->length);
48488#endif
48489
48490 UA_StatusCode rv = UA_NetworkMessage_decodeHeaders(src: buffer, offset: pos, dst: nm);
48491 if(rv != UA_STATUSCODE_GOOD) {
48492 UA_LOG_WARNING_CONNECTION(server->config.logging, connection,
48493 "PubSub receive. decoding headers failed");
48494 UA_NetworkMessage_clear(p: nm);
48495 return rv;
48496 }
48497
48498#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
48499 UA_Boolean processed = false;
48500 UA_ReaderGroup *readerGroup;
48501 UA_DataSetReader *reader;
48502
48503 /* Choose a correct readergroup for decrypt/verify this message
48504 * (there could be multiple) */
48505 LIST_FOREACH(readerGroup, &connection->readerGroups, listEntry) {
48506 LIST_FOREACH(reader, &readerGroup->readers, listEntry) {
48507 UA_StatusCode retval =
48508 UA_DataSetReader_checkIdentifier(server, nm, reader, readerGroup->config);
48509 if(retval != UA_STATUSCODE_GOOD)
48510 continue;
48511 processed = true;
48512 rv = verifyAndDecryptNetworkMessage(server->config.logging, buffer, pos,
48513 nm, readerGroup);
48514 if(rv != UA_STATUSCODE_GOOD) {
48515 UA_LOG_WARNING_CONNECTION(server->config.logging, connection,
48516 "Subscribe failed, verify and decrypt "
48517 "network message failed.");
48518 UA_NetworkMessage_clear(nm);
48519 return rv;
48520 }
48521
48522 /* break out of all loops when first verify & decrypt was successful */
48523 goto loops_exit;
48524 }
48525 }
48526
48527loops_exit:
48528 if(!processed) {
48529 UA_DateTime nowM = UA_DateTime_nowMonotonic();
48530 if(connection->silenceErrorUntil < nowM) {
48531 UA_LOG_INFO_CONNECTION(server->config.logging, connection,
48532 "Dataset reader not found. Check PublisherId, "
48533 "WriterGroupId and DatasetWriterId. "
48534 "(This error is now silenced for 10s.)");
48535 connection->silenceErrorUntil = nowM + (UA_DateTime)(10.0 * UA_DATETIME_SEC);
48536 }
48537 /* Possible multicast scenario: there are multiple connections (with one
48538 * or more ReaderGroups) within a multicast group every connection
48539 * receives all network messages, even if some of them are not meant for
48540 * the connection currently processed -> therefore it is ok if the
48541 * connection does not have a DataSetReader for every received network
48542 * message. We must not return an error here, but continue with the
48543 * buffer decoding and see if we have a matching DataSetReader for the
48544 * next network message. */
48545 }
48546#endif
48547
48548 rv = UA_NetworkMessage_decodePayload(src: buffer, offset: pos, dst: nm, customTypes: server->config.customDataTypes, NULL);
48549 if(rv != UA_STATUSCODE_GOOD) {
48550 UA_NetworkMessage_clear(p: nm);
48551 return rv;
48552 }
48553
48554 rv = UA_NetworkMessage_decodeFooters(src: buffer, offset: pos, dst: nm);
48555 if(rv != UA_STATUSCODE_GOOD) {
48556 UA_NetworkMessage_clear(p: nm);
48557 return rv;
48558 }
48559
48560 return UA_STATUSCODE_GOOD;
48561}
48562
48563UA_StatusCode
48564UA_PubSubConnectionConfig_copy(const UA_PubSubConnectionConfig *src,
48565 UA_PubSubConnectionConfig *dst) {
48566 UA_StatusCode res = UA_STATUSCODE_GOOD;
48567 memcpy(dest: dst, src: src, n: sizeof(UA_PubSubConnectionConfig));
48568 if(src->publisherIdType == UA_PUBLISHERIDTYPE_STRING) {
48569 res |= UA_String_copy(src: &src->publisherId.string, dst: &dst->publisherId.string);
48570 }
48571 res |= UA_String_copy(src: &src->name, dst: &dst->name);
48572 res |= UA_Variant_copy(src: &src->address, dst: &dst->address);
48573 res |= UA_String_copy(src: &src->transportProfileUri, dst: &dst->transportProfileUri);
48574 res |= UA_Variant_copy(src: &src->connectionTransportSettings,
48575 dst: &dst->connectionTransportSettings);
48576 res |= UA_KeyValueMap_copy(src: &src->connectionProperties,
48577 dst: &dst->connectionProperties);
48578 if(res != UA_STATUSCODE_GOOD)
48579 UA_PubSubConnectionConfig_clear(connectionConfig: dst);
48580 return res;
48581}
48582
48583UA_StatusCode
48584UA_Server_getPubSubConnectionConfig(UA_Server *server, const UA_NodeId connection,
48585 UA_PubSubConnectionConfig *config) {
48586 if(!config)
48587 return UA_STATUSCODE_BADINVALIDARGUMENT;
48588 lockServer(server);
48589 UA_PubSubConnection *currentPubSubConnection =
48590 UA_PubSubConnection_findConnectionbyId(server, connectionIdentifier: connection);
48591 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
48592 if(currentPubSubConnection)
48593 res = UA_PubSubConnectionConfig_copy(src: &currentPubSubConnection->config, dst: config);
48594 unlockServer(server);
48595 return res;
48596}
48597
48598UA_PubSubConnection *
48599UA_PubSubConnection_findConnectionbyId(UA_Server *server, UA_NodeId connectionIdentifier) {
48600 UA_PubSubConnection *pubSubConnection;
48601 TAILQ_FOREACH(pubSubConnection, &server->pubSubManager.connections, listEntry){
48602 if(UA_NodeId_equal(p1: &connectionIdentifier, p2: &pubSubConnection->identifier))
48603 break;
48604 }
48605 return pubSubConnection;
48606}
48607
48608void
48609UA_PubSubConnectionConfig_clear(UA_PubSubConnectionConfig *connectionConfig) {
48610 if(connectionConfig->publisherIdType == UA_PUBLISHERIDTYPE_STRING)
48611 UA_String_clear(p: &connectionConfig->publisherId.string);
48612 UA_String_clear(p: &connectionConfig->name);
48613 UA_String_clear(p: &connectionConfig->transportProfileUri);
48614 UA_Variant_clear(p: &connectionConfig->connectionTransportSettings);
48615 UA_Variant_clear(p: &connectionConfig->address);
48616 UA_KeyValueMap_clear(map: &connectionConfig->connectionProperties);
48617}
48618
48619UA_StatusCode
48620UA_PubSubConnection_create(UA_Server *server, const UA_PubSubConnectionConfig *cc,
48621 UA_NodeId *cId) {
48622 /* Validate preconditions */
48623 UA_CHECK_MEM(server, return UA_STATUSCODE_BADINTERNALERROR);
48624 UA_CHECK_ERROR(cc != NULL, return UA_STATUSCODE_BADINTERNALERROR,
48625 server->config.logging, UA_LOGCATEGORY_SERVER,
48626 "PubSub Connection creation failed. Missing connection configuration.");
48627
48628 /* Allocate */
48629 UA_PubSubConnection *c = (UA_PubSubConnection *)
48630 UA_calloc(nmemb: 1, size: sizeof(UA_PubSubConnection));
48631 if(!c) {
48632 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
48633 msg: "PubSub Connection creation failed. Out of Memory.");
48634 return UA_STATUSCODE_BADOUTOFMEMORY;
48635 }
48636 c->componentType = UA_PUBSUB_COMPONENT_CONNECTION;
48637
48638 /* Copy the connection config */
48639 UA_StatusCode ret = UA_PubSubConnectionConfig_copy(src: cc, dst: &c->config);
48640 UA_CHECK_STATUS(ret, UA_free(c); return ret);
48641
48642 /* Assign the connection identifier */
48643#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
48644 /* Internally create a unique id */
48645 addPubSubConnectionRepresentation(server, connection: c);
48646#else
48647 /* Create a unique NodeId that does not correspond to a Node */
48648 UA_PubSubManager_generateUniqueNodeId(&server->pubSubManager,
48649 &c->identifier);
48650#endif
48651
48652 /* Register */
48653 UA_PubSubManager *pubSubManager = &server->pubSubManager;
48654 TAILQ_INSERT_HEAD(&pubSubManager->connections, c, listEntry);
48655 pubSubManager->connectionsSize++;
48656
48657 /* Validate-connect to check the parameters */
48658 ret = UA_PubSubConnection_connect(server, c, true);
48659 if(ret != UA_STATUSCODE_GOOD)
48660 goto cleanup;
48661
48662 /* Make the connection operational */
48663 ret = UA_PubSubConnection_setPubSubState(server, connection: c, state: UA_PUBSUBSTATE_OPERATIONAL,
48664 UA_STATUSCODE_GOOD);
48665 if(ret != UA_STATUSCODE_GOOD)
48666 goto cleanup;
48667
48668 /* Copy the created NodeId to the output. Cannot fail as we create a
48669 * numerical NodeId. */
48670 if(cId)
48671 UA_NodeId_copy(src: &c->identifier, dst: cId);
48672
48673 cleanup:
48674 if(ret != UA_STATUSCODE_GOOD)
48675 UA_PubSubConnection_delete(server, c);
48676 return ret;
48677}
48678
48679UA_StatusCode
48680UA_Server_addPubSubConnection(UA_Server *server, const UA_PubSubConnectionConfig *cc,
48681 UA_NodeId *cId) {
48682 lockServer(server);
48683 UA_StatusCode res = UA_PubSubConnection_create(server, cc, cId);
48684 unlockServer(server);
48685 return res;
48686}
48687
48688static void
48689delayedPubSubConnection_delete(void *application, void *context) {
48690 UA_Server *server = (UA_Server*)application;
48691 UA_PubSubConnection *c = (UA_PubSubConnection*)context;
48692 lockServer(server);
48693 UA_PubSubConnection_delete(server, c);
48694 unlockServer(server);
48695}
48696
48697/* Clean up the PubSubConnection. If no EventLoop connection is attached we can
48698 * immediately free. Otherwise we close the EventLoop connections and free in
48699 * the connection callback. */
48700void
48701UA_PubSubConnection_delete(UA_Server *server, UA_PubSubConnection *c) {
48702 UA_LOCK_ASSERT(&server->serviceMutex, 1);
48703
48704 /* Disable (and disconnect) and set the deleteFlag. This prevents a
48705 * reconnect and triggers the deletion when the last open socket is
48706 * closed. */
48707 c->deleteFlag = true;
48708 UA_PubSubConnection_setPubSubState(server, connection: c, state: UA_PUBSUBSTATE_DISABLED, UA_STATUSCODE_GOOD);
48709
48710 /* Stop and unfreeze all ReaderGroupds and WriterGroups attached to the
48711 * Connection. Do this before removing them because we need to unfreeze all
48712 * to remove the Connection.*/
48713 UA_ReaderGroup *readerGroup, *tmpReaderGroup;
48714 LIST_FOREACH(readerGroup, &c->readerGroups, listEntry) {
48715 UA_ReaderGroup_setPubSubState(server, readerGroup, state: UA_PUBSUBSTATE_DISABLED,
48716 UA_STATUSCODE_BADSHUTDOWN);
48717 UA_ReaderGroup_unfreezeConfiguration(server, rg: readerGroup);
48718 }
48719
48720 UA_WriterGroup *writerGroup, *tmpWriterGroup;
48721 LIST_FOREACH(writerGroup, &c->writerGroups, listEntry) {
48722 UA_WriterGroup_setPubSubState(server, writerGroup, state: UA_PUBSUBSTATE_DISABLED,
48723 UA_STATUSCODE_BADSHUTDOWN);
48724 UA_WriterGroup_unfreezeConfiguration(server, wg: writerGroup);
48725 }
48726
48727 /* Remove all ReaderGorups and WriterGroups */
48728 LIST_FOREACH_SAFE(readerGroup, &c->readerGroups, listEntry, tmpReaderGroup) {
48729 UA_ReaderGroup_remove(server, rg: readerGroup);
48730 }
48731
48732 LIST_FOREACH_SAFE(writerGroup, &c->writerGroups, listEntry, tmpWriterGroup) {
48733 UA_WriterGroup_remove(server, wg: writerGroup);
48734 }
48735
48736 /* Not all sockets are closed. This method will be called again */
48737 if(c->sendChannel != 0 || c->recvChannelsSize > 0)
48738 return;
48739
48740 /* The WriterGroups / ReaderGroups are not deleted. Try again in the next
48741 * iteration of the event loop.*/
48742 if(!LIST_EMPTY(&c->writerGroups) || !LIST_EMPTY(&c->readerGroups)) {
48743 UA_EventLoop *el = UA_PubSubConnection_getEL(server, c);
48744 c->dc.callback = delayedPubSubConnection_delete;
48745 c->dc.application = server;
48746 c->dc.context = c;
48747 el->addDelayedCallback(el, &c->dc);
48748 return;
48749 }
48750
48751 /* Remove from the information model */
48752#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
48753 deleteNode(server, nodeId: c->identifier, true);
48754#endif
48755
48756 /* Unlink from the server */
48757 TAILQ_REMOVE(&server->pubSubManager.connections, c, listEntry);
48758 server->pubSubManager.connectionsSize--;
48759
48760 UA_PubSubConnectionConfig_clear(connectionConfig: &c->config);
48761 UA_NodeId_clear(p: &c->identifier);
48762 UA_free(ptr: c);
48763}
48764
48765UA_StatusCode
48766UA_Server_removePubSubConnection(UA_Server *server, const UA_NodeId connection) {
48767 lockServer(server);
48768 UA_PubSubConnection *psc =
48769 UA_PubSubConnection_findConnectionbyId(server, connectionIdentifier: connection);
48770 if(!psc) {
48771 unlockServer(server);
48772 return UA_STATUSCODE_BADNOTFOUND;
48773 }
48774 UA_PubSubConnection_delete(server, c: psc);
48775 unlockServer(server);
48776 return UA_STATUSCODE_GOOD;
48777}
48778
48779UA_StatusCode
48780UA_PubSubConnection_setPubSubState(UA_Server *server, UA_PubSubConnection *c,
48781 UA_PubSubState state, UA_StatusCode cause) {
48782 UA_LOCK_ASSERT(&server->serviceMutex, 1);
48783
48784 if(c->deleteFlag && state != UA_PUBSUBSTATE_DISABLED) {
48785 UA_LOG_WARNING_CONNECTION(server->config.logging, c,
48786 "The connection is being deleted. Can only be disabled.");
48787 return UA_STATUSCODE_BADINTERNALERROR;
48788 }
48789
48790 UA_StatusCode ret = UA_STATUSCODE_GOOD;
48791 UA_PubSubState oldState = c->state;
48792 UA_WriterGroup *writerGroup;
48793 UA_ReaderGroup *readerGroup;
48794
48795 switch(state) {
48796 case UA_PUBSUBSTATE_ERROR:
48797 case UA_PUBSUBSTATE_PAUSED:
48798 case UA_PUBSUBSTATE_DISABLED:
48799 if(state == oldState)
48800 break;
48801
48802 /* Close the EventLoop connection */
48803 c->state = state;
48804 UA_PubSubConnection_disconnect(c);
48805
48806 /* Disable Reader and WriterGroups */
48807 LIST_FOREACH(readerGroup, &c->readerGroups, listEntry) {
48808 UA_ReaderGroup_setPubSubState(server, readerGroup, state,
48809 UA_STATUSCODE_BADRESOURCEUNAVAILABLE);
48810 }
48811 LIST_FOREACH(writerGroup, &c->writerGroups, listEntry) {
48812 UA_WriterGroup_setPubSubState(server, writerGroup, state,
48813 UA_STATUSCODE_BADRESOURCEUNAVAILABLE);
48814 }
48815 break;
48816
48817 case UA_PUBSUBSTATE_PREOPERATIONAL:
48818 case UA_PUBSUBSTATE_OPERATIONAL:
48819 /* Called also if the connection is already operational. We might to
48820 * open an additional recv connection, etc. Sets the new state
48821 * internally. */
48822 if(oldState != UA_PUBSUBSTATE_OPERATIONAL)
48823 c->state = UA_PUBSUBSTATE_PREOPERATIONAL;
48824 ret = UA_PubSubConnection_connect(server, c, false);
48825 if(ret != UA_STATUSCODE_GOOD)
48826 UA_PubSubConnection_setPubSubState(server, c,
48827 state: UA_PUBSUBSTATE_ERROR, cause: ret);
48828 break;
48829 default:
48830 UA_LOG_WARNING_CONNECTION(server->config.logging, c,
48831 "Received unknown PubSub state!");
48832 return UA_STATUSCODE_BADINTERNALERROR;
48833 }
48834
48835 /* Inform application about state change */
48836 if(c->state != oldState) {
48837 UA_ServerConfig *config = &server->config;
48838 if(config->pubSubConfig.stateChangeCallback)
48839 config->pubSubConfig.stateChangeCallback(server, &c->identifier, state, cause);
48840 }
48841 return ret;
48842}
48843
48844UA_EventLoop *
48845UA_PubSubConnection_getEL(UA_Server *server, UA_PubSubConnection *c) {
48846 if(c->config.eventLoop)
48847 return c->config.eventLoop;
48848 return server->config.eventLoop;
48849}
48850
48851#endif /* UA_ENABLE_PUBSUB */
48852
48853/**** amalgamated original file "/src/pubsub/ua_pubsub_dataset.c" ****/
48854
48855/* This Source Code Form is subject to the terms of the Mozilla Public
48856 * License, v. 2.0. If a copy of the MPL was not distributed with this
48857 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
48858 *
48859 * Copyright (c) 2017-2019 Fraunhofer IOSB (Author: Andreas Ebner)
48860 * Copyright (c) 2019 Fraunhofer IOSB (Author: Julius Pfrommer)
48861 * Copyright (c) 2019-2021 Kalycito Infotech Private Limited
48862 * Copyright (c) 2020 Yannick Wallerer, Siemens AG
48863 * Copyright (c) 2020 Thomas Fischer, Siemens AG
48864 * Copyright (c) 2021 Fraunhofer IOSB (Author: Jan Hermes)
48865 */
48866
48867
48868#ifdef UA_ENABLE_PUBSUB /* conditional compilation */
48869
48870static void
48871UA_DataSetField_clear(UA_DataSetField *field) {
48872 UA_DataSetFieldConfig_clear(dataSetFieldConfig: &field->config);
48873 UA_NodeId_clear(p: &field->identifier);
48874 UA_NodeId_clear(p: &field->publishedDataSet);
48875 UA_FieldMetaData_clear(p: &field->fieldMetaData);
48876}
48877
48878UA_StatusCode
48879UA_PublishedDataSetConfig_copy(const UA_PublishedDataSetConfig *src,
48880 UA_PublishedDataSetConfig *dst) {
48881 UA_StatusCode res = UA_STATUSCODE_GOOD;
48882 memcpy(dest: dst, src: src, n: sizeof(UA_PublishedDataSetConfig));
48883 res |= UA_String_copy(src: &src->name, dst: &dst->name);
48884 switch(src->publishedDataSetType) {
48885 case UA_PUBSUB_DATASET_PUBLISHEDITEMS:
48886 //no additional items
48887 break;
48888
48889 case UA_PUBSUB_DATASET_PUBLISHEDITEMS_TEMPLATE:
48890 if(src->config.itemsTemplate.variablesToAddSize > 0) {
48891 dst->config.itemsTemplate.variablesToAdd = (UA_PublishedVariableDataType *)
48892 UA_calloc(nmemb: src->config.itemsTemplate.variablesToAddSize,
48893 size: sizeof(UA_PublishedVariableDataType));
48894 if(!dst->config.itemsTemplate.variablesToAdd) {
48895 res = UA_STATUSCODE_BADOUTOFMEMORY;
48896 break;
48897 }
48898 dst->config.itemsTemplate.variablesToAddSize =
48899 src->config.itemsTemplate.variablesToAddSize;
48900 }
48901
48902 for(size_t i = 0; i < src->config.itemsTemplate.variablesToAddSize; i++) {
48903 res |= UA_PublishedVariableDataType_copy(src: &src->config.itemsTemplate.variablesToAdd[i],
48904 dst: &dst->config.itemsTemplate.variablesToAdd[i]);
48905 }
48906 res |= UA_DataSetMetaDataType_copy(src: &src->config.itemsTemplate.metaData,
48907 dst: &dst->config.itemsTemplate.metaData);
48908 break;
48909
48910 default:
48911 res = UA_STATUSCODE_BADINVALIDARGUMENT;
48912 break;
48913 }
48914
48915 if(res != UA_STATUSCODE_GOOD)
48916 UA_PublishedDataSetConfig_clear(pdsConfig: dst);
48917 return res;
48918}
48919
48920UA_StatusCode
48921getPublishedDataSetConfig(UA_Server *server, const UA_NodeId pds,
48922 UA_PublishedDataSetConfig *config) {
48923 if(!config)
48924 return UA_STATUSCODE_BADINVALIDARGUMENT;
48925 UA_PublishedDataSet *currentPDS = UA_PublishedDataSet_findPDSbyId(server, identifier: pds);
48926 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
48927 if(currentPDS)
48928 res = UA_PublishedDataSetConfig_copy(src: &currentPDS->config, dst: config);
48929 return res;
48930}
48931
48932UA_StatusCode
48933UA_Server_getPublishedDataSetConfig(UA_Server *server, const UA_NodeId pds,
48934 UA_PublishedDataSetConfig *config) {
48935 lockServer(server);
48936 UA_StatusCode res = getPublishedDataSetConfig(server, pds, config);
48937 unlockServer(server);
48938 return res;
48939}
48940
48941UA_StatusCode
48942UA_Server_getPublishedDataSetMetaData(UA_Server *server, const UA_NodeId pds,
48943 UA_DataSetMetaDataType *metaData) {
48944 if(!metaData)
48945 return UA_STATUSCODE_BADINVALIDARGUMENT;
48946 lockServer(server);
48947 UA_PublishedDataSet *currentPDS = UA_PublishedDataSet_findPDSbyId(server, identifier: pds);
48948 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
48949 if(currentPDS)
48950 res = UA_DataSetMetaDataType_copy(src: &currentPDS->dataSetMetaData, dst: metaData);
48951 unlockServer(server);
48952 return res;
48953}
48954
48955UA_PublishedDataSet *
48956UA_PublishedDataSet_findPDSbyId(UA_Server *server, UA_NodeId identifier) {
48957 UA_PublishedDataSet *tmpPDS = NULL;
48958 TAILQ_FOREACH(tmpPDS, &server->pubSubManager.publishedDataSets, listEntry) {
48959 if(UA_NodeId_equal(p1: &tmpPDS->identifier, p2: &identifier))
48960 break;
48961 }
48962 return tmpPDS;
48963}
48964
48965UA_PublishedDataSet *
48966UA_PublishedDataSet_findPDSbyName(UA_Server *server, UA_String name) {
48967 UA_PublishedDataSet *tmpPDS = NULL;
48968 TAILQ_FOREACH(tmpPDS, &server->pubSubManager.publishedDataSets, listEntry) {
48969 if(UA_String_equal(p1: &name, p2: &tmpPDS->config.name))
48970 break;
48971 }
48972
48973 return tmpPDS;
48974}
48975
48976void
48977UA_PublishedDataSetConfig_clear(UA_PublishedDataSetConfig *pdsConfig) {
48978 //delete pds config
48979 UA_String_clear(p: &pdsConfig->name);
48980 switch (pdsConfig->publishedDataSetType){
48981 case UA_PUBSUB_DATASET_PUBLISHEDITEMS:
48982 //no additional items
48983 break;
48984 case UA_PUBSUB_DATASET_PUBLISHEDITEMS_TEMPLATE:
48985 if(pdsConfig->config.itemsTemplate.variablesToAddSize > 0){
48986 for(size_t i = 0; i < pdsConfig->config.itemsTemplate.variablesToAddSize; i++){
48987 UA_PublishedVariableDataType_clear(p: &pdsConfig->config.itemsTemplate.variablesToAdd[i]);
48988 }
48989 UA_free(ptr: pdsConfig->config.itemsTemplate.variablesToAdd);
48990 }
48991 UA_DataSetMetaDataType_clear(p: &pdsConfig->config.itemsTemplate.metaData);
48992 break;
48993 default:
48994 break;
48995 }
48996}
48997
48998void
48999UA_PublishedDataSet_clear(UA_Server *server, UA_PublishedDataSet *publishedDataSet) {
49000 UA_DataSetField *field, *tmpField;
49001 TAILQ_FOREACH_SAFE(field, &publishedDataSet->fields, listEntry, tmpField) {
49002 /* Code in this block is a duplication of similar code in UA_DataSetField_remove, but
49003 * this is intentional. We don't want to call UA_DataSetField_remove here as that
49004 * function regenerates DataSetMetaData, which is not necessary if we want to
49005 * clear the whole PDS anyway. */
49006 if(field->configurationFrozen) {
49007 UA_LOG_WARNING_DATASET(server->config.logging, publishedDataSet,
49008 "Clearing a frozen field.");
49009 }
49010 field->fieldMetaData.arrayDimensions = NULL;
49011 field->fieldMetaData.properties = NULL;
49012 field->fieldMetaData.name = UA_STRING_NULL;
49013 field->fieldMetaData.description.locale = UA_STRING_NULL;
49014 field->fieldMetaData.description.text = UA_STRING_NULL;
49015 UA_DataSetField_clear(field);
49016 TAILQ_REMOVE(&publishedDataSet->fields, field, listEntry);
49017 UA_free(ptr: field);
49018 }
49019 UA_PublishedDataSetConfig_clear(pdsConfig: &publishedDataSet->config);
49020 UA_DataSetMetaDataType_clear(p: &publishedDataSet->dataSetMetaData);
49021 UA_NodeId_clear(p: &publishedDataSet->identifier);
49022}
49023
49024/* The fieldMetaData variable has to be cleaned up external in case of an error */
49025static UA_StatusCode
49026generateFieldMetaData(UA_Server *server, UA_PublishedDataSet *pds,
49027 UA_DataSetField *field, UA_FieldMetaData *fieldMetaData) {
49028 if(field->config.dataSetFieldType != UA_PUBSUB_DATASETFIELD_VARIABLE)
49029 return UA_STATUSCODE_BADNOTSUPPORTED;
49030
49031 /* Set the field identifier */
49032 fieldMetaData->dataSetFieldId = UA_PubSubManager_generateUniqueGuid(server);
49033
49034 /* Set the description */
49035 fieldMetaData->description = UA_LOCALIZEDTEXT_ALLOC(locale: "", text: "");
49036
49037 /* Set the name */
49038 const UA_DataSetVariableConfig *var = &field->config.field.variable;
49039 UA_StatusCode res = UA_String_copy(src: &var->fieldNameAlias, dst: &fieldMetaData->name);
49040 UA_CHECK_STATUS(res, return res);
49041
49042 /* Static value source. ToDo after freeze PR, the value source must be
49043 * checked (other behavior for static value source) */
49044 if(var->rtValueSource.rtFieldSourceEnabled &&
49045 !var->rtValueSource.rtInformationModelNode) {
49046 const UA_DataValue *svs = *var->rtValueSource.staticValueSource;
49047 if(svs->value.arrayDimensionsSize > 0) {
49048 fieldMetaData->arrayDimensions = (UA_UInt32 *)
49049 UA_calloc(nmemb: svs->value.arrayDimensionsSize, size: sizeof(UA_UInt32));
49050 if(fieldMetaData->arrayDimensions == NULL)
49051 return UA_STATUSCODE_BADOUTOFMEMORY;
49052 memcpy(dest: fieldMetaData->arrayDimensions, src: svs->value.arrayDimensions,
49053 n: sizeof(UA_UInt32) * svs->value.arrayDimensionsSize);
49054 }
49055 fieldMetaData->arrayDimensionsSize = svs->value.arrayDimensionsSize;
49056
49057 if(svs->value.type)
49058 res = UA_NodeId_copy(src: &svs->value.type->typeId, dst: &fieldMetaData->dataType);
49059 UA_CHECK_STATUS(res, return res);
49060
49061 //TODO collect value rank for the static field source
49062 fieldMetaData->properties = NULL;
49063 fieldMetaData->propertiesSize = 0;
49064 fieldMetaData->fieldFlags = UA_DATASETFIELDFLAGS_NONE;
49065 return UA_STATUSCODE_GOOD;
49066 }
49067
49068 /* Set the Array Dimensions */
49069 const UA_PublishedVariableDataType *pp = &var->publishParameters;
49070 UA_Variant value;
49071 UA_Variant_init(p: &value);
49072 res = readWithReadValue(server, nodeId: &pp->publishedVariable,
49073 attributeId: UA_ATTRIBUTEID_ARRAYDIMENSIONS, v: &value);
49074 if(res != UA_STATUSCODE_GOOD) {
49075 UA_LOG_WARNING_DATASET(server->config.logging, pds,
49076 "PubSub meta data generation: Reading the array dimensions failed");
49077 return res;
49078 }
49079
49080 if(value.arrayDimensionsSize > 0) {
49081 fieldMetaData->arrayDimensions = (UA_UInt32 *)
49082 UA_calloc(nmemb: value.arrayDimensionsSize, size: sizeof(UA_UInt32));
49083 if(!fieldMetaData->arrayDimensions)
49084 return UA_STATUSCODE_BADOUTOFMEMORY;
49085 memcpy(dest: fieldMetaData->arrayDimensions, src: value.arrayDimensions,
49086 n: sizeof(UA_UInt32)*value.arrayDimensionsSize);
49087 }
49088 fieldMetaData->arrayDimensionsSize = value.arrayDimensionsSize;
49089
49090 UA_Variant_clear(p: &value);
49091
49092 /* Set the DataType */
49093 res = readWithReadValue(server, nodeId: &pp->publishedVariable,
49094 attributeId: UA_ATTRIBUTEID_DATATYPE, v: &fieldMetaData->dataType);
49095 if(res != UA_STATUSCODE_GOOD) {
49096 UA_LOG_WARNING_DATASET(server->config.logging, pds,
49097 "PubSub meta data generation: Reading the datatype failed");
49098 return res;
49099 }
49100
49101 if(!UA_NodeId_isNull(p: &fieldMetaData->dataType)) {
49102 const UA_DataType *currentDataType =
49103 UA_findDataTypeWithCustom(typeId: &fieldMetaData->dataType,
49104 customTypes: server->config.customDataTypes);
49105#ifdef UA_ENABLE_TYPEDESCRIPTION
49106 UA_LOG_DEBUG_DATASET(server->config.logging, pds,
49107 "MetaData creation: Found DataType %s",
49108 currentDataType->typeName);
49109#endif
49110 /* Check if the datatype is a builtInType, if yes set the builtinType. */
49111 if(currentDataType->typeKind <= UA_DATATYPEKIND_ENUM)
49112 fieldMetaData->builtInType = (UA_Byte)currentDataType->typeId.identifier.numeric;
49113 /* set the maxStringLength attribute */
49114 if(field->config.field.variable.maxStringLength != 0){
49115 if(currentDataType->typeKind == UA_DATATYPEKIND_BYTESTRING ||
49116 currentDataType->typeKind == UA_DATATYPEKIND_STRING ||
49117 currentDataType->typeKind == UA_DATATYPEKIND_LOCALIZEDTEXT) {
49118 fieldMetaData->maxStringLength = field->config.field.variable.maxStringLength;
49119 } else {
49120 UA_LOG_WARNING_DATASET(server->config.logging, pds,
49121 "PubSub meta data generation: MaxStringLength with incompatible DataType configured.");
49122 }
49123 }
49124 } else {
49125 UA_LOG_WARNING_DATASET(server->config.logging, pds,
49126 "PubSub meta data generation: DataType is UA_NODEID_NULL");
49127 }
49128
49129 /* Set the ValueRank */
49130 UA_Int32 valueRank;
49131 res = readWithReadValue(server, nodeId: &pp->publishedVariable,
49132 attributeId: UA_ATTRIBUTEID_VALUERANK, v: &valueRank);
49133 if(res != UA_STATUSCODE_GOOD) {
49134 UA_LOG_WARNING_DATASET(server->config.logging, pds,
49135 "PubSub meta data generation: Reading the value rank failed");
49136 return res;
49137 }
49138 fieldMetaData->valueRank = valueRank;
49139
49140 /* PromotedField? */
49141 if(var->promotedField)
49142 fieldMetaData->fieldFlags = UA_DATASETFIELDFLAGS_PROMOTEDFIELD;
49143 else
49144 fieldMetaData->fieldFlags = UA_DATASETFIELDFLAGS_NONE;
49145
49146 /* Properties */
49147 fieldMetaData->properties = NULL;
49148 fieldMetaData->propertiesSize = 0;
49149
49150 //TODO collect the following fields*/
49151 //fieldMetaData.builtInType
49152 //fieldMetaData.maxStringLength
49153
49154 return UA_STATUSCODE_GOOD;
49155}
49156
49157UA_DataSetFieldResult
49158UA_DataSetField_create(UA_Server *server, const UA_NodeId publishedDataSet,
49159 const UA_DataSetFieldConfig *fieldConfig,
49160 UA_NodeId *fieldIdentifier) {
49161 UA_DataSetFieldResult result;
49162 memset(s: &result, c: 0, n: sizeof(UA_DataSetFieldResult));
49163 if(!fieldConfig) {
49164 result.result = UA_STATUSCODE_BADINVALIDARGUMENT;
49165 return result;
49166 }
49167
49168 UA_PublishedDataSet *currDS =
49169 UA_PublishedDataSet_findPDSbyId(server, identifier: publishedDataSet);
49170 if(!currDS) {
49171 result.result = UA_STATUSCODE_BADNOTFOUND;
49172 return result;
49173 }
49174
49175 if(currDS->configurationFreezeCounter > 0) {
49176 UA_LOG_WARNING_DATASET(server->config.logging, currDS,
49177 "Adding DataSetField failed: PublishedDataSet is frozen");
49178 result.result = UA_STATUSCODE_BADCONFIGURATIONERROR;
49179 return result;
49180 }
49181
49182 if(currDS->config.publishedDataSetType != UA_PUBSUB_DATASET_PUBLISHEDITEMS) {
49183 result.result = UA_STATUSCODE_BADNOTIMPLEMENTED;
49184 return result;
49185 }
49186
49187 UA_DataSetField *newField = (UA_DataSetField*)UA_calloc(nmemb: 1, size: sizeof(UA_DataSetField));
49188 if(!newField) {
49189 result.result = UA_STATUSCODE_BADINTERNALERROR;
49190 return result;
49191 }
49192
49193 result.result = UA_DataSetFieldConfig_copy(src: fieldConfig, dst: &newField->config);
49194 if(result.result != UA_STATUSCODE_GOOD) {
49195 UA_free(ptr: newField);
49196 return result;
49197 }
49198
49199 result.result = UA_NodeId_copy(src: &currDS->identifier, dst: &newField->publishedDataSet);
49200 if(result.result != UA_STATUSCODE_GOOD) {
49201 UA_DataSetFieldConfig_clear(dataSetFieldConfig: &newField->config);
49202 UA_free(ptr: newField);
49203 return result;
49204 }
49205
49206 /* Initialize the field metadata. Also generates a FieldId */
49207 UA_FieldMetaData fmd;
49208 UA_FieldMetaData_init(p: &fmd);
49209 result.result = generateFieldMetaData(server, pds: currDS, field: newField, fieldMetaData: &fmd);
49210 if(result.result != UA_STATUSCODE_GOOD) {
49211 UA_FieldMetaData_clear(p: &fmd);
49212 UA_DataSetFieldConfig_clear(dataSetFieldConfig: &newField->config);
49213 UA_NodeId_clear(p: &newField->publishedDataSet);
49214 UA_free(ptr: newField);
49215 return result;
49216 }
49217
49218 /* Append to the metadata fields array. Point of last return. */
49219 result.result = UA_Array_appendCopy(p: (void**)&currDS->dataSetMetaData.fields,
49220 size: &currDS->dataSetMetaData.fieldsSize,
49221 newElem: &fmd, type: &UA_TYPES[UA_TYPES_FIELDMETADATA]);
49222 if(result.result != UA_STATUSCODE_GOOD) {
49223 UA_FieldMetaData_clear(p: &fmd);
49224 UA_DataSetFieldConfig_clear(dataSetFieldConfig: &newField->config);
49225 UA_NodeId_clear(p: &newField->publishedDataSet);
49226 UA_free(ptr: newField);
49227 return result;
49228 }
49229
49230 /* Copy the identifier from the metadata. Cannot fail with a guid NodeId. */
49231 newField->identifier = UA_NODEID_GUID(nsIndex: 1, guid: fmd.dataSetFieldId);
49232 if(fieldIdentifier)
49233 UA_NodeId_copy(src: &newField->identifier, dst: fieldIdentifier);
49234 UA_FieldMetaData_clear(p: &fmd);
49235
49236 /* Register the field. The order of DataSetFields should be the same in both
49237 * creating and publishing. So adding DataSetFields at the the end of the
49238 * DataSets using the TAILQ structure. */
49239 TAILQ_INSERT_TAIL(&currDS->fields, newField, listEntry);
49240 currDS->fieldSize++;
49241
49242 if(newField->config.field.variable.promotedField)
49243 currDS->promotedFieldsCount++;
49244
49245 /* The values of the metadata are "borrowed" in a mirrored structure in the
49246 * pds. Reset them after resizing the array. */
49247 size_t counter = 0;
49248 UA_DataSetField *dsf;
49249 TAILQ_FOREACH(dsf, &currDS->fields, listEntry) {
49250 dsf->fieldMetaData = currDS->dataSetMetaData.fields[counter++];
49251 }
49252
49253 /* Update major version of parent published data set */
49254 currDS->dataSetMetaData.configurationVersion.majorVersion =
49255 UA_PubSubConfigurationVersionTimeDifference();
49256
49257 result.configurationVersion.majorVersion =
49258 currDS->dataSetMetaData.configurationVersion.majorVersion;
49259 result.configurationVersion.minorVersion =
49260 currDS->dataSetMetaData.configurationVersion.minorVersion;
49261 return result;
49262}
49263
49264UA_DataSetFieldResult
49265UA_Server_addDataSetField(UA_Server *server, const UA_NodeId publishedDataSet,
49266 const UA_DataSetFieldConfig *fieldConfig,
49267 UA_NodeId *fieldIdentifier) {
49268 lockServer(server);
49269 UA_DataSetFieldResult res =
49270 UA_DataSetField_create(server, publishedDataSet, fieldConfig, fieldIdentifier);
49271 unlockServer(server);
49272 return res;
49273}
49274
49275UA_DataSetFieldResult
49276UA_DataSetField_remove(UA_Server *server, UA_DataSetField *currentField) {
49277 UA_DataSetFieldResult result;
49278 memset(s: &result, c: 0, n: sizeof(UA_DataSetFieldResult));
49279
49280 UA_PublishedDataSet *pds =
49281 UA_PublishedDataSet_findPDSbyId(server, identifier: currentField->publishedDataSet);
49282 if(!pds) {
49283 result.result = UA_STATUSCODE_BADNOTFOUND;
49284 return result;
49285 }
49286
49287 if(currentField->configurationFrozen) {
49288 UA_LOG_WARNING_DATASET(server->config.logging, pds,
49289 "Remove DataSetField failed: DataSetField is frozen");
49290 result.result = UA_STATUSCODE_BADCONFIGURATIONERROR;
49291 return result;
49292 }
49293
49294 if(pds->configurationFreezeCounter > 0) {
49295 UA_LOG_WARNING_DATASET(server->config.logging, pds,
49296 "Remove DataSetField failed: PublishedDataSet is frozen");
49297 result.result = UA_STATUSCODE_BADCONFIGURATIONERROR;
49298 return result;
49299 }
49300
49301 /* Reduce the counters before the config is cleaned up */
49302 if(currentField->config.field.variable.promotedField)
49303 pds->promotedFieldsCount--;
49304 pds->fieldSize--;
49305
49306 /* Update major version of PublishedDataSet */
49307 pds->dataSetMetaData.configurationVersion.majorVersion =
49308 UA_PubSubConfigurationVersionTimeDifference();
49309
49310 /* Clean up */
49311 currentField->fieldMetaData.arrayDimensions = NULL;
49312 currentField->fieldMetaData.properties = NULL;
49313 currentField->fieldMetaData.name = UA_STRING_NULL;
49314 currentField->fieldMetaData.description.locale = UA_STRING_NULL;
49315 currentField->fieldMetaData.description.text = UA_STRING_NULL;
49316 UA_DataSetField_clear(field: currentField);
49317
49318 /* Remove */
49319 TAILQ_REMOVE(&pds->fields, currentField, listEntry);
49320 UA_free(ptr: currentField);
49321
49322 /* Regenerate DataSetMetaData */
49323 pds->dataSetMetaData.fieldsSize--;
49324 if(pds->dataSetMetaData.fieldsSize > 0) {
49325 for(size_t i = 0; i < pds->dataSetMetaData.fieldsSize+1; i++) {
49326 UA_FieldMetaData_clear(p: &pds->dataSetMetaData.fields[i]);
49327 }
49328 UA_free(ptr: pds->dataSetMetaData.fields);
49329 UA_FieldMetaData *fieldMetaData = (UA_FieldMetaData *)
49330 UA_calloc(nmemb: pds->dataSetMetaData.fieldsSize, size: sizeof(UA_FieldMetaData));
49331 if(!fieldMetaData) {
49332 result.result = UA_STATUSCODE_BADOUTOFMEMORY;
49333 return result;
49334 }
49335 UA_DataSetField *tmpDSF;
49336 size_t counter = 0;
49337 TAILQ_FOREACH(tmpDSF, &pds->fields, listEntry) {
49338 result.result = generateFieldMetaData(server, pds, field: tmpDSF, fieldMetaData: &fieldMetaData[counter]);
49339 if(result.result != UA_STATUSCODE_GOOD) {
49340 UA_FieldMetaData_clear(p: &fieldMetaData[counter]);
49341 UA_LOG_WARNING_DATASET(server->config.logging, pds,
49342 "PubSub MetaData regeneration failed "
49343 "after removing a field!");
49344 break;
49345 }
49346 // The contents of the metadata is shared between the PDS and its fields.
49347 tmpDSF->fieldMetaData = fieldMetaData[counter++];
49348 }
49349 pds->dataSetMetaData.fields = fieldMetaData;
49350 } else {
49351 UA_FieldMetaData_delete(p: pds->dataSetMetaData.fields);
49352 pds->dataSetMetaData.fields = NULL;
49353 }
49354
49355 result.configurationVersion.majorVersion =
49356 pds->dataSetMetaData.configurationVersion.majorVersion;
49357 result.configurationVersion.minorVersion =
49358 pds->dataSetMetaData.configurationVersion.minorVersion;
49359 return result;
49360}
49361
49362UA_DataSetFieldResult
49363UA_Server_removeDataSetField(UA_Server *server, const UA_NodeId dsf) {
49364 lockServer(server);
49365 UA_DataSetFieldResult res;
49366 memset(s: &res, c: 0, n: sizeof(UA_DataSetFieldResult));
49367 UA_DataSetField *field = UA_DataSetField_findDSFbyId(server, identifier: dsf);
49368 if(!field) {
49369 res.result = UA_STATUSCODE_BADNOTFOUND;
49370 unlockServer(server);
49371 return res;
49372 }
49373 res = UA_DataSetField_remove(server, currentField: field);
49374 unlockServer(server);
49375 return res;
49376}
49377
49378UA_StatusCode
49379UA_DataSetFieldConfig_copy(const UA_DataSetFieldConfig *src,
49380 UA_DataSetFieldConfig *dst) {
49381 if(src->dataSetFieldType != UA_PUBSUB_DATASETFIELD_VARIABLE)
49382 return UA_STATUSCODE_BADNOTSUPPORTED;
49383 memcpy(dest: dst, src: src, n: sizeof(UA_DataSetFieldConfig));
49384 UA_StatusCode res = UA_STATUSCODE_GOOD;
49385 res |= UA_String_copy(src: &src->field.variable.fieldNameAlias,
49386 dst: &dst->field.variable.fieldNameAlias);
49387 res |= UA_PublishedVariableDataType_copy(src: &src->field.variable.publishParameters,
49388 dst: &dst->field.variable.publishParameters);
49389 if(res != UA_STATUSCODE_GOOD)
49390 UA_DataSetFieldConfig_clear(dataSetFieldConfig: dst);
49391 return res;
49392}
49393
49394UA_StatusCode
49395UA_Server_getDataSetFieldConfig(UA_Server *server, const UA_NodeId dsf,
49396 UA_DataSetFieldConfig *config) {
49397 if(!config)
49398 return UA_STATUSCODE_BADINVALIDARGUMENT;
49399 lockServer(server);
49400 UA_DataSetField *currentDataSetField = UA_DataSetField_findDSFbyId(server, identifier: dsf);
49401 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
49402 if(currentDataSetField)
49403 res = UA_DataSetFieldConfig_copy(src: &currentDataSetField->config, dst: config);
49404 unlockServer(server);
49405 return res;
49406}
49407
49408UA_DataSetField *
49409UA_DataSetField_findDSFbyId(UA_Server *server, UA_NodeId identifier) {
49410 UA_PublishedDataSet *tmpPDS;
49411 TAILQ_FOREACH(tmpPDS, &server->pubSubManager.publishedDataSets, listEntry) {
49412 UA_DataSetField *tmpField;
49413 TAILQ_FOREACH(tmpField, &tmpPDS->fields, listEntry) {
49414 if(UA_NodeId_equal(p1: &tmpField->identifier, p2: &identifier))
49415 return tmpField;
49416 }
49417 }
49418 return NULL;
49419}
49420
49421void
49422UA_DataSetFieldConfig_clear(UA_DataSetFieldConfig *dataSetFieldConfig) {
49423 if(dataSetFieldConfig->dataSetFieldType == UA_PUBSUB_DATASETFIELD_VARIABLE) {
49424 UA_String_clear(p: &dataSetFieldConfig->field.variable.fieldNameAlias);
49425 UA_PublishedVariableDataType_clear(p: &dataSetFieldConfig->field.variable.publishParameters);
49426 }
49427}
49428
49429/* Obtain the latest value for a specific DataSetField. This method is currently
49430 * called inside the DataSetMessage generation process. */
49431void
49432UA_PubSubDataSetField_sampleValue(UA_Server *server, UA_DataSetField *field,
49433 UA_DataValue *value) {
49434 UA_PublishedVariableDataType *params = &field->config.field.variable.publishParameters;
49435
49436 /* Read the value */
49437 if(field->config.field.variable.rtValueSource.rtInformationModelNode) {
49438 const UA_VariableNode *rtNode = (const UA_VariableNode *)
49439 UA_NODESTORE_GET(server, nodeId: &params->publishedVariable);
49440 *value = **rtNode->valueBackend.backend.external.value;
49441 value->value.storageType = UA_VARIANT_DATA_NODELETE;
49442 UA_NODESTORE_RELEASE(server, (const UA_Node *) rtNode);
49443 } else if(field->config.field.variable.rtValueSource.rtFieldSourceEnabled == false){
49444 UA_ReadValueId rvid;
49445 UA_ReadValueId_init(p: &rvid);
49446 rvid.nodeId = params->publishedVariable;
49447 rvid.attributeId = params->attributeId;
49448 rvid.indexRange = params->indexRange;
49449 *value = readWithSession(server, session: &server->adminSession,
49450 item: &rvid, timestampsToReturn: UA_TIMESTAMPSTORETURN_BOTH);
49451 } else {
49452 *value = **field->config.field.variable.rtValueSource.staticValueSource;
49453 value->value.storageType = UA_VARIANT_DATA_NODELETE;
49454 }
49455}
49456
49457UA_AddPublishedDataSetResult
49458UA_PublishedDataSet_create(UA_Server *server,
49459 const UA_PublishedDataSetConfig *publishedDataSetConfig,
49460 UA_NodeId *pdsIdentifier) {
49461 UA_LOCK_ASSERT(&server->serviceMutex, 1);
49462
49463 UA_AddPublishedDataSetResult result = {UA_STATUSCODE_BADINVALIDARGUMENT, 0, NULL, {0, 0}};
49464 if(!publishedDataSetConfig){
49465 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
49466 msg: "PublishedDataSet creation failed. No config passed in.");
49467 return result;
49468 }
49469
49470 if(publishedDataSetConfig->publishedDataSetType != UA_PUBSUB_DATASET_PUBLISHEDITEMS){
49471 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
49472 msg: "PublishedDataSet creation failed. Unsupported PublishedDataSet type.");
49473 return result;
49474 }
49475
49476 if(UA_String_isEmpty(s: &publishedDataSetConfig->name)) {
49477 // DataSet has to have a valid name
49478 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
49479 msg: "PublishedDataSet creation failed. Invalid name.");
49480 return result;
49481 }
49482
49483 if(UA_PublishedDataSet_findPDSbyName(server, name: publishedDataSetConfig->name)) {
49484 // DataSet name has to be unique in the publisher
49485 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
49486 msg: "PublishedDataSet creation failed. DataSet with the same name already exists.");
49487 result.addResult = UA_STATUSCODE_BADBROWSENAMEDUPLICATED;
49488 return result;
49489 }
49490
49491 /* Create new PDS and add to UA_PubSubManager */
49492 UA_PublishedDataSet *newPDS = (UA_PublishedDataSet *)
49493 UA_calloc(nmemb: 1, size: sizeof(UA_PublishedDataSet));
49494 if(!newPDS) {
49495 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
49496 msg: "PublishedDataSet creation failed. Out of Memory.");
49497 result.addResult = UA_STATUSCODE_BADOUTOFMEMORY;
49498 return result;
49499 }
49500 TAILQ_INIT(&newPDS->fields);
49501
49502 UA_PublishedDataSetConfig *newConfig = &newPDS->config;
49503
49504 /* Deep copy the given connection config */
49505 UA_StatusCode res = UA_PublishedDataSetConfig_copy(src: publishedDataSetConfig, dst: newConfig);
49506 if(res != UA_STATUSCODE_GOOD){
49507 UA_free(ptr: newPDS);
49508 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
49509 msg: "PublishedDataSet creation failed. Configuration copy failed.");
49510 result.addResult = UA_STATUSCODE_BADINTERNALERROR;
49511 return result;
49512 }
49513
49514 /* TODO: Parse template config and add fields (later PubSub batch) */
49515 if(newConfig->publishedDataSetType == UA_PUBSUB_DATASET_PUBLISHEDITEMS_TEMPLATE) {
49516 }
49517
49518 /* Fill the DataSetMetaData */
49519 result.configurationVersion.majorVersion = UA_PubSubConfigurationVersionTimeDifference();
49520 result.configurationVersion.minorVersion = UA_PubSubConfigurationVersionTimeDifference();
49521 switch(newConfig->publishedDataSetType) {
49522 case UA_PUBSUB_DATASET_PUBLISHEDEVENTS_TEMPLATE:
49523 case UA_PUBSUB_DATASET_PUBLISHEDEVENTS:
49524 res = UA_STATUSCODE_BADNOTSUPPORTED;
49525 break;
49526 case UA_PUBSUB_DATASET_PUBLISHEDITEMS:
49527 newPDS->dataSetMetaData.configurationVersion.majorVersion =
49528 UA_PubSubConfigurationVersionTimeDifference();
49529 newPDS->dataSetMetaData.configurationVersion.minorVersion =
49530 UA_PubSubConfigurationVersionTimeDifference();
49531 newPDS->dataSetMetaData.description = UA_LOCALIZEDTEXT_ALLOC(locale: "", text: "");
49532 newPDS->dataSetMetaData.dataSetClassId = UA_GUID_NULL;
49533 res = UA_String_copy(src: &newConfig->name, dst: &newPDS->dataSetMetaData.name);
49534 break;
49535 case UA_PUBSUB_DATASET_PUBLISHEDITEMS_TEMPLATE:
49536 res = UA_DataSetMetaDataType_copy(src: &newConfig->config.itemsTemplate.metaData,
49537 dst: &newPDS->dataSetMetaData);
49538 break;
49539 default:
49540 res = UA_STATUSCODE_BADINTERNALERROR;
49541 }
49542
49543 /* Abort? */
49544 result.addResult = res;
49545 if(result.addResult != UA_STATUSCODE_GOOD) {
49546 UA_PublishedDataSetConfig_clear(pdsConfig: newConfig);
49547 UA_free(ptr: newPDS);
49548 return result;
49549 }
49550
49551 /* Insert into the queue of the manager */
49552 TAILQ_INSERT_TAIL(&server->pubSubManager.publishedDataSets, newPDS, listEntry);
49553 server->pubSubManager.publishedDataSetsSize++;
49554
49555#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
49556 /* Create representation and unique id */
49557 addPublishedDataItemsRepresentation(server, publishedDataSet: newPDS);
49558#else
49559 /* Generate unique nodeId */
49560 UA_PubSubManager_generateUniqueNodeId(&server->pubSubManager, &newPDS->identifier);
49561#endif
49562 if(pdsIdentifier)
49563 UA_NodeId_copy(src: &newPDS->identifier, dst: pdsIdentifier);
49564
49565 return result;
49566}
49567
49568UA_AddPublishedDataSetResult
49569UA_Server_addPublishedDataSet(UA_Server *server,
49570 const UA_PublishedDataSetConfig *publishedDataSetConfig,
49571 UA_NodeId *pdsIdentifier) {
49572 lockServer(server);
49573 UA_AddPublishedDataSetResult res =
49574 UA_PublishedDataSet_create(server, publishedDataSetConfig, pdsIdentifier);
49575 unlockServer(server);
49576 return res;
49577}
49578
49579UA_StatusCode
49580UA_PublishedDataSet_remove(UA_Server *server, UA_PublishedDataSet *publishedDataSet) {
49581 if(publishedDataSet->configurationFreezeCounter > 0) {
49582 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
49583 msg: "Remove PublishedDataSet failed. PublishedDataSet is frozen.");
49584 return UA_STATUSCODE_BADCONFIGURATIONERROR;
49585 }
49586
49587 //search for referenced writers -> delete this writers. (Standard: writer must be connected with PDS)
49588 UA_PubSubConnection *tmpConnectoin;
49589 TAILQ_FOREACH(tmpConnectoin, &server->pubSubManager.connections, listEntry){
49590 UA_WriterGroup *writerGroup;
49591 LIST_FOREACH(writerGroup, &tmpConnectoin->writerGroups, listEntry){
49592 UA_DataSetWriter *currentWriter, *tmpWriterGroup;
49593 LIST_FOREACH_SAFE(currentWriter, &writerGroup->writers, listEntry, tmpWriterGroup){
49594 if(UA_NodeId_equal(p1: &currentWriter->connectedDataSet,
49595 p2: &publishedDataSet->identifier)) {
49596 UA_DataSetWriter_remove(server, dataSetWriter: currentWriter);
49597 }
49598 }
49599 }
49600 }
49601
49602#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
49603 deleteNode(server, nodeId: publishedDataSet->identifier, true);
49604#endif
49605
49606 UA_PublishedDataSet_clear(server, publishedDataSet);
49607 server->pubSubManager.publishedDataSetsSize--;
49608
49609 TAILQ_REMOVE(&server->pubSubManager.publishedDataSets, publishedDataSet, listEntry);
49610 UA_free(ptr: publishedDataSet);
49611 return UA_STATUSCODE_GOOD;
49612}
49613
49614UA_StatusCode
49615UA_Server_removePublishedDataSet(UA_Server *server, const UA_NodeId pds) {
49616 lockServer(server);
49617 UA_PublishedDataSet *currentPDS = UA_PublishedDataSet_findPDSbyId(server, identifier: pds);
49618 if(!currentPDS) {
49619 unlockServer(server);
49620 return UA_STATUSCODE_BADNOTFOUND;
49621 }
49622 UA_StatusCode res = UA_PublishedDataSet_remove(server, publishedDataSet: currentPDS);
49623 unlockServer(server);
49624 return res;
49625}
49626
49627
49628UA_StandaloneSubscribedDataSet *
49629UA_StandaloneSubscribedDataSet_findSDSbyId(UA_Server *server, UA_NodeId identifier) {
49630 UA_StandaloneSubscribedDataSet *subscribedDataSet;
49631 TAILQ_FOREACH(subscribedDataSet, &server->pubSubManager.subscribedDataSets,
49632 listEntry) {
49633 if(UA_NodeId_equal(p1: &identifier, p2: &subscribedDataSet->identifier))
49634 return subscribedDataSet;
49635 }
49636 return NULL;
49637}
49638
49639UA_StandaloneSubscribedDataSet *
49640UA_StandaloneSubscribedDataSet_findSDSbyName(UA_Server *server, UA_String identifier) {
49641 UA_StandaloneSubscribedDataSet *subscribedDataSet;
49642 TAILQ_FOREACH(subscribedDataSet, &server->pubSubManager.subscribedDataSets,
49643 listEntry) {
49644 if(UA_String_equal(p1: &identifier, p2: &subscribedDataSet->config.name))
49645 return subscribedDataSet;
49646 }
49647 return NULL;
49648}
49649
49650UA_StatusCode
49651UA_StandaloneSubscribedDataSetConfig_copy(const UA_StandaloneSubscribedDataSetConfig *src,
49652 UA_StandaloneSubscribedDataSetConfig *dst) {
49653 UA_StatusCode res = UA_STATUSCODE_GOOD;
49654 memcpy(dest: dst, src: src, n: sizeof(UA_StandaloneSubscribedDataSetConfig));
49655 res = UA_DataSetMetaDataType_copy(src: &src->dataSetMetaData, dst: &dst->dataSetMetaData);
49656 res |= UA_String_copy(src: &src->name, dst: &dst->name);
49657 res |= UA_Boolean_copy(src: &src->isConnected, dst: &dst->isConnected);
49658 res |= UA_TargetVariablesDataType_copy(src: &src->subscribedDataSet.target,
49659 dst: &dst->subscribedDataSet.target);
49660
49661 if(res != UA_STATUSCODE_GOOD)
49662 UA_StandaloneSubscribedDataSetConfig_clear(sdsConfig: dst);
49663 return res;
49664}
49665
49666void
49667UA_StandaloneSubscribedDataSetConfig_clear(
49668 UA_StandaloneSubscribedDataSetConfig *sdsConfig) {
49669 UA_String_clear(p: &sdsConfig->name);
49670 UA_DataSetMetaDataType_clear(p: &sdsConfig->dataSetMetaData);
49671 UA_TargetVariablesDataType_clear(p: &sdsConfig->subscribedDataSet.target);
49672}
49673
49674void
49675UA_StandaloneSubscribedDataSet_clear(UA_Server *server,
49676 UA_StandaloneSubscribedDataSet *subscribedDataSet) {
49677 UA_StandaloneSubscribedDataSetConfig_clear(sdsConfig: &subscribedDataSet->config);
49678 UA_NodeId_clear(p: &subscribedDataSet->identifier);
49679 UA_NodeId_clear(p: &subscribedDataSet->connectedReader);
49680}
49681
49682#endif /* UA_ENABLE_PUBSUB */
49683
49684/**** amalgamated original file "/src/pubsub/ua_pubsub_writer.c" ****/
49685
49686/* This Source Code Form is subject to the terms of the Mozilla Public
49687 * License, v. 2.0. If a copy of the MPL was not distributed with this
49688 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
49689 *
49690 * Copyright (c) 2017-2019 Fraunhofer IOSB (Author: Andreas Ebner)
49691 * Copyright (c) 2019 Fraunhofer IOSB (Author: Julius Pfrommer)
49692 * Copyright (c) 2019-2021 Kalycito Infotech Private Limited
49693 * Copyright (c) 2020 Yannick Wallerer, Siemens AG
49694 * Copyright (c) 2020 Thomas Fischer, Siemens AG
49695 * Copyright (c) 2021 Fraunhofer IOSB (Author: Jan Hermes)
49696 */
49697
49698
49699#ifdef UA_ENABLE_PUBSUB /* conditional compilation */
49700
49701
49702#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
49703#endif
49704
49705
49706UA_StatusCode
49707UA_DataSetWriterConfig_copy(const UA_DataSetWriterConfig *src,
49708 UA_DataSetWriterConfig *dst){
49709 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
49710 memcpy(dest: dst, src: src, n: sizeof(UA_DataSetWriterConfig));
49711 retVal |= UA_String_copy(src: &src->name, dst: &dst->name);
49712 retVal |= UA_String_copy(src: &src->dataSetName, dst: &dst->dataSetName);
49713 retVal |= UA_ExtensionObject_copy(src: &src->messageSettings, dst: &dst->messageSettings);
49714 retVal |= UA_KeyValueMap_copy(src: &src->dataSetWriterProperties, dst: &dst->dataSetWriterProperties);
49715 if(retVal != UA_STATUSCODE_GOOD)
49716 UA_DataSetWriterConfig_clear(pdsConfig: dst);
49717 return retVal;
49718}
49719
49720UA_StatusCode
49721UA_Server_getDataSetWriterConfig(UA_Server *server, const UA_NodeId dsw,
49722 UA_DataSetWriterConfig *config) {
49723 if(!config)
49724 return UA_STATUSCODE_BADINVALIDARGUMENT;
49725 lockServer(server);
49726 UA_DataSetWriter *currentDataSetWriter = UA_DataSetWriter_findDSWbyId(server, identifier: dsw);
49727 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
49728 if(currentDataSetWriter)
49729 res = UA_DataSetWriterConfig_copy(src: &currentDataSetWriter->config, dst: config);
49730 unlockServer(server);
49731 return res;
49732}
49733
49734UA_StatusCode
49735UA_Server_DataSetWriter_getState(UA_Server *server, UA_NodeId dataSetWriterIdentifier,
49736 UA_PubSubState *state) {
49737 if((server == NULL) || (state == NULL))
49738 return UA_STATUSCODE_BADINVALIDARGUMENT;
49739 lockServer(server);
49740 UA_DataSetWriter *currentDataSetWriter =
49741 UA_DataSetWriter_findDSWbyId(server, identifier: dataSetWriterIdentifier);
49742 UA_StatusCode res = UA_STATUSCODE_GOOD;
49743 if(currentDataSetWriter) {
49744 *state = currentDataSetWriter->state;
49745 } else {
49746 res = UA_STATUSCODE_BADNOTFOUND;
49747 }
49748 unlockServer(server);
49749 return res;
49750}
49751
49752UA_DataSetWriter *
49753UA_DataSetWriter_findDSWbyId(UA_Server *server, UA_NodeId identifier) {
49754 UA_PubSubConnection *pubSubConnection;
49755 TAILQ_FOREACH(pubSubConnection, &server->pubSubManager.connections, listEntry){
49756 UA_WriterGroup *tmpWriterGroup;
49757 LIST_FOREACH(tmpWriterGroup, &pubSubConnection->writerGroups, listEntry){
49758 UA_DataSetWriter *tmpWriter;
49759 LIST_FOREACH(tmpWriter, &tmpWriterGroup->writers, listEntry){
49760 if(UA_NodeId_equal(p1: &tmpWriter->identifier, p2: &identifier)){
49761 return tmpWriter;
49762 }
49763 }
49764 }
49765 }
49766 return NULL;
49767}
49768
49769void
49770UA_DataSetWriterConfig_clear(UA_DataSetWriterConfig *pdsConfig) {
49771 UA_String_clear(p: &pdsConfig->name);
49772 UA_String_clear(p: &pdsConfig->dataSetName);
49773 UA_KeyValueMap_clear(map: &pdsConfig->dataSetWriterProperties);
49774 UA_ExtensionObject_clear(p: &pdsConfig->messageSettings);
49775 memset(s: pdsConfig, c: 0, n: sizeof(UA_DataSetWriterConfig));
49776}
49777
49778//state machine methods not part of the open62541 state machine API
49779UA_StatusCode
49780UA_DataSetWriter_setPubSubState(UA_Server *server,
49781 UA_DataSetWriter *dataSetWriter,
49782 UA_PubSubState state,
49783 UA_StatusCode cause) {
49784 UA_StatusCode ret = UA_STATUSCODE_GOOD;
49785 UA_PubSubState oldState = dataSetWriter->state;
49786 switch(state){
49787 case UA_PUBSUBSTATE_DISABLED:
49788 switch (dataSetWriter->state){
49789 case UA_PUBSUBSTATE_DISABLED:
49790 break;
49791 case UA_PUBSUBSTATE_PAUSED:
49792 dataSetWriter->state = UA_PUBSUBSTATE_DISABLED;
49793 //no further action is required
49794 break;
49795 case UA_PUBSUBSTATE_OPERATIONAL:
49796 dataSetWriter->state = UA_PUBSUBSTATE_DISABLED;
49797 break;
49798 case UA_PUBSUBSTATE_ERROR:
49799 break;
49800 default:
49801 UA_LOG_WARNING_WRITER(server->config.logging, dataSetWriter,
49802 "Received unknown PubSub state!");
49803 }
49804 break;
49805 case UA_PUBSUBSTATE_PAUSED:
49806 switch (dataSetWriter->state){
49807 case UA_PUBSUBSTATE_DISABLED:
49808 break;
49809 case UA_PUBSUBSTATE_PAUSED:
49810 break;
49811 case UA_PUBSUBSTATE_OPERATIONAL:
49812 break;
49813 case UA_PUBSUBSTATE_ERROR:
49814 break;
49815 default:
49816 UA_LOG_WARNING_WRITER(server->config.logging, dataSetWriter,
49817 "Received unknown PubSub state!");
49818 }
49819 break;
49820 case UA_PUBSUBSTATE_OPERATIONAL:
49821 switch (dataSetWriter->state){
49822 case UA_PUBSUBSTATE_DISABLED:
49823 dataSetWriter->state = UA_PUBSUBSTATE_OPERATIONAL;
49824 break;
49825 case UA_PUBSUBSTATE_PAUSED:
49826 break;
49827 case UA_PUBSUBSTATE_OPERATIONAL:
49828 break;
49829 case UA_PUBSUBSTATE_ERROR:
49830 break;
49831 default:
49832 UA_LOG_WARNING_WRITER(server->config.logging, dataSetWriter,
49833 "Received unknown PubSub state!");
49834 }
49835 break;
49836 case UA_PUBSUBSTATE_ERROR:
49837 switch (dataSetWriter->state){
49838 case UA_PUBSUBSTATE_DISABLED:
49839 break;
49840 case UA_PUBSUBSTATE_PAUSED:
49841 break;
49842 case UA_PUBSUBSTATE_OPERATIONAL:
49843 break;
49844 case UA_PUBSUBSTATE_ERROR:
49845 break;
49846 default:
49847 UA_LOG_WARNING_WRITER(server->config.logging, dataSetWriter,
49848 "Received unknown PubSub state!");
49849 }
49850 break;
49851 default:
49852 UA_LOG_WARNING_WRITER(server->config.logging, dataSetWriter,
49853 "Received unknown PubSub state!");
49854 }
49855 if (state != oldState) {
49856 /* inform application about state change */
49857 UA_ServerConfig *pConfig = &server->config;
49858 if(pConfig->pubSubConfig.stateChangeCallback != 0) {
49859 pConfig->pubSubConfig.
49860 stateChangeCallback(server, &dataSetWriter->identifier, state, cause);
49861 }
49862 }
49863 return ret;
49864}
49865
49866UA_StatusCode
49867UA_DataSetWriter_create(UA_Server *server,
49868 const UA_NodeId writerGroup, const UA_NodeId dataSet,
49869 const UA_DataSetWriterConfig *dataSetWriterConfig,
49870 UA_NodeId *writerIdentifier) {
49871 UA_LOCK_ASSERT(&server->serviceMutex, 1);
49872 if(!dataSetWriterConfig)
49873 return UA_STATUSCODE_BADINVALIDARGUMENT;
49874
49875 UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, identifier: writerGroup);
49876 if(!wg)
49877 return UA_STATUSCODE_BADNOTFOUND;
49878
49879 /* Make checks for a heartbeat */
49880 if(UA_NodeId_isNull(p: &dataSet) && dataSetWriterConfig->keyFrameCount != 1) {
49881 UA_LOG_WARNING_WRITERGROUP(server->config.logging, wg,
49882 "Adding DataSetWriter failed: DataSet can be null only for "
49883 "a heartbeat in which case KeyFrameCount shall be 1");
49884 return UA_STATUSCODE_BADCONFIGURATIONERROR;
49885 }
49886
49887 if(wg->configurationFrozen) {
49888 UA_LOG_WARNING_WRITERGROUP(server->config.logging, wg,
49889 "Adding DataSetWriter failed: WriterGroup is frozen");
49890 return UA_STATUSCODE_BADCONFIGURATIONERROR;
49891 }
49892
49893 UA_PublishedDataSet *currentDataSetContext = NULL;
49894
49895 if(!UA_NodeId_isNull(p: &dataSet)) {
49896 currentDataSetContext = UA_PublishedDataSet_findPDSbyId(server, identifier: dataSet);
49897 if(!currentDataSetContext)
49898 return UA_STATUSCODE_BADNOTFOUND;
49899
49900 if(currentDataSetContext->configurationFreezeCounter > 0) {
49901 UA_LOG_WARNING_DATASET(server->config.logging, currentDataSetContext,
49902 "Adding DataSetWriter failed: PublishedDataSet is frozen");
49903 return UA_STATUSCODE_BADCONFIGURATIONERROR;
49904 }
49905
49906 if(wg->config.rtLevel != UA_PUBSUB_RT_NONE) {
49907 UA_DataSetField *tmpDSF;
49908 TAILQ_FOREACH(tmpDSF, &currentDataSetContext->fields, listEntry) {
49909 if(!tmpDSF->config.field.variable.rtValueSource.rtFieldSourceEnabled &&
49910 !tmpDSF->config.field.variable.rtValueSource.rtInformationModelNode) {
49911 UA_LOG_WARNING_DATASET(server->config.logging, currentDataSetContext,
49912 "Adding DataSetWriter failed: "
49913 "Fields in PDS are not RT capable");
49914 return UA_STATUSCODE_BADCONFIGURATIONERROR;
49915 }
49916 }
49917 }
49918 }
49919
49920 UA_DataSetWriter *newDataSetWriter = (UA_DataSetWriter *)
49921 UA_calloc(nmemb: 1, size: sizeof(UA_DataSetWriter));
49922 if(!newDataSetWriter)
49923 return UA_STATUSCODE_BADOUTOFMEMORY;
49924
49925 newDataSetWriter->componentType = UA_PUBSUB_COMPONENT_DATASETWRITER;
49926
49927 UA_StatusCode res = UA_STATUSCODE_GOOD;
49928 if(wg->state == UA_PUBSUBSTATE_OPERATIONAL) {
49929 res = UA_DataSetWriter_setPubSubState(server, dataSetWriter: newDataSetWriter,
49930 state: UA_PUBSUBSTATE_OPERATIONAL,
49931 UA_STATUSCODE_GOOD);
49932 if(res != UA_STATUSCODE_GOOD) {
49933 UA_LOG_ERROR_WRITERGROUP(server->config.logging, wg,
49934 "Add DataSetWriter failed: setPubSubState failed");
49935 UA_free(ptr: newDataSetWriter);
49936 return res;
49937 }
49938 }
49939
49940 /* Copy the config into the new dataSetWriter */
49941 res = UA_DataSetWriterConfig_copy(src: dataSetWriterConfig, dst: &newDataSetWriter->config);
49942 UA_CHECK_STATUS(res, UA_free(newDataSetWriter); return res);
49943
49944 if(!UA_NodeId_isNull(p: &dataSet) && currentDataSetContext != NULL) {
49945 /* Save the current version of the connected PublishedDataSet */
49946 newDataSetWriter->connectedDataSetVersion =
49947 currentDataSetContext->dataSetMetaData.configurationVersion;
49948
49949 if(server->config.pubSubConfig.enableDeltaFrames) {
49950 /* Initialize the queue for the last values */
49951 if(currentDataSetContext->fieldSize > 0) {
49952 newDataSetWriter->lastSamples = (UA_DataSetWriterSample*)
49953 UA_calloc(nmemb: currentDataSetContext->fieldSize, size: sizeof(UA_DataSetWriterSample));
49954 if(!newDataSetWriter->lastSamples) {
49955 UA_DataSetWriterConfig_clear(pdsConfig: &newDataSetWriter->config);
49956 UA_free(ptr: newDataSetWriter);
49957 return UA_STATUSCODE_BADOUTOFMEMORY;
49958 }
49959 newDataSetWriter->lastSamplesCount = currentDataSetContext->fieldSize;
49960 for(size_t i = 0; i < newDataSetWriter->lastSamplesCount; i++) {
49961 UA_DataValue_init(p: &newDataSetWriter->lastSamples[i].value);
49962 newDataSetWriter->lastSamples[i].valueChanged = false;
49963 }
49964 }
49965 }
49966 /* Connect PublishedDataSet with DataSetWriter */
49967 newDataSetWriter->connectedDataSet = currentDataSetContext->identifier;
49968 } else {
49969 /* If the dataSet is NULL, we are adding a heartbeat writer */
49970 newDataSetWriter->connectedDataSetVersion.majorVersion = 0;
49971 newDataSetWriter->connectedDataSetVersion.minorVersion = 0;
49972 newDataSetWriter->connectedDataSet = UA_NODEID_NULL;
49973 }
49974
49975 newDataSetWriter->linkedWriterGroup = wg->identifier;
49976
49977 /* Add the new writer to the group. Add to the end of the linked list to
49978 * ensure the order in the generated NetworkMessage is as expected. */
49979 UA_DataSetWriter *after = LIST_FIRST(&wg->writers);
49980 if(!after) {
49981 LIST_INSERT_HEAD(&wg->writers, newDataSetWriter, listEntry);
49982 } else {
49983 while(LIST_NEXT(after, listEntry))
49984 after = LIST_NEXT(after, listEntry);
49985 LIST_INSERT_AFTER(after, newDataSetWriter, listEntry);
49986 }
49987 wg->writersCount++;
49988
49989#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
49990 res |= addDataSetWriterRepresentation(server, dataSetWriter: newDataSetWriter);
49991#else
49992 UA_PubSubManager_generateUniqueNodeId(&server->pubSubManager,
49993 &newDataSetWriter->identifier);
49994#endif
49995 if(writerIdentifier)
49996 UA_NodeId_copy(src: &newDataSetWriter->identifier, dst: writerIdentifier);
49997 return res;
49998}
49999
50000UA_StatusCode
50001UA_Server_addDataSetWriter(UA_Server *server,
50002 const UA_NodeId writerGroup, const UA_NodeId dataSet,
50003 const UA_DataSetWriterConfig *dataSetWriterConfig,
50004 UA_NodeId *writerIdentifier) {
50005 lockServer(server);
50006 /* Delete the reserved IDs if the related session no longer exists. */
50007 UA_PubSubManager_freeIds(server);
50008 UA_StatusCode res = UA_DataSetWriter_create(server, writerGroup, dataSet,
50009 dataSetWriterConfig, writerIdentifier);
50010 unlockServer(server);
50011 return res;
50012}
50013
50014void
50015UA_DataSetWriter_freezeConfiguration(UA_Server *server,
50016 UA_DataSetWriter *dsw) {
50017 UA_PublishedDataSet *pds =
50018 UA_PublishedDataSet_findPDSbyId(server, identifier: dsw->connectedDataSet);
50019 if(pds) { /* Skip for heartbeat writers */
50020 pds->configurationFreezeCounter++;
50021 UA_DataSetField *dsf;
50022 TAILQ_FOREACH(dsf, &pds->fields, listEntry) {
50023 dsf->configurationFrozen = true;
50024 }
50025 }
50026 dsw->configurationFrozen = true;
50027}
50028
50029void
50030UA_DataSetWriter_unfreezeConfiguration(UA_Server *server,
50031 UA_DataSetWriter *dsw) {
50032 UA_PublishedDataSet *pds =
50033 UA_PublishedDataSet_findPDSbyId(server, identifier: dsw->connectedDataSet);
50034 if(pds) { /* Skip for heartbeat writers */
50035 pds->configurationFreezeCounter--;
50036 if(pds->configurationFreezeCounter == 0) {
50037 UA_DataSetField *dsf;
50038 TAILQ_FOREACH(dsf, &pds->fields, listEntry){
50039 dsf->configurationFrozen = false;
50040 }
50041 }
50042 dsw->configurationFrozen = false;
50043 }
50044}
50045
50046UA_StatusCode
50047UA_DataSetWriter_prepareDataSet(UA_Server *server, UA_DataSetWriter *dsw,
50048 UA_DataSetMessage *dsm) {
50049 /* No PublishedDataSet defined -> Heartbeat messages only */
50050 UA_StatusCode res = UA_STATUSCODE_GOOD;
50051 if(UA_NodeId_isNull(p: &dsw->connectedDataSet)) {
50052 res = UA_DataSetWriter_generateDataSetMessage(server, dataSetMessage: dsm, dataSetWriter: dsw);
50053 if(res != UA_STATUSCODE_GOOD) {
50054 UA_LOG_WARNING_WRITER(server->config.logging, dsw,
50055 "PubSub-RT configuration fail: "
50056 "Heartbeat DataSetMessage creation failed");
50057 }
50058 return res;
50059 }
50060
50061 /* Get the PublishedDataSet */
50062 UA_PublishedDataSet *pds =
50063 UA_PublishedDataSet_findPDSbyId(server, identifier: dsw->connectedDataSet);
50064 if(!pds) {
50065 UA_LOG_WARNING_WRITER(server->config.logging, dsw,
50066 "PubSub-RT configuration fail: "
50067 "PublishedDataSet not found");
50068 return UA_STATUSCODE_BADINTERNALERROR;
50069 }
50070
50071 UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, identifier: dsw->linkedWriterGroup);
50072 UA_assert(wg);
50073
50074 /* Promoted Fields not allowed if RT is enabled */
50075 if(wg->config.rtLevel > UA_PUBSUB_RT_NONE &&
50076 pds->promotedFieldsCount > 0) {
50077 UA_LOG_WARNING_WRITER(server->config.logging, dsw,
50078 "PubSub-RT configuration fail: "
50079 "PDS contains promoted fields");
50080 return UA_STATUSCODE_BADNOTSUPPORTED;
50081 }
50082
50083 /* Test the DataSetFields */
50084 UA_DataSetField *dsf;
50085 TAILQ_FOREACH(dsf, &pds->fields, listEntry) {
50086 UA_NodeId *publishedVariable =
50087 &dsf->config.field.variable.publishParameters.publishedVariable;
50088
50089 /* Check that the target is a VariableNode */
50090 const UA_VariableNode *rtNode = (const UA_VariableNode*)
50091 UA_NODESTORE_GET(server, nodeId: publishedVariable);
50092 if(rtNode && rtNode->head.nodeClass != UA_NODECLASS_VARIABLE) {
50093 UA_LOG_ERROR_WRITER(server->config.logging, dsw,
50094 "PubSub-RT configuration fail: "
50095 "PDS points to a node that is not a variable");
50096 UA_NODESTORE_RELEASE(server, (const UA_Node *)rtNode);
50097 return UA_STATUSCODE_BADNOTSUPPORTED;
50098 }
50099 UA_NODESTORE_RELEASE(server, (const UA_Node *)rtNode);
50100
50101 /* TODO: Get the External Value Source from the node instead of from the config */
50102
50103 /* If direct-value-access is enabled, the pointers need to be set */
50104 if(wg->config.rtLevel & UA_PUBSUB_RT_DIRECT_VALUE_ACCESS &&
50105 !dsf->config.field.variable.rtValueSource.rtFieldSourceEnabled) {
50106 UA_LOG_ERROR_WRITER(server->config.logging, dsw,
50107 "PubSub-RT configuration fail: PDS published-variable "
50108 "does not have an external data source");
50109 return UA_STATUSCODE_BADNOTSUPPORTED;
50110 }
50111
50112 /* Check that the values have a fixed size if fixed offsets are needed */
50113 if(wg->config.rtLevel & UA_PUBSUB_RT_FIXED_SIZE) {
50114 if((UA_NodeId_equal(p1: &dsf->fieldMetaData.dataType,
50115 p2: &UA_TYPES[UA_TYPES_STRING].typeId) ||
50116 UA_NodeId_equal(p1: &dsf->fieldMetaData.dataType,
50117 p2: &UA_TYPES[UA_TYPES_BYTESTRING].typeId)) &&
50118 dsf->fieldMetaData.maxStringLength == 0) {
50119 UA_LOG_WARNING_WRITER(server->config.logging, dsw,
50120 "PubSub-RT configuration fail: "
50121 "PDS contains String/ByteString with dynamic length");
50122 return UA_STATUSCODE_BADNOTSUPPORTED;
50123 } else if(!UA_DataType_isNumeric(
50124 type: UA_findDataType(typeId: &dsf->fieldMetaData.dataType)) &&
50125 !UA_NodeId_equal(p1: &dsf->fieldMetaData.dataType,
50126 p2: &UA_TYPES[UA_TYPES_BOOLEAN].typeId)) {
50127 UA_LOG_WARNING_WRITER(server->config.logging, dsw,
50128 "PubSub-RT configuration fail: "
50129 "PDS contains variable with dynamic size");
50130 return UA_STATUSCODE_BADNOTSUPPORTED;
50131 }
50132 }
50133 }
50134
50135 /* Generate the DSM */
50136 res = UA_DataSetWriter_generateDataSetMessage(server, dataSetMessage: dsm, dataSetWriter: dsw);
50137 if(res != UA_STATUSCODE_GOOD) {
50138 UA_LOG_WARNING_WRITER(server->config.logging, dsw,
50139 "PubSub-RT configuration fail: "
50140 "DataSetMessage buffering failed");
50141 }
50142
50143 return res;
50144}
50145
50146UA_StatusCode
50147UA_DataSetWriter_remove(UA_Server *server, UA_DataSetWriter *dataSetWriter) {
50148 UA_LOCK_ASSERT(&server->serviceMutex, 1);
50149
50150 /* Frozen? */
50151 if(dataSetWriter->configurationFrozen) {
50152 UA_LOG_WARNING_WRITER(server->config.logging, dataSetWriter,
50153 "Remove DataSetWriter failed: WriterGroup is frozen");
50154 return UA_STATUSCODE_BADCONFIGURATIONERROR;
50155 }
50156
50157 /* Remove from information model */
50158#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
50159 deleteNode(server, nodeId: dataSetWriter->identifier, true);
50160#endif
50161
50162 /* Remove DataSetWriter from group */
50163 UA_WriterGroup *linkedWriterGroup =
50164 UA_WriterGroup_findWGbyId(server, identifier: dataSetWriter->linkedWriterGroup);
50165 if(linkedWriterGroup) {
50166 LIST_REMOVE(dataSetWriter, listEntry);
50167 linkedWriterGroup->writersCount--;
50168 }
50169
50170 UA_DataSetWriterConfig_clear(pdsConfig: &dataSetWriter->config);
50171 UA_NodeId_clear(p: &dataSetWriter->identifier);
50172 UA_NodeId_clear(p: &dataSetWriter->linkedWriterGroup);
50173 UA_NodeId_clear(p: &dataSetWriter->connectedDataSet);
50174
50175 if(server->config.pubSubConfig.enableDeltaFrames) {
50176 /* Delete lastSamples store */
50177 for(size_t i = 0; i < dataSetWriter->lastSamplesCount; i++) {
50178 UA_DataValue_clear(p: &dataSetWriter->lastSamples[i].value);
50179 }
50180 UA_free(ptr: dataSetWriter->lastSamples);
50181 dataSetWriter->lastSamples = NULL;
50182 dataSetWriter->lastSamplesCount = 0;
50183 }
50184
50185 UA_free(ptr: dataSetWriter);
50186 return UA_STATUSCODE_GOOD;
50187}
50188
50189UA_StatusCode
50190UA_Server_removeDataSetWriter(UA_Server *server, const UA_NodeId dsw) {
50191 lockServer(server);
50192 UA_DataSetWriter *dataSetWriter = UA_DataSetWriter_findDSWbyId(server, identifier: dsw);
50193 if(!dataSetWriter) {
50194 unlockServer(server);
50195 return UA_STATUSCODE_BADNOTFOUND;
50196 }
50197 UA_StatusCode res = UA_DataSetWriter_remove(server, dataSetWriter);
50198 unlockServer(server);
50199 return res;
50200}
50201
50202/*********************************************************/
50203/* PublishValues handling */
50204/*********************************************************/
50205
50206/* Compare two variants. Internally used for value change detection. */
50207static UA_Boolean
50208valueChangedVariant(UA_Variant *oldValue, UA_Variant *newValue) {
50209 if(!oldValue || !newValue)
50210 return false;
50211
50212 size_t oldValueEncodingSize = UA_calcSizeBinary(p: oldValue, type: &UA_TYPES[UA_TYPES_VARIANT]);
50213 size_t newValueEncodingSize = UA_calcSizeBinary(p: newValue, type: &UA_TYPES[UA_TYPES_VARIANT]);
50214 if(oldValueEncodingSize == 0 || newValueEncodingSize == 0)
50215 return false;
50216
50217 if(oldValueEncodingSize != newValueEncodingSize)
50218 return true;
50219
50220 UA_ByteString oldValueEncoding = UA_BYTESTRING_NULL;
50221 UA_StatusCode res = UA_ByteString_allocBuffer(bs: &oldValueEncoding, length: oldValueEncodingSize);
50222 if(res != UA_STATUSCODE_GOOD)
50223 return false;
50224
50225 UA_ByteString newValueEncoding = UA_BYTESTRING_NULL;
50226 res = UA_ByteString_allocBuffer(bs: &newValueEncoding, length: newValueEncodingSize);
50227 if(res != UA_STATUSCODE_GOOD) {
50228 UA_ByteString_clear(p: &oldValueEncoding);
50229 return false;
50230 }
50231
50232 UA_Byte *bufPosOldValue = oldValueEncoding.data;
50233 const UA_Byte *bufEndOldValue = &oldValueEncoding.data[oldValueEncoding.length];
50234 UA_Byte *bufPosNewValue = newValueEncoding.data;
50235 const UA_Byte *bufEndNewValue = &newValueEncoding.data[newValueEncoding.length];
50236
50237 UA_Boolean compareResult = false; /* default */
50238
50239 res = UA_encodeBinaryInternal(src: oldValue, type: &UA_TYPES[UA_TYPES_VARIANT],
50240 bufPos: &bufPosOldValue, bufEnd: &bufEndOldValue, NULL, NULL);
50241 if(res != UA_STATUSCODE_GOOD)
50242 goto cleanup;
50243
50244 res = UA_encodeBinaryInternal(src: newValue, type: &UA_TYPES[UA_TYPES_VARIANT],
50245 bufPos: &bufPosNewValue, bufEnd: &bufEndNewValue, NULL, NULL);
50246 if(res != UA_STATUSCODE_GOOD)
50247 goto cleanup;
50248
50249 oldValueEncoding.length = (uintptr_t)bufPosOldValue - (uintptr_t)oldValueEncoding.data;
50250 newValueEncoding.length = (uintptr_t)bufPosNewValue - (uintptr_t)newValueEncoding.data;
50251 compareResult = !UA_ByteString_equal(p1: &oldValueEncoding, p2: &newValueEncoding);
50252
50253 cleanup:
50254 UA_ByteString_clear(p: &oldValueEncoding);
50255 UA_ByteString_clear(p: &newValueEncoding);
50256 return compareResult;
50257}
50258
50259static UA_StatusCode
50260UA_PubSubDataSetWriter_generateKeyFrameMessage(UA_Server *server,
50261 UA_DataSetMessage *dataSetMessage,
50262 UA_DataSetWriter *dataSetWriter) {
50263 UA_PublishedDataSet *currentDataSet =
50264 UA_PublishedDataSet_findPDSbyId(server, identifier: dataSetWriter->connectedDataSet);
50265 if(!currentDataSet)
50266 return UA_STATUSCODE_BADNOTFOUND;
50267
50268 /* Prepare DataSetMessageContent */
50269 dataSetMessage->header.dataSetMessageValid = true;
50270 dataSetMessage->header.dataSetMessageType = UA_DATASETMESSAGE_DATAKEYFRAME;
50271 dataSetMessage->data.keyFrameData.fieldCount = currentDataSet->fieldSize;
50272 dataSetMessage->data.keyFrameData.dataSetFields = (UA_DataValue *)
50273 UA_Array_new(size: currentDataSet->fieldSize, type: &UA_TYPES[UA_TYPES_DATAVALUE]);
50274 UA_PublishedDataSet *pds = UA_PublishedDataSet_findPDSbyId(server, identifier: dataSetWriter->connectedDataSet);
50275 dataSetMessage->data.keyFrameData.dataSetMetaDataType = &pds->dataSetMetaData;
50276 if(!dataSetMessage->data.keyFrameData.dataSetFields)
50277 return UA_STATUSCODE_BADOUTOFMEMORY;
50278
50279#ifdef UA_ENABLE_JSON_ENCODING
50280 dataSetMessage->data.keyFrameData.fieldNames = (UA_String *)
50281 UA_Array_new(size: currentDataSet->fieldSize, type: &UA_TYPES[UA_TYPES_STRING]);
50282 if(!dataSetMessage->data.keyFrameData.fieldNames) {
50283 UA_DataSetMessage_clear(p: dataSetMessage);
50284 return UA_STATUSCODE_BADOUTOFMEMORY;
50285 }
50286#endif
50287
50288 /* Loop over the fields */
50289 size_t counter = 0;
50290 UA_DataSetField *dsf;
50291 TAILQ_FOREACH(dsf, &currentDataSet->fields, listEntry) {
50292#ifdef UA_ENABLE_JSON_ENCODING
50293 /* Set the field name alias */
50294 UA_String_copy(src: &dsf->config.field.variable.fieldNameAlias,
50295 dst: &dataSetMessage->data.keyFrameData.fieldNames[counter]);
50296#endif
50297
50298 /* Sample the value */
50299 UA_DataValue *dfv = &dataSetMessage->data.keyFrameData.dataSetFields[counter];
50300 UA_PubSubDataSetField_sampleValue(server, field: dsf, value: dfv);
50301
50302 /* Deactivate statuscode? */
50303 if(((u64)dataSetWriter->config.dataSetFieldContentMask &
50304 (u64)UA_DATASETFIELDCONTENTMASK_STATUSCODE) == 0)
50305 dfv->hasStatus = false;
50306
50307 /* Deactivate timestamps */
50308 if(((u64)dataSetWriter->config.dataSetFieldContentMask &
50309 (u64)UA_DATASETFIELDCONTENTMASK_SOURCETIMESTAMP) == 0)
50310 dfv->hasSourceTimestamp = false;
50311 if(((u64)dataSetWriter->config.dataSetFieldContentMask &
50312 (u64)UA_DATASETFIELDCONTENTMASK_SOURCEPICOSECONDS) == 0)
50313 dfv->hasSourcePicoseconds = false;
50314 if(((u64)dataSetWriter->config.dataSetFieldContentMask &
50315 (u64)UA_DATASETFIELDCONTENTMASK_SERVERTIMESTAMP) == 0)
50316 dfv->hasServerTimestamp = false;
50317 if(((u64)dataSetWriter->config.dataSetFieldContentMask &
50318 (u64)UA_DATASETFIELDCONTENTMASK_SERVERPICOSECONDS) == 0)
50319 dfv->hasServerPicoseconds = false;
50320
50321 if(server->config.pubSubConfig.enableDeltaFrames) {
50322 /* Update lastValue store */
50323 UA_DataValue_clear(p: &dataSetWriter->lastSamples[counter].value);
50324 UA_DataValue_copy(src: dfv, dst: &dataSetWriter->lastSamples[counter].value);
50325 }
50326 counter++;
50327 }
50328 return UA_STATUSCODE_GOOD;
50329}
50330
50331/* the input message is already initialized and that the method
50332 * must not be called twice for the same message */
50333static UA_StatusCode
50334UA_PubSubDataSetWriter_generateDeltaFrameMessage(UA_Server *server,
50335 UA_DataSetMessage *dataSetMessage,
50336 UA_DataSetWriter *dataSetWriter) {
50337 UA_PublishedDataSet *currentDataSet =
50338 UA_PublishedDataSet_findPDSbyId(server, identifier: dataSetWriter->connectedDataSet);
50339 if(!currentDataSet)
50340 return UA_STATUSCODE_BADNOTFOUND;
50341
50342 /* Prepare DataSetMessageContent */
50343 dataSetMessage->header.dataSetMessageValid = true;
50344 dataSetMessage->header.dataSetMessageType = UA_DATASETMESSAGE_DATADELTAFRAME;
50345 if(currentDataSet->fieldSize == 0)
50346 return UA_STATUSCODE_GOOD;
50347
50348 UA_DataSetField *dsf;
50349 UA_UInt16 counter = 0;
50350 TAILQ_FOREACH(dsf, &currentDataSet->fields, listEntry) {
50351 /* Sample the value */
50352 UA_DataValue value;
50353 UA_DataValue_init(p: &value);
50354 UA_PubSubDataSetField_sampleValue(server, field: dsf, value: &value);
50355
50356 /* Check if the value has changed */
50357 UA_DataSetWriterSample *ls = &dataSetWriter->lastSamples[counter];
50358 if(valueChangedVariant(oldValue: &ls->value.value, newValue: &value.value)) {
50359 /* increase fieldCount for current delta message */
50360 dataSetMessage->data.deltaFrameData.fieldCount++;
50361 ls->valueChanged = true;
50362
50363 /* Update last stored sample */
50364 UA_DataValue_clear(p: &ls->value);
50365 ls->value = value;
50366 } else {
50367 UA_DataValue_clear(p: &value);
50368 ls->valueChanged = false;
50369 }
50370
50371 counter++;
50372 }
50373
50374 /* Allocate DeltaFrameFields */
50375 UA_DataSetMessage_DeltaFrameField *deltaFields = (UA_DataSetMessage_DeltaFrameField *)
50376 UA_calloc(nmemb: counter, size: sizeof(UA_DataSetMessage_DeltaFrameField));
50377 if(!deltaFields)
50378 return UA_STATUSCODE_BADOUTOFMEMORY;
50379
50380 dataSetMessage->data.deltaFrameData.deltaFrameFields = deltaFields;
50381 dataSetMessage->data.deltaFrameData.fieldCount = counter;
50382
50383 size_t currentDeltaField = 0;
50384 for(size_t i = 0; i < currentDataSet->fieldSize; i++) {
50385 if(!dataSetWriter->lastSamples[i].valueChanged)
50386 continue;
50387
50388 UA_DataSetMessage_DeltaFrameField *dff = &deltaFields[currentDeltaField];
50389
50390 dff->fieldIndex = (UA_UInt16) i;
50391 UA_DataValue_copy(src: &dataSetWriter->lastSamples[i].value, dst: &dff->fieldValue);
50392
50393 /* Reset the changed flag */
50394 dataSetWriter->lastSamples[i].valueChanged = false;
50395
50396 /* Deactivate statuscode? */
50397 if(((u64)dataSetWriter->config.dataSetFieldContentMask &
50398 (u64)UA_DATASETFIELDCONTENTMASK_STATUSCODE) == 0)
50399 dff->fieldValue.hasStatus = false;
50400
50401 /* Deactivate timestamps? */
50402 if(((u64)dataSetWriter->config.dataSetFieldContentMask &
50403 (u64)UA_DATASETFIELDCONTENTMASK_SOURCETIMESTAMP) == 0)
50404 dff->fieldValue.hasSourceTimestamp = false;
50405 if(((u64)dataSetWriter->config.dataSetFieldContentMask &
50406 (u64)UA_DATASETFIELDCONTENTMASK_SOURCEPICOSECONDS) == 0)
50407 dff->fieldValue.hasServerPicoseconds = false;
50408 if(((u64)dataSetWriter->config.dataSetFieldContentMask &
50409 (u64)UA_DATASETFIELDCONTENTMASK_SERVERTIMESTAMP) == 0)
50410 dff->fieldValue.hasServerTimestamp = false;
50411 if(((u64)dataSetWriter->config.dataSetFieldContentMask &
50412 (u64)UA_DATASETFIELDCONTENTMASK_SERVERPICOSECONDS) == 0)
50413 dff->fieldValue.hasServerPicoseconds = false;
50414
50415 currentDeltaField++;
50416 }
50417 return UA_STATUSCODE_GOOD;
50418}
50419
50420/* Generate a DataSetMessage for the given writer. */
50421UA_StatusCode
50422UA_DataSetWriter_generateDataSetMessage(UA_Server *server,
50423 UA_DataSetMessage *dataSetMessage,
50424 UA_DataSetWriter *dataSetWriter) {
50425 UA_Boolean heartbeat = false;
50426 UA_PublishedDataSet *currentDataSet = NULL;
50427 if(UA_NodeId_isNull(p: &dataSetWriter->connectedDataSet)){
50428 heartbeat = true;
50429 } else {
50430 currentDataSet =
50431 UA_PublishedDataSet_findPDSbyId(server, identifier: dataSetWriter->connectedDataSet);
50432 if(!currentDataSet){
50433 return UA_STATUSCODE_BADNOTFOUND;
50434 }
50435 }
50436
50437 /* Reset the message */
50438 memset(s: dataSetMessage, c: 0, n: sizeof(UA_DataSetMessage));
50439
50440 /* The configuration Flags are included
50441 * inside the std. defined UA_UadpDataSetWriterMessageDataType */
50442 UA_UadpDataSetWriterMessageDataType defaultUadpConfiguration;
50443 UA_UadpDataSetWriterMessageDataType *dsm = NULL;
50444 UA_JsonDataSetWriterMessageDataType *jsonDsm = NULL;
50445 const UA_ExtensionObject *ms = &dataSetWriter->config.messageSettings;
50446 if((ms->encoding == UA_EXTENSIONOBJECT_DECODED ||
50447 ms->encoding == UA_EXTENSIONOBJECT_DECODED_NODELETE) &&
50448 ms->content.decoded.type == &UA_TYPES[UA_TYPES_UADPDATASETWRITERMESSAGEDATATYPE]) {
50449 dsm = (UA_UadpDataSetWriterMessageDataType*)ms->content.decoded.data; /* type is UADP */
50450 } else if((ms->encoding == UA_EXTENSIONOBJECT_DECODED ||
50451 ms->encoding == UA_EXTENSIONOBJECT_DECODED_NODELETE) &&
50452 ms->content.decoded.type == &UA_TYPES[UA_TYPES_JSONDATASETWRITERMESSAGEDATATYPE]) {
50453 jsonDsm = (UA_JsonDataSetWriterMessageDataType*)ms->content.decoded.data; /* type is JSON */
50454 } else {
50455 /* Create default flag configuration if no
50456 * UadpDataSetWriterMessageDataType was passed in */
50457 memset(s: &defaultUadpConfiguration, c: 0, n: sizeof(UA_UadpDataSetWriterMessageDataType));
50458 defaultUadpConfiguration.dataSetMessageContentMask = (UA_UadpDataSetMessageContentMask)
50459 ((u64)UA_UADPDATASETMESSAGECONTENTMASK_TIMESTAMP |
50460 (u64)UA_UADPDATASETMESSAGECONTENTMASK_MAJORVERSION |
50461 (u64)UA_UADPDATASETMESSAGECONTENTMASK_MINORVERSION);
50462 dsm = &defaultUadpConfiguration; /* type is UADP */
50463 }
50464
50465 /* The field encoding depends on the flags inside the writer config. */
50466 if(dataSetWriter->config.dataSetFieldContentMask &
50467 (u64)UA_DATASETFIELDCONTENTMASK_RAWDATA) {
50468 dataSetMessage->header.fieldEncoding = UA_FIELDENCODING_RAWDATA;
50469 } else if((u64)dataSetWriter->config.dataSetFieldContentMask &
50470 ((u64)UA_DATASETFIELDCONTENTMASK_SOURCETIMESTAMP |
50471 (u64)UA_DATASETFIELDCONTENTMASK_SERVERPICOSECONDS |
50472 (u64)UA_DATASETFIELDCONTENTMASK_SOURCEPICOSECONDS |
50473 (u64)UA_DATASETFIELDCONTENTMASK_STATUSCODE)) {
50474 dataSetMessage->header.fieldEncoding = UA_FIELDENCODING_DATAVALUE;
50475 } else {
50476 dataSetMessage->header.fieldEncoding = UA_FIELDENCODING_VARIANT;
50477 }
50478
50479 if(dsm) {
50480 /* Sanity-test the configuration */
50481 if(dsm->networkMessageNumber != 0 ||
50482 dsm->dataSetOffset != 0 ||
50483 dsm->configuredSize != 0) {
50484 UA_LOG_WARNING_WRITER(server->config.logging, dataSetWriter,
50485 "Static DSM configuration not supported, using defaults");
50486 dsm->networkMessageNumber = 0;
50487 dsm->dataSetOffset = 0;
50488 // dsm->configuredSize = 0;
50489 }
50490
50491 /* setting configured size in the dataSetMessage to add padding later on */
50492 dataSetMessage->configuredSize = dsm->configuredSize;
50493
50494 /* Std: 'The DataSetMessageContentMask defines the flags for the content
50495 * of the DataSetMessage header.' */
50496 if((u64)dsm->dataSetMessageContentMask &
50497 (u64)UA_UADPDATASETMESSAGECONTENTMASK_MAJORVERSION) {
50498 dataSetMessage->header.configVersionMajorVersionEnabled = true;
50499 if(heartbeat){
50500 dataSetMessage->header.configVersionMajorVersion = 0;
50501 } else {
50502 dataSetMessage->header.configVersionMajorVersion =
50503 currentDataSet->dataSetMetaData.configurationVersion.majorVersion;
50504 }
50505 }
50506 if((u64)dsm->dataSetMessageContentMask &
50507 (u64)UA_UADPDATASETMESSAGECONTENTMASK_MINORVERSION) {
50508 dataSetMessage->header.configVersionMinorVersionEnabled = true;
50509 if(heartbeat){
50510 dataSetMessage->header.configVersionMinorVersion = 0;
50511 } else {
50512 dataSetMessage->header.configVersionMinorVersion =
50513 currentDataSet->dataSetMetaData.configurationVersion.minorVersion;
50514 }
50515 }
50516
50517 if((u64)dsm->dataSetMessageContentMask &
50518 (u64)UA_UADPDATASETMESSAGECONTENTMASK_SEQUENCENUMBER) {
50519 dataSetMessage->header.dataSetMessageSequenceNrEnabled = true;
50520 dataSetMessage->header.dataSetMessageSequenceNr =
50521 dataSetWriter->actualDataSetMessageSequenceCount;
50522 }
50523
50524 if((u64)dsm->dataSetMessageContentMask &
50525 (u64)UA_UADPDATASETMESSAGECONTENTMASK_TIMESTAMP) {
50526 dataSetMessage->header.timestampEnabled = true;
50527 dataSetMessage->header.timestamp = UA_DateTime_now();
50528 }
50529
50530 /* TODO: Picoseconds resolution not supported atm */
50531 if((u64)dsm->dataSetMessageContentMask &
50532 (u64)UA_UADPDATASETMESSAGECONTENTMASK_PICOSECONDS) {
50533 dataSetMessage->header.picoSecondsIncluded = false;
50534 }
50535
50536 /* TODO: Statuscode not supported yet */
50537 if((u64)dsm->dataSetMessageContentMask &
50538 (u64)UA_UADPDATASETMESSAGECONTENTMASK_STATUS) {
50539 dataSetMessage->header.statusEnabled = true;
50540 }
50541 } else if(jsonDsm) {
50542 if((u64)jsonDsm->dataSetMessageContentMask &
50543 (u64)UA_JSONDATASETMESSAGECONTENTMASK_METADATAVERSION) {
50544 dataSetMessage->header.configVersionMajorVersionEnabled = true;
50545 dataSetMessage->header.configVersionMinorVersionEnabled = true;
50546 if(heartbeat){
50547 dataSetMessage->header.configVersionMajorVersion = 0;
50548 dataSetMessage->header.configVersionMinorVersion = 0;
50549 } else {
50550 dataSetMessage->header.configVersionMajorVersion =
50551 currentDataSet->dataSetMetaData.configurationVersion.majorVersion;
50552 dataSetMessage->header.configVersionMinorVersion =
50553 currentDataSet->dataSetMetaData.configurationVersion.minorVersion;
50554 }
50555 }
50556
50557 if((u64)jsonDsm->dataSetMessageContentMask &
50558 (u64)UA_JSONDATASETMESSAGECONTENTMASK_SEQUENCENUMBER) {
50559 dataSetMessage->header.dataSetMessageSequenceNrEnabled = true;
50560 dataSetMessage->header.dataSetMessageSequenceNr =
50561 dataSetWriter->actualDataSetMessageSequenceCount;
50562 }
50563
50564 if((u64)jsonDsm->dataSetMessageContentMask &
50565 (u64)UA_JSONDATASETMESSAGECONTENTMASK_TIMESTAMP) {
50566 dataSetMessage->header.timestampEnabled = true;
50567 dataSetMessage->header.timestamp = UA_DateTime_now();
50568 }
50569
50570 /* TODO: Statuscode not supported yet */
50571 if((u64)jsonDsm->dataSetMessageContentMask &
50572 (u64)UA_JSONDATASETMESSAGECONTENTMASK_STATUS) {
50573 dataSetMessage->header.statusEnabled = true;
50574 }
50575 }
50576
50577 /* Set the sequence count. Automatically rolls over to zero */
50578 dataSetWriter->actualDataSetMessageSequenceCount++;
50579
50580 if(heartbeat) {
50581 /* Prepare DataSetMessageContent */
50582 dataSetMessage->header.dataSetMessageValid = true;
50583 dataSetMessage->header.dataSetMessageType = UA_DATASETMESSAGE_DATAKEYFRAME;
50584 dataSetMessage->data.keyFrameData.fieldCount = 0;
50585 return UA_STATUSCODE_GOOD;
50586 }
50587
50588 /* JSON does not differ between deltaframes and keyframes, only keyframes
50589 * are currently used. */
50590 if(dsm && server->config.pubSubConfig.enableDeltaFrames) {
50591 /* Check if the PublishedDataSet version has changed -> if yes flush the
50592 * lastValue store and send a KeyFrame */
50593 if(dataSetWriter->connectedDataSetVersion.majorVersion !=
50594 currentDataSet->dataSetMetaData.configurationVersion.majorVersion ||
50595 dataSetWriter->connectedDataSetVersion.minorVersion !=
50596 currentDataSet->dataSetMetaData.configurationVersion.minorVersion) {
50597 /* Remove old samples */
50598 for(size_t i = 0; i < dataSetWriter->lastSamplesCount; i++)
50599 UA_DataValue_clear(p: &dataSetWriter->lastSamples[i].value);
50600
50601 /* Realloc PDS dependent memory */
50602 dataSetWriter->lastSamplesCount = currentDataSet->fieldSize;
50603 UA_DataSetWriterSample *newSamplesArray = (UA_DataSetWriterSample * )
50604 UA_realloc(ptr: dataSetWriter->lastSamples,
50605 size: sizeof(UA_DataSetWriterSample) * dataSetWriter->lastSamplesCount);
50606 if(!newSamplesArray)
50607 return UA_STATUSCODE_BADOUTOFMEMORY;
50608 dataSetWriter->lastSamples = newSamplesArray;
50609 memset(s: dataSetWriter->lastSamples, c: 0,
50610 n: sizeof(UA_DataSetWriterSample) * dataSetWriter->lastSamplesCount);
50611
50612 dataSetWriter->connectedDataSetVersion =
50613 currentDataSet->dataSetMetaData.configurationVersion;
50614 UA_PubSubDataSetWriter_generateKeyFrameMessage(server, dataSetMessage,
50615 dataSetWriter);
50616 dataSetWriter->deltaFrameCounter = 0;
50617 return UA_STATUSCODE_GOOD;
50618 }
50619
50620 /* The standard defines: if a PDS contains only one fields no delta messages
50621 * should be generated because they need more memory than a keyframe with 1
50622 * field. */
50623 if(currentDataSet->fieldSize > 1 && dataSetWriter->deltaFrameCounter > 0 &&
50624 dataSetWriter->deltaFrameCounter <= dataSetWriter->config.keyFrameCount) {
50625 UA_PubSubDataSetWriter_generateDeltaFrameMessage(server, dataSetMessage,
50626 dataSetWriter);
50627 dataSetWriter->deltaFrameCounter++;
50628 return UA_STATUSCODE_GOOD;
50629 }
50630
50631 dataSetWriter->deltaFrameCounter = 1;
50632 }
50633
50634 return UA_PubSubDataSetWriter_generateKeyFrameMessage(server, dataSetMessage,
50635 dataSetWriter);
50636}
50637
50638#endif /* UA_ENABLE_PUBSUB */
50639
50640/**** amalgamated original file "/src/pubsub/ua_pubsub_writergroup.c" ****/
50641
50642/* This Source Code Form is subject to the terms of the Mozilla Public
50643 * License, v. 2.0. If a copy of the MPL was not distributed with this
50644 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
50645 *
50646 * Copyright (c) 2017-2019 Fraunhofer IOSB (Author: Andreas Ebner)
50647 * Copyright (c) 2019 Fraunhofer IOSB (Author: Julius Pfrommer)
50648 * Copyright (c) 2019 Kalycito Infotech Private Limited
50649 * Copyright (c) 2020 Yannick Wallerer, Siemens AG
50650 * Copyright (c) 2020 Thomas Fischer, Siemens AG
50651 * Copyright (c) 2021 Fraunhofer IOSB (Author: Jan Hermes)
50652 * Copyright (c) 2022 Linutronix GmbH (Author: Muddasir Shakil)
50653 */
50654
50655
50656#ifdef UA_ENABLE_PUBSUB /* conditional compilation */
50657
50658
50659#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
50660#endif
50661
50662#define UA_MAX_STACKBUF 128 /* Max size of network messages on the stack */
50663
50664#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
50665static UA_StatusCode
50666encryptAndSign(UA_WriterGroup *wg, const UA_NetworkMessage *nm,
50667 UA_Byte *signStart, UA_Byte *encryptStart,
50668 UA_Byte *msgEnd);
50669
50670#endif
50671
50672static UA_StatusCode
50673generateNetworkMessage(UA_PubSubConnection *connection, UA_WriterGroup *wg,
50674 UA_DataSetMessage *dsm, UA_UInt16 *writerIds, UA_Byte dsmCount,
50675 UA_ExtensionObject *messageSettings,
50676 UA_ExtensionObject *transportSettings,
50677 UA_NetworkMessage *networkMessage);
50678
50679/* Add new publishCallback. The first execution is triggered directly after
50680 * creation. */
50681UA_StatusCode
50682UA_WriterGroup_addPublishCallback(UA_Server *server, UA_WriterGroup *wg) {
50683 UA_LOCK_ASSERT(&server->serviceMutex, 1);
50684
50685 /* Already registered */
50686 if(wg->publishCallbackId != 0)
50687 return UA_STATUSCODE_BADINTERNALERROR;
50688
50689 UA_StatusCode retval = UA_STATUSCODE_GOOD;
50690 if(wg->config.pubsubManagerCallback.addCustomCallback) {
50691 /* Use configured mechanism for cyclic callbacks */
50692 retval = wg->config.pubsubManagerCallback.
50693 addCustomCallback(server, wg->identifier,
50694 (UA_ServerCallback)UA_WriterGroup_publishCallback,
50695 wg, wg->config.publishingInterval,
50696 NULL, UA_TIMER_HANDLE_CYCLEMISS_WITH_CURRENTTIME,
50697 &wg->publishCallbackId);
50698 } else {
50699 /* Use EventLoop for cyclic callbacks */
50700 UA_EventLoop *el = UA_PubSubConnection_getEL(server, c: wg->linkedConnection);
50701 retval = el->addCyclicCallback(el, (UA_Callback)UA_WriterGroup_publishCallback,
50702 server, wg, wg->config.publishingInterval,
50703 NULL /* TODO: use basetime */,
50704 UA_TIMER_HANDLE_CYCLEMISS_WITH_CURRENTTIME,
50705 &wg->publishCallbackId);
50706 }
50707 if(retval != UA_STATUSCODE_GOOD)
50708 return retval;
50709
50710 /* Run once after creation. The Publish callback itself takes the server
50711 * mutex. So we release it first. */
50712 UA_WriterGroup_publishCallback(server, writerGroup: wg);
50713 return retval;
50714}
50715
50716static void
50717UA_WriterGroup_removePublishCallback(UA_Server *server, UA_WriterGroup *wg) {
50718 if(wg->publishCallbackId == 0)
50719 return;
50720 if(wg->config.pubsubManagerCallback.removeCustomCallback) {
50721 wg->config.pubsubManagerCallback.
50722 removeCustomCallback(server, wg->identifier, wg->publishCallbackId);
50723 } else {
50724 UA_EventLoop *el = UA_PubSubConnection_getEL(server, c: wg->linkedConnection);
50725 el->removeCyclicCallback(el, wg->publishCallbackId);
50726 }
50727 wg->publishCallbackId = 0;
50728}
50729
50730UA_StatusCode
50731UA_WriterGroup_create(UA_Server *server, const UA_NodeId connection,
50732 const UA_WriterGroupConfig *writerGroupConfig,
50733 UA_NodeId *writerGroupIdentifier) {
50734 /* Delete the reserved IDs if the related session no longer exists. */
50735 UA_PubSubManager_freeIds(server);
50736 if(!writerGroupConfig)
50737 return UA_STATUSCODE_BADINVALIDARGUMENT;
50738
50739 /* Search the connection by the given connectionIdentifier */
50740 UA_PubSubConnection *currentConnectionContext =
50741 UA_PubSubConnection_findConnectionbyId(server, connectionIdentifier: connection);
50742 if(!currentConnectionContext)
50743 return UA_STATUSCODE_BADNOTFOUND;
50744
50745 if(currentConnectionContext->configurationFreezeCounter > 0) {
50746 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
50747 msg: "Adding WriterGroup failed. PubSubConnection is frozen.");
50748 return UA_STATUSCODE_BADCONFIGURATIONERROR;
50749 }
50750
50751 /* Validate messageSettings type */
50752 const UA_ExtensionObject *ms = &writerGroupConfig->messageSettings;
50753 if(ms->content.decoded.type) {
50754 if(writerGroupConfig->encodingMimeType == UA_PUBSUB_ENCODING_JSON &&
50755 (ms->encoding != UA_EXTENSIONOBJECT_DECODED ||
50756 ms->content.decoded.type != &UA_TYPES[UA_TYPES_JSONWRITERGROUPMESSAGEDATATYPE])) {
50757 return UA_STATUSCODE_BADTYPEMISMATCH;
50758 }
50759
50760 if(writerGroupConfig->encodingMimeType == UA_PUBSUB_ENCODING_UADP &&
50761 (ms->encoding != UA_EXTENSIONOBJECT_DECODED ||
50762 ms->content.decoded.type != &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE])) {
50763 return UA_STATUSCODE_BADTYPEMISMATCH;
50764 }
50765 }
50766
50767 /* Allocate new WriterGroup */
50768 UA_WriterGroup *newWriterGroup = (UA_WriterGroup*)UA_calloc(nmemb: 1, size: sizeof(UA_WriterGroup));
50769 if(!newWriterGroup)
50770 return UA_STATUSCODE_BADOUTOFMEMORY;
50771
50772 memset(s: newWriterGroup, c: 0, n: sizeof(UA_WriterGroup));
50773 newWriterGroup->componentType = UA_PUBSUB_COMPONENT_WRITERGROUP;
50774 newWriterGroup->linkedConnection = currentConnectionContext;
50775
50776 /* Deep copy of the config */
50777 UA_WriterGroupConfig *newConfig = &newWriterGroup->config;
50778 UA_StatusCode res = UA_WriterGroupConfig_copy(src: writerGroupConfig, dst: newConfig);
50779 if(res != UA_STATUSCODE_GOOD) {
50780 UA_free(ptr: newWriterGroup);
50781 return res;
50782 }
50783
50784 /* Create the datatype value if not present */
50785 if(!newConfig->messageSettings.content.decoded.type) {
50786 UA_UadpWriterGroupMessageDataType *wgm = UA_UadpWriterGroupMessageDataType_new();
50787 newConfig->messageSettings.content.decoded.data = wgm;
50788 newConfig->messageSettings.content.decoded.type =
50789 &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE];
50790 newConfig->messageSettings.encoding = UA_EXTENSIONOBJECT_DECODED;
50791 }
50792
50793 /* Attach to the connection */
50794 LIST_INSERT_HEAD(&currentConnectionContext->writerGroups, newWriterGroup, listEntry);
50795 currentConnectionContext->writerGroupsSize++;
50796
50797 /* Add representation / create unique identifier */
50798#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
50799 res = addWriterGroupRepresentation(server, writerGroup: newWriterGroup);
50800#else
50801 UA_PubSubManager_generateUniqueNodeId(&server->pubSubManager,
50802 &newWriterGroup->identifier);
50803#endif
50804
50805#ifdef UA_ENABLE_PUBSUB_SKS
50806 if(writerGroupConfig->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
50807 writerGroupConfig->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
50808 if(!UA_String_isEmpty(&writerGroupConfig->securityGroupId) &&
50809 writerGroupConfig->securityPolicy) {
50810 /* Does the key storage already exist? */
50811 newWriterGroup->keyStorage =
50812 UA_PubSubKeyStorage_findKeyStorage(server, writerGroupConfig->securityGroupId);
50813
50814 if(!newWriterGroup->keyStorage) {
50815 /* Create a new key storage */
50816 newWriterGroup->keyStorage = (UA_PubSubKeyStorage *)
50817 UA_calloc(1, sizeof(UA_PubSubKeyStorage));
50818 if(!newWriterGroup)
50819 return UA_STATUSCODE_BADOUTOFMEMORY;
50820 res = UA_PubSubKeyStorage_init(server, newWriterGroup->keyStorage,
50821 &writerGroupConfig->securityGroupId,
50822 writerGroupConfig->securityPolicy, 0, 0);
50823 if(res != UA_STATUSCODE_GOOD) {
50824 UA_free(newWriterGroup);
50825 return res;
50826 }
50827 }
50828
50829 /* Increase the ref count */
50830 newWriterGroup->keyStorage->referenceCount++;
50831 }
50832 }
50833
50834#endif
50835
50836 if(writerGroupIdentifier)
50837 UA_NodeId_copy(src: &newWriterGroup->identifier, dst: writerGroupIdentifier);
50838
50839 /* Trigger the connection to open a connection */
50840 UA_PubSubConnection_setPubSubState(server, c: currentConnectionContext,
50841 state: currentConnectionContext->state,
50842 UA_STATUSCODE_GOOD);
50843
50844 return res;
50845}
50846
50847UA_StatusCode
50848UA_Server_addWriterGroup(UA_Server *server, const UA_NodeId connection,
50849 const UA_WriterGroupConfig *writerGroupConfig,
50850 UA_NodeId *writerGroupIdentifier) {
50851 lockServer(server);
50852 UA_StatusCode res = UA_WriterGroup_create(server, connection, writerGroupConfig,
50853 writerGroupIdentifier);
50854 unlockServer(server);
50855 return res;
50856}
50857
50858UA_StatusCode
50859UA_WriterGroup_remove(UA_Server *server, UA_WriterGroup *wg) {
50860 UA_LOCK_ASSERT(&server->serviceMutex, 1);
50861
50862 if(wg->configurationFrozen) {
50863 UA_LOG_WARNING_WRITERGROUP(server->config.logging, wg,
50864 "Deleting the WriterGroup failed. "
50865 "WriterGroup is frozen.");
50866 return UA_STATUSCODE_BADCONFIGURATIONERROR;
50867 }
50868
50869 UA_PubSubConnection *connection = wg->linkedConnection;
50870 UA_assert(connection);
50871 if(connection->configurationFreezeCounter > 0) {
50872 UA_LOG_WARNING_WRITERGROUP(server->config.logging, wg,
50873 "Deleting the WriterGroup failed. "
50874 "PubSubConnection is frozen.");
50875 return UA_STATUSCODE_BADCONFIGURATIONERROR;
50876 }
50877
50878 /* Disable (and disconnect) and set the deleteFlag. This prevents a
50879 * reconnect and triggers the deletion when the last open socket is
50880 * closed. */
50881 wg->deleteFlag = true;
50882 UA_WriterGroup_setPubSubState(server, writerGroup: wg, state: UA_PUBSUBSTATE_DISABLED, UA_STATUSCODE_GOOD);
50883
50884 UA_DataSetWriter *dsw, *dsw_tmp;
50885 LIST_FOREACH_SAFE(dsw, &wg->writers, listEntry, dsw_tmp) {
50886 UA_DataSetWriter_remove(server, dataSetWriter: dsw);
50887 }
50888
50889#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
50890 if(wg->config.securityPolicy && wg->securityPolicyContext) {
50891 wg->config.securityPolicy->deleteContext(wg->securityPolicyContext);
50892 wg->securityPolicyContext = NULL;
50893 }
50894#endif
50895
50896#ifdef UA_ENABLE_PUBSUB_SKS
50897 if(wg->keyStorage) {
50898 UA_PubSubKeyStorage_detachKeyStorage(server, wg->keyStorage);
50899 wg->keyStorage = NULL;
50900 }
50901#endif
50902
50903 if(wg->sendChannel == 0) {
50904 /* Unlink from the connection */
50905 LIST_REMOVE(wg, listEntry);
50906 connection->writerGroupsSize--;
50907 wg->linkedConnection = NULL;
50908
50909 /* Actually remove the WriterGroup */
50910#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
50911 deleteNode(server, nodeId: wg->identifier, true);
50912#endif
50913 UA_WriterGroupConfig_clear(writerGroupConfig: &wg->config);
50914 UA_NodeId_clear(p: &wg->identifier);
50915 UA_NetworkMessageOffsetBuffer_clear(nmob: &wg->bufferedMessage);
50916 UA_free(ptr: wg);
50917 }
50918
50919 /* Update the connection state */
50920 UA_PubSubConnection_setPubSubState(server, c: connection, state: connection->state,
50921 UA_STATUSCODE_GOOD);
50922
50923 return UA_STATUSCODE_GOOD;
50924}
50925
50926UA_StatusCode
50927UA_Server_removeWriterGroup(UA_Server *server, const UA_NodeId writerGroup) {
50928 lockServer(server);
50929 UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, identifier: writerGroup);
50930 if(!wg) {
50931 unlockServer(server);
50932 return UA_STATUSCODE_BADNOTFOUND;
50933 }
50934 UA_StatusCode res = UA_WriterGroup_remove(server, wg);
50935 unlockServer(server);
50936 return res;
50937}
50938
50939UA_StatusCode
50940UA_WriterGroup_freezeConfiguration(UA_Server *server, UA_WriterGroup *wg) {
50941 UA_LOCK_ASSERT(&server->serviceMutex, 1);
50942
50943 if(wg->configurationFrozen)
50944 return UA_STATUSCODE_GOOD;
50945
50946 /* Increase PubSubConnection freezeCounter */
50947 UA_PubSubConnection *pubSubConnection = wg->linkedConnection;
50948 pubSubConnection->configurationFreezeCounter++;
50949
50950 /* Freeze the WriterGroup */
50951 wg->configurationFrozen = true;
50952
50953 /* Freeze the DataSetWriter */
50954 UA_DataSetWriter *dsw;
50955 LIST_FOREACH(dsw, &wg->writers, listEntry) {
50956 UA_DataSetWriter_freezeConfiguration(server, dsw);
50957 }
50958
50959 /* Offset table enabled? */
50960 if((wg->config.rtLevel & UA_PUBSUB_RT_FIXED_SIZE) == 0)
50961 return UA_STATUSCODE_GOOD;
50962
50963 /* Offset table only possible for binary encoding */
50964 if(wg->config.encodingMimeType != UA_PUBSUB_ENCODING_UADP) {
50965 UA_LOG_WARNING_WRITERGROUP(server->config.logging, wg,
50966 "PubSub-RT configuration fail: Non-RT capable encoding.");
50967 return UA_STATUSCODE_BADNOTSUPPORTED;
50968 }
50969
50970 //TODO Clarify: should we only allow = maxEncapsulatedDataSetMessageCount == 1 with RT?
50971 //TODO Clarify: Behaviour if the finale size is more than MTU
50972
50973 /* Define variables here for goto */
50974 size_t msgSize;
50975 UA_ByteString buf;
50976 const UA_Byte *bufEnd;
50977 UA_Byte *bufPos;
50978 UA_NetworkMessage networkMessage;
50979 UA_StatusCode res = UA_STATUSCODE_GOOD;
50980 UA_STACKARRAY(UA_UInt16, dsWriterIds, wg->writersCount);
50981 UA_STACKARRAY(UA_DataSetMessage, dsmStore, wg->writersCount);
50982
50983 /* Validate the DataSetWriters and generate their DataSetMessage */
50984 size_t dsmCount = 0;
50985 LIST_FOREACH(dsw, &wg->writers, listEntry) {
50986 dsWriterIds[dsmCount] = dsw->config.dataSetWriterId;
50987 res = UA_DataSetWriter_prepareDataSet(server, dsw, dsm: &dsmStore[dsmCount]);
50988 if(res != UA_STATUSCODE_GOOD)
50989 goto cleanup_dsm;
50990 dsmCount++;
50991 }
50992
50993 /* Generate the NetworkMessage */
50994 memset(s: &networkMessage, c: 0, n: sizeof(networkMessage));
50995 res = generateNetworkMessage(connection: pubSubConnection, wg, dsm: dsmStore, writerIds: dsWriterIds,
50996 dsmCount: (UA_Byte) dsmCount, messageSettings: &wg->config.messageSettings,
50997 transportSettings: &wg->config.transportSettings, networkMessage: &networkMessage);
50998 if(res != UA_STATUSCODE_GOOD)
50999 goto cleanup_dsm;
51000
51001 /* Compute the message length and generate the offset-table (done inside
51002 * calcSizeBinary) */
51003 memset(s: &wg->bufferedMessage, c: 0, n: sizeof(UA_NetworkMessageOffsetBuffer));
51004 msgSize = UA_NetworkMessage_calcSizeBinary(p: &networkMessage, offsetBuffer: &wg->bufferedMessage);
51005#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
51006 if(wg->config.securityMode > UA_MESSAGESECURITYMODE_NONE) {
51007 UA_PubSubSecurityPolicy *sp = wg->config.securityPolicy;
51008 msgSize += sp->symmetricModule.cryptoModule.
51009 signatureAlgorithm.getLocalSignatureSize(sp->policyContext);
51010 }
51011#endif
51012
51013 /* Generate the buffer for the pre-encoded message */
51014 res = UA_ByteString_allocBuffer(bs: &buf, length: msgSize);
51015 if(res != UA_STATUSCODE_GOOD)
51016 goto cleanup;
51017 wg->bufferedMessage.buffer = buf;
51018
51019 /* Encode the NetworkMessage */
51020 bufEnd = &wg->bufferedMessage.buffer.data[wg->bufferedMessage.buffer.length];
51021 bufPos = wg->bufferedMessage.buffer.data;
51022
51023 /* Preallocate the encryption buffer */
51024#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
51025 if(wg->config.securityMode > UA_MESSAGESECURITYMODE_NONE) {
51026 UA_Byte *payloadPosition;
51027 UA_NetworkMessage_encodeBinary(&networkMessage, &bufPos, bufEnd, &payloadPosition);
51028 wg->bufferedMessage.payloadPosition = payloadPosition;
51029 wg->bufferedMessage.nm = (UA_NetworkMessage *)UA_calloc(1,sizeof(UA_NetworkMessage));
51030 wg->bufferedMessage.nm->securityHeader = networkMessage.securityHeader;
51031 UA_ByteString_allocBuffer(&wg->bufferedMessage.encryptBuffer, msgSize);
51032 }
51033#endif
51034
51035 if(wg->config.securityMode <= UA_MESSAGESECURITYMODE_NONE)
51036 UA_NetworkMessage_encodeBinary(src: &networkMessage, bufPos: &bufPos, bufEnd, NULL);
51037
51038 /* Post-processing of the OffsetBuffer to set the external data source from
51039 * the DataSetField configuration */
51040 if(wg->config.rtLevel & UA_PUBSUB_RT_DIRECT_VALUE_ACCESS) {
51041 size_t fieldPos = 0;
51042 LIST_FOREACH(dsw, &wg->writers, listEntry) {
51043 UA_PublishedDataSet *pds =
51044 UA_PublishedDataSet_findPDSbyId(server, identifier: dsw->connectedDataSet);
51045 if(!pds)
51046 continue;
51047
51048 /* Loop over all DataSetFields */
51049 UA_DataSetField *dsf;
51050 TAILQ_FOREACH(dsf, &pds->fields, listEntry) {
51051 UA_NetworkMessageOffsetType contentType;
51052 /* Move forward to the next payload-type offset field */
51053 do {
51054 fieldPos++;
51055 contentType = wg->bufferedMessage.offsets[fieldPos].contentType;
51056 } while(contentType != UA_PUBSUB_OFFSETTYPE_PAYLOAD_DATAVALUE &&
51057 contentType != UA_PUBSUB_OFFSETTYPE_PAYLOAD_VARIANT &&
51058 contentType != UA_PUBSUB_OFFSETTYPE_PAYLOAD_RAW);
51059 UA_assert(fieldPos < wg->bufferedMessage.offsetsSize);
51060
51061 if(!dsf->config.field.variable.rtValueSource.rtFieldSourceEnabled)
51062 continue;
51063
51064 /* Set the external value soure in the offset buffer */
51065 UA_DataValue_clear(p: &wg->bufferedMessage.offsets[fieldPos].content.value);
51066 wg->bufferedMessage.offsets[fieldPos].content.externalValue =
51067 dsf->config.field.variable.rtValueSource.staticValueSource;
51068
51069 /* Update the content type to _EXTERNAL */
51070 wg->bufferedMessage.offsets[fieldPos].contentType =
51071 (UA_NetworkMessageOffsetType)(contentType + 1);
51072 }
51073 }
51074 }
51075
51076 cleanup:
51077 UA_free(ptr: networkMessage.payload.dataSetPayload.sizes);
51078
51079 cleanup_dsm:
51080 /* Clean up DataSetMessages */
51081 for(size_t i = 0; i < dsmCount; i++) {
51082 UA_DataSetMessage_clear(p: &dsmStore[i]);
51083 }
51084 return res;
51085}
51086
51087UA_StatusCode
51088UA_Server_freezeWriterGroupConfiguration(UA_Server *server,
51089 const UA_NodeId writerGroup) {
51090 lockServer(server);
51091 UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, identifier: writerGroup);
51092 if(!wg) {
51093 unlockServer(server);
51094 return UA_STATUSCODE_BADNOTFOUND;
51095 }
51096 UA_StatusCode res = UA_WriterGroup_freezeConfiguration(server, wg);
51097 unlockServer(server);
51098 return res;
51099}
51100
51101UA_StatusCode
51102UA_WriterGroup_unfreezeConfiguration(UA_Server *server, UA_WriterGroup *wg) {
51103 UA_LOCK_ASSERT(&server->serviceMutex, 1);
51104
51105 /* Already unfrozen */
51106 if(!wg->configurationFrozen)
51107 return UA_STATUSCODE_GOOD;
51108
51109 UA_PubSubConnection *pubSubConnection = wg->linkedConnection;
51110 pubSubConnection->configurationFreezeCounter--;
51111
51112 /* DataSetWriter unfreeze */
51113 UA_DataSetWriter *dsw;
51114 LIST_FOREACH(dsw, &wg->writers, listEntry) {
51115 UA_DataSetWriter_unfreezeConfiguration(server, dsw);
51116 }
51117
51118 UA_NetworkMessageOffsetBuffer_clear(nmob: &wg->bufferedMessage);
51119 wg->configurationFrozen = false;
51120
51121 return UA_STATUSCODE_GOOD;
51122}
51123
51124UA_StatusCode
51125UA_Server_unfreezeWriterGroupConfiguration(UA_Server *server,
51126 const UA_NodeId writerGroup) {
51127 lockServer(server);
51128 UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, identifier: writerGroup);
51129 if(!wg) {
51130 unlockServer(server);
51131 return UA_STATUSCODE_BADNOTFOUND;
51132 }
51133 UA_StatusCode res = UA_WriterGroup_unfreezeConfiguration(server, wg);
51134 unlockServer(server);
51135 return res;
51136}
51137
51138UA_StatusCode
51139UA_Server_setWriterGroupOperational(UA_Server *server,
51140 const UA_NodeId writerGroup) {
51141 lockServer(server);
51142 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
51143 UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, identifier: writerGroup);
51144 if(wg) {
51145#ifdef UA_ENABLE_PUBSUB_SKS
51146 if(wg->keyStorage && wg->keyStorage->currentItem) {
51147 res = UA_PubSubKeyStorage_activateKeyToChannelContext(
51148 server, wg->identifier, wg->config.securityGroupId);
51149 if(res != UA_STATUSCODE_GOOD) {
51150 unlockServer(server);
51151 return res;
51152 }
51153 }
51154#endif
51155
51156 res = UA_WriterGroup_setPubSubState(server, writerGroup: wg, state: UA_PUBSUBSTATE_OPERATIONAL,
51157 UA_STATUSCODE_GOOD);
51158 }
51159 unlockServer(server);
51160 return res;
51161}
51162
51163UA_StatusCode
51164UA_Server_setWriterGroupDisabled(UA_Server *server,
51165 const UA_NodeId writerGroup) {
51166 lockServer(server);
51167 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
51168 UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, identifier: writerGroup);
51169 if(wg)
51170 res = UA_WriterGroup_setPubSubState(server, writerGroup: wg, state: UA_PUBSUBSTATE_DISABLED,
51171 UA_STATUSCODE_BADRESOURCEUNAVAILABLE);
51172 unlockServer(server);
51173 return res;
51174}
51175
51176UA_StatusCode
51177UA_WriterGroupConfig_copy(const UA_WriterGroupConfig *src,
51178 UA_WriterGroupConfig *dst) {
51179 UA_StatusCode res = UA_STATUSCODE_GOOD;
51180 memcpy(dest: dst, src: src, n: sizeof(UA_WriterGroupConfig));
51181 res |= UA_String_copy(src: &src->name, dst: &dst->name);
51182 res |= UA_ExtensionObject_copy(src: &src->transportSettings, dst: &dst->transportSettings);
51183 res |= UA_ExtensionObject_copy(src: &src->messageSettings, dst: &dst->messageSettings);
51184 res |= UA_KeyValueMap_copy(src: &src->groupProperties, dst: &dst->groupProperties);
51185#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
51186 res |= UA_String_copy(&src->securityGroupId, &dst->securityGroupId);
51187#endif
51188 if(res != UA_STATUSCODE_GOOD)
51189 UA_WriterGroupConfig_clear(writerGroupConfig: dst);
51190 return res;
51191}
51192
51193UA_StatusCode
51194UA_Server_getWriterGroupConfig(UA_Server *server, const UA_NodeId writerGroup,
51195 UA_WriterGroupConfig *config) {
51196 if(!config)
51197 return UA_STATUSCODE_BADINVALIDARGUMENT;
51198 lockServer(server);
51199 UA_WriterGroup *currentWG = UA_WriterGroup_findWGbyId(server, identifier: writerGroup);
51200 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
51201 if(currentWG)
51202 res = UA_WriterGroupConfig_copy(src: &currentWG->config, dst: config);
51203 unlockServer(server);
51204 return res;
51205}
51206
51207UA_StatusCode
51208UA_WriterGroup_updateConfig(UA_Server *server, UA_WriterGroup *wg,
51209 const UA_WriterGroupConfig *config) {
51210 UA_StatusCode res = UA_STATUSCODE_GOOD;
51211 if(!config)
51212 return UA_STATUSCODE_BADINVALIDARGUMENT;
51213
51214 if(wg->configurationFrozen){
51215 UA_LOG_WARNING_WRITERGROUP(server->config.logging, wg,
51216 "Modify WriterGroup failed. WriterGroup is frozen.");
51217 return UA_STATUSCODE_BADCONFIGURATIONERROR;
51218 }
51219
51220 //The update functionality will be extended during the next PubSub batches.
51221 //Currently is only a change of the publishing interval possible.
51222 if(wg->config.maxEncapsulatedDataSetMessageCount != config->maxEncapsulatedDataSetMessageCount) {
51223 wg->config.maxEncapsulatedDataSetMessageCount = config->maxEncapsulatedDataSetMessageCount;
51224 if(wg->config.messageSettings.encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY) {
51225 UA_LOG_WARNING_WRITERGROUP(server->config.logging, wg,
51226 "MaxEncapsulatedDataSetMessag need enabled "
51227 "'PayloadHeader' within the message settings.");
51228 }
51229 }
51230
51231 if(wg->config.publishingInterval != config->publishingInterval) {
51232 wg->config.publishingInterval = config->publishingInterval;
51233 if(wg->config.rtLevel == UA_PUBSUB_RT_NONE &&
51234 wg->state == UA_PUBSUBSTATE_OPERATIONAL) {
51235 UA_WriterGroup_removePublishCallback(server, wg);
51236 res = UA_WriterGroup_addPublishCallback(server, wg);
51237 if(res != UA_STATUSCODE_GOOD) {
51238 UA_LOG_WARNING_WRITERGROUP(server->config.logging, wg,
51239 "Modify WriterGroup failed. Adding publish callback failed"
51240 "with status code %s", UA_StatusCode_name(res));
51241 return res;
51242 }
51243 }
51244 }
51245
51246 if(wg->config.priority != config->priority) {
51247 UA_LOG_WARNING_WRITERGROUP(server->config.logging, wg,
51248 "Priority parameter is not yet "
51249 "supported for WriterGroup updates");
51250 }
51251
51252 return UA_STATUSCODE_GOOD;
51253}
51254
51255UA_StatusCode
51256UA_Server_updateWriterGroupConfig(UA_Server *server, UA_NodeId writerGroupIdentifier,
51257 const UA_WriterGroupConfig *config) {
51258 lockServer(server);
51259 UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, identifier: writerGroupIdentifier);
51260 if(!wg) {
51261 unlockServer(server);
51262 return UA_STATUSCODE_BADNOTFOUND;
51263 }
51264
51265 UA_StatusCode res = UA_WriterGroup_updateConfig(server, wg, config);
51266 unlockServer(server);
51267 return res;
51268}
51269
51270UA_StatusCode
51271UA_Server_WriterGroup_getState(UA_Server *server, UA_NodeId writerGroupIdentifier,
51272 UA_PubSubState *state) {
51273 if((server == NULL) || (state == NULL))
51274 return UA_STATUSCODE_BADINVALIDARGUMENT;
51275 lockServer(server);
51276 UA_WriterGroup *currentWriterGroup =
51277 UA_WriterGroup_findWGbyId(server, identifier: writerGroupIdentifier);
51278 UA_StatusCode res = UA_STATUSCODE_GOOD;
51279 if(currentWriterGroup) {
51280 *state = currentWriterGroup->state;
51281 } else {
51282 res = UA_STATUSCODE_BADNOTFOUND;
51283 }
51284 unlockServer(server);
51285 return res;
51286}
51287
51288UA_StatusCode
51289UA_Server_WriterGroup_publish(UA_Server *server, const UA_NodeId writerGroupIdentifier){
51290 lockServer(server);
51291
51292 //search WriterGroup ToDo create lookup table for more efficiency
51293 UA_WriterGroup *writerGroup;
51294 writerGroup = UA_WriterGroup_findWGbyId(server, identifier: writerGroupIdentifier);
51295 if(writerGroup == NULL){
51296 unlockServer(server);
51297 return UA_STATUSCODE_BADNOTFOUND;
51298 }
51299 unlockServer(server);
51300 UA_WriterGroup_publishCallback(server, writerGroup);
51301 return UA_STATUSCODE_GOOD;
51302}
51303
51304UA_StatusCode
51305UA_WriterGroup_lastPublishTimestamp(UA_Server *server, const UA_NodeId writerGroupId,
51306 UA_DateTime *timestamp){
51307 lockServer(server);
51308 //search WriterGroup ToDo create lookup table for more efficiency
51309 UA_WriterGroup *writerGroup;
51310 writerGroup = UA_WriterGroup_findWGbyId(server, identifier: writerGroupId);
51311 if(writerGroup == NULL){
51312 unlockServer(server);
51313 return UA_STATUSCODE_BADNOTFOUND;
51314 }
51315 *timestamp = writerGroup->lastPublishTimeStamp;
51316 unlockServer(server);
51317 return UA_STATUSCODE_BADNOTFOUND;
51318}
51319
51320UA_WriterGroup *
51321UA_WriterGroup_findWGbyId(UA_Server *server, UA_NodeId identifier) {
51322 UA_PubSubConnection *tmpConnection;
51323 TAILQ_FOREACH(tmpConnection, &server->pubSubManager.connections, listEntry) {
51324 UA_WriterGroup *tmpWriterGroup;
51325 LIST_FOREACH(tmpWriterGroup, &tmpConnection->writerGroups, listEntry) {
51326 if(UA_NodeId_equal(p1: &identifier, p2: &tmpWriterGroup->identifier))
51327 return tmpWriterGroup;
51328 }
51329 }
51330 return NULL;
51331}
51332
51333#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
51334UA_StatusCode
51335setWriterGroupEncryptionKeys(UA_Server *server, const UA_NodeId writerGroup,
51336 UA_UInt32 securityTokenId,
51337 const UA_ByteString signingKey,
51338 const UA_ByteString encryptingKey,
51339 const UA_ByteString keyNonce) {
51340 UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, writerGroup);
51341 if(!wg)
51342 return UA_STATUSCODE_BADNOTFOUND;
51343 if(wg->config.encodingMimeType == UA_PUBSUB_ENCODING_JSON) {
51344 UA_LOG_WARNING_WRITERGROUP(server->config.logging, wg,
51345 "JSON encoding is enabled. The message security is only defined for the UADP message mapping.");
51346 return UA_STATUSCODE_BADINTERNALERROR;
51347 }
51348 if(!wg->config.securityPolicy) {
51349 UA_LOG_WARNING_WRITERGROUP(server->config.logging, wg,
51350 "No SecurityPolicy configured for the WriterGroup");
51351 return UA_STATUSCODE_BADINTERNALERROR;
51352 }
51353
51354 if(securityTokenId != wg->securityTokenId) {
51355 wg->securityTokenId = securityTokenId;
51356 wg->nonceSequenceNumber = 1;
51357 }
51358
51359 /* Create a new context */
51360 if(!wg->securityPolicyContext) {
51361 return wg->config.securityPolicy->
51362 newContext(wg->config.securityPolicy->policyContext,
51363 &signingKey, &encryptingKey, &keyNonce,
51364 &wg->securityPolicyContext);
51365 }
51366
51367 /* Update the context */
51368 return wg->config.securityPolicy->
51369 setSecurityKeys(wg->securityPolicyContext, &signingKey, &encryptingKey, &keyNonce);
51370}
51371
51372UA_StatusCode
51373UA_Server_setWriterGroupEncryptionKeys(UA_Server *server, const UA_NodeId writerGroup,
51374 UA_UInt32 securityTokenId,
51375 const UA_ByteString signingKey,
51376 const UA_ByteString encryptingKey,
51377 const UA_ByteString keyNonce) {
51378 lockServer(server);
51379 UA_StatusCode res = setWriterGroupEncryptionKeys(server, writerGroup, securityTokenId,
51380 signingKey, encryptingKey, keyNonce);
51381 unlockServer(server);
51382 return res;
51383}
51384#endif
51385
51386void
51387UA_WriterGroupConfig_clear(UA_WriterGroupConfig *writerGroupConfig) {
51388 UA_String_clear(p: &writerGroupConfig->name);
51389 UA_ExtensionObject_clear(p: &writerGroupConfig->transportSettings);
51390 UA_ExtensionObject_clear(p: &writerGroupConfig->messageSettings);
51391 UA_KeyValueMap_clear(map: &writerGroupConfig->groupProperties);
51392#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
51393 UA_String_clear(&writerGroupConfig->securityGroupId);
51394#endif
51395 memset(s: writerGroupConfig, c: 0, n: sizeof(UA_WriterGroupConfig));
51396}
51397
51398UA_StatusCode
51399UA_WriterGroup_setPubSubState(UA_Server *server, UA_WriterGroup *writerGroup,
51400 UA_PubSubState state, UA_StatusCode cause) {
51401 UA_LOCK_ASSERT(&server->serviceMutex, 1);
51402
51403 if(writerGroup->deleteFlag && state != UA_PUBSUBSTATE_DISABLED) {
51404 UA_LOG_WARNING_WRITERGROUP(server->config.logging, writerGroup,
51405 "The WriterGroup is being deleted. Can only be disabled.");
51406 return UA_STATUSCODE_BADINTERNALERROR;
51407 }
51408
51409 UA_StatusCode ret = UA_STATUSCODE_GOOD;
51410 UA_DataSetWriter *dataSetWriter;
51411 UA_PubSubState oldState = writerGroup->state;
51412 switch(state) {
51413 case UA_PUBSUBSTATE_DISABLED:
51414 UA_WriterGroup_disconnect(wg: writerGroup);
51415 switch (writerGroup->state){
51416 case UA_PUBSUBSTATE_DISABLED:
51417 break;
51418 case UA_PUBSUBSTATE_PAUSED:
51419 break;
51420 case UA_PUBSUBSTATE_OPERATIONAL: {
51421 UA_WriterGroup_removePublishCallback(server, wg: writerGroup);
51422 LIST_FOREACH(dataSetWriter, &writerGroup->writers, listEntry) {
51423 UA_DataSetWriter_setPubSubState(server, dataSetWriter,
51424 state: UA_PUBSUBSTATE_DISABLED,
51425 UA_STATUSCODE_BADRESOURCEUNAVAILABLE);
51426 }
51427
51428 writerGroup->state = UA_PUBSUBSTATE_DISABLED;
51429 break;
51430 }
51431 case UA_PUBSUBSTATE_ERROR:
51432 break;
51433 default:
51434 UA_LOG_WARNING_WRITERGROUP(server->config.logging, writerGroup,
51435 "Received unknown PubSub state!");
51436 }
51437 break;
51438 case UA_PUBSUBSTATE_PAUSED:
51439 switch (writerGroup->state) {
51440 case UA_PUBSUBSTATE_DISABLED:
51441 break;
51442 case UA_PUBSUBSTATE_PAUSED:
51443 break;
51444 case UA_PUBSUBSTATE_OPERATIONAL:
51445 break;
51446 case UA_PUBSUBSTATE_ERROR:
51447 break;
51448 default:
51449 UA_LOG_WARNING_WRITERGROUP(server->config.logging, writerGroup,
51450 "Received unknown PubSub state!");
51451 }
51452 break;
51453 case UA_PUBSUBSTATE_OPERATIONAL:
51454 switch (writerGroup->state) {
51455 case UA_PUBSUBSTATE_DISABLED: {
51456 writerGroup->state = UA_PUBSUBSTATE_OPERATIONAL;
51457 UA_WriterGroup_removePublishCallback(server, wg: writerGroup);
51458 LIST_FOREACH(dataSetWriter, &writerGroup->writers, listEntry) {
51459 UA_DataSetWriter_setPubSubState(server, dataSetWriter,
51460 state: UA_PUBSUBSTATE_OPERATIONAL, cause);
51461 }
51462
51463 ret = UA_WriterGroup_connect(server, wg: writerGroup, false);
51464 if(ret != UA_STATUSCODE_GOOD) {
51465 UA_WriterGroup_setPubSubState(server, writerGroup,
51466 state: UA_PUBSUBSTATE_ERROR, cause: ret);
51467 break;
51468 }
51469 ret = UA_WriterGroup_addPublishCallback(server, wg: writerGroup);
51470 if(ret != UA_STATUSCODE_GOOD) {
51471 UA_WriterGroup_setPubSubState(server, writerGroup,
51472 state: UA_PUBSUBSTATE_ERROR, cause: ret);
51473 break;
51474 }
51475 break;
51476 }
51477 case UA_PUBSUBSTATE_PAUSED:
51478 break;
51479 case UA_PUBSUBSTATE_OPERATIONAL:
51480 break;
51481 case UA_PUBSUBSTATE_ERROR:
51482 break;
51483 default:
51484 UA_LOG_WARNING_WRITERGROUP(server->config.logging, writerGroup,
51485 "Received unknown PubSub state!");
51486 }
51487
51488 UA_PubSubConnection *c = writerGroup->linkedConnection;
51489 ret = UA_PubSubConnection_setPubSubState(server, c,
51490 state: UA_PUBSUBSTATE_OPERATIONAL,
51491 UA_STATUSCODE_GOOD);
51492 if(ret != UA_STATUSCODE_GOOD ||
51493 (c->state != UA_PUBSUBSTATE_OPERATIONAL &&
51494 c->state != UA_PUBSUBSTATE_PREOPERATIONAL)) {
51495 UA_LOG_WARNING_WRITERGROUP(server->config.logging, writerGroup,
51496 "Connection not operational");
51497 return UA_STATUSCODE_BADINTERNALERROR;
51498 }
51499 break;
51500 case UA_PUBSUBSTATE_ERROR: {
51501 switch (writerGroup->state){
51502 case UA_PUBSUBSTATE_DISABLED:
51503 break;
51504 case UA_PUBSUBSTATE_PAUSED:
51505 break;
51506 case UA_PUBSUBSTATE_OPERATIONAL: {
51507 UA_WriterGroup_removePublishCallback(server, wg: writerGroup);
51508 LIST_FOREACH(dataSetWriter, &writerGroup->writers, listEntry){
51509 UA_DataSetWriter_setPubSubState(server, dataSetWriter,
51510 state: UA_PUBSUBSTATE_ERROR,
51511 UA_STATUSCODE_GOOD);
51512 }
51513 break;
51514 }
51515 case UA_PUBSUBSTATE_ERROR:
51516 break;
51517 default:
51518 UA_LOG_WARNING_WRITERGROUP(server->config.logging, writerGroup,
51519 "Received unknown PubSub state!");
51520 }
51521 writerGroup->state = UA_PUBSUBSTATE_ERROR;
51522 break;
51523 }
51524 default:
51525 UA_LOG_WARNING_WRITERGROUP(server->config.logging, writerGroup,
51526 "Received unknown PubSub state!");
51527 }
51528
51529 if(state != oldState) {
51530 /* inform application about state change */
51531 UA_ServerConfig *pConfig = &server->config;
51532 if(pConfig->pubSubConfig.stateChangeCallback != 0) {
51533 pConfig->pubSubConfig.
51534 stateChangeCallback(server, &writerGroup->identifier, state, cause);
51535 }
51536 }
51537 return ret;
51538}
51539
51540#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
51541static UA_StatusCode
51542encryptAndSign(UA_WriterGroup *wg, const UA_NetworkMessage *nm,
51543 UA_Byte *signStart, UA_Byte *encryptStart,
51544 UA_Byte *msgEnd) {
51545 UA_StatusCode rv;
51546 void *channelContext = wg->securityPolicyContext;
51547
51548 if(nm->securityHeader.networkMessageEncrypted) {
51549 /* Set the temporary MessageNonce in the SecurityPolicy */
51550 const UA_ByteString nonce = {
51551 (size_t)nm->securityHeader.messageNonceSize,
51552 (UA_Byte*)(uintptr_t)nm->securityHeader.messageNonce
51553 };
51554 rv = wg->config.securityPolicy->setMessageNonce(channelContext, &nonce);
51555 UA_CHECK_STATUS(rv, return rv);
51556
51557 /* The encryption is done in-place, no need to encode again */
51558 UA_ByteString toBeEncrypted =
51559 {(uintptr_t)msgEnd - (uintptr_t)encryptStart, encryptStart};
51560 rv = wg->config.securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm.
51561 encrypt(channelContext, &toBeEncrypted);
51562 UA_CHECK_STATUS(rv, return rv);
51563 }
51564
51565 if(nm->securityHeader.networkMessageSigned) {
51566 UA_ByteString toBeSigned = {(uintptr_t)msgEnd - (uintptr_t)signStart,
51567 signStart};
51568
51569 size_t sigSize = wg->config.securityPolicy->symmetricModule.cryptoModule.
51570 signatureAlgorithm.getLocalSignatureSize(channelContext);
51571 UA_ByteString signature = {sigSize, msgEnd};
51572
51573 rv = wg->config.securityPolicy->symmetricModule.cryptoModule.
51574 signatureAlgorithm.sign(channelContext, &toBeSigned, &signature);
51575 UA_CHECK_STATUS(rv, return rv);
51576 }
51577 return UA_STATUSCODE_GOOD;
51578}
51579#endif
51580
51581static UA_StatusCode
51582encodeNetworkMessage(UA_WriterGroup *wg, UA_NetworkMessage *nm,
51583 UA_ByteString *buf) {
51584 UA_Byte *bufPos = buf->data;
51585 UA_Byte *bufEnd = &buf->data[buf->length];
51586
51587#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
51588 UA_Byte *networkMessageStart = bufPos;
51589#endif
51590 UA_StatusCode rv = UA_NetworkMessage_encodeHeaders(src: nm, bufPos: &bufPos, bufEnd);
51591 UA_CHECK_STATUS(rv, return rv);
51592
51593#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
51594 UA_Byte *payloadStart = bufPos;
51595#endif
51596 rv = UA_NetworkMessage_encodePayload(src: nm, bufPos: &bufPos, bufEnd);
51597 UA_CHECK_STATUS(rv, return rv);
51598
51599 rv = UA_NetworkMessage_encodeFooters(src: nm, bufPos: &bufPos, bufEnd);
51600 UA_CHECK_STATUS(rv, return rv);
51601
51602#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
51603 /* Encrypt and Sign the message */
51604 UA_Byte *footerEnd = bufPos;
51605 rv = encryptAndSign(wg, nm, networkMessageStart, payloadStart, footerEnd);
51606 UA_CHECK_STATUS(rv, return rv);
51607#endif
51608
51609 return UA_STATUSCODE_GOOD;
51610}
51611
51612static void
51613sendNetworkMessageBuffer(UA_Server *server, UA_WriterGroup *wg,
51614 UA_PubSubConnection *connection, uintptr_t connectionId,
51615 UA_ByteString *buffer) {
51616 UA_StatusCode res = connection->cm->
51617 sendWithConnection(connection->cm, connectionId,
51618 &UA_KEYVALUEMAP_NULL, buffer);
51619
51620 /* Failure, set the WriterGroup into an error mode */
51621 if(res != UA_STATUSCODE_GOOD) {
51622 UA_LOG_ERROR_WRITERGROUP(server->config.logging, wg,
51623 "Sending NetworkMessage failed");
51624 UA_WriterGroup_setPubSubState(server, writerGroup: wg, state: UA_PUBSUBSTATE_ERROR, cause: res);
51625 UA_PubSubConnection_setPubSubState(server, c: connection, state: UA_PUBSUBSTATE_ERROR, cause: res);
51626 return;
51627 }
51628
51629 /* Sending successful - increase the sequence number */
51630 wg->sequenceNumber++;
51631}
51632
51633#ifdef UA_ENABLE_JSON_ENCODING
51634static UA_StatusCode
51635sendNetworkMessageJson(UA_Server *server, UA_PubSubConnection *connection, UA_WriterGroup *wg,
51636 UA_DataSetMessage *dsm, UA_UInt16 *writerIds, UA_Byte dsmCount) {
51637 /* Prepare the NetworkMessage */
51638 UA_NetworkMessage nm;
51639 memset(s: &nm, c: 0, n: sizeof(UA_NetworkMessage));
51640 nm.version = 1;
51641 nm.networkMessageType = UA_NETWORKMESSAGE_DATASET;
51642 nm.payloadHeaderEnabled = true;
51643 nm.payloadHeader.dataSetPayloadHeader.count = dsmCount;
51644 nm.payloadHeader.dataSetPayloadHeader.dataSetWriterIds = writerIds;
51645 nm.payload.dataSetPayload.dataSetMessages = dsm;
51646 nm.publisherIdEnabled = true;
51647 nm.publisherIdType = connection->config.publisherIdType;
51648 nm.publisherId = connection->config.publisherId;
51649
51650 /* Compute the message length */
51651 size_t msgSize = UA_NetworkMessage_calcSizeJson(src: &nm, NULL, namespaceSize: 0, NULL, serverUriSize: 0, true);
51652
51653 UA_ConnectionManager *cm = connection->cm;
51654 if(!cm)
51655 return UA_STATUSCODE_BADINTERNALERROR;
51656
51657 /* Select the wg sendchannel if configured */
51658 uintptr_t sendChannel = connection->sendChannel;
51659 if(wg->sendChannel != 0)
51660 sendChannel = wg->sendChannel;
51661 if(sendChannel == 0) {
51662 UA_LOG_ERROR_WRITERGROUP(server->config.logging, wg,
51663 "Cannot send, no open connection");
51664 return UA_STATUSCODE_BADINTERNALERROR;
51665 }
51666
51667 /* Allocate the buffer */
51668 UA_ByteString buf;
51669 UA_StatusCode res = cm->allocNetworkBuffer(cm, sendChannel, &buf, msgSize);
51670 UA_CHECK_STATUS(res, return res);
51671
51672 /* Encode the message */
51673 UA_Byte *bufPos = buf.data;
51674 const UA_Byte *bufEnd = &buf.data[msgSize];
51675 res = UA_NetworkMessage_encodeJson(src: &nm, bufPos: &bufPos, bufEnd: &bufEnd, NULL, namespaceSize: 0, NULL, serverUriSize: 0, true);
51676 if(res != UA_STATUSCODE_GOOD) {
51677 cm->freeNetworkBuffer(cm, sendChannel, &buf);
51678 return res;
51679 }
51680 UA_assert(bufPos == bufEnd);
51681
51682 /* Send the prepared messages */
51683 sendNetworkMessageBuffer(server, wg, connection, connectionId: sendChannel, buffer: &buf);
51684 return UA_STATUSCODE_GOOD;
51685}
51686#endif
51687
51688static UA_StatusCode
51689generateNetworkMessage(UA_PubSubConnection *connection, UA_WriterGroup *wg,
51690 UA_DataSetMessage *dsm, UA_UInt16 *writerIds, UA_Byte dsmCount,
51691 UA_ExtensionObject *messageSettings,
51692 UA_ExtensionObject *transportSettings,
51693 UA_NetworkMessage *networkMessage) {
51694 if(messageSettings->content.decoded.type !=
51695 &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE])
51696 return UA_STATUSCODE_BADINTERNALERROR;
51697 UA_UadpWriterGroupMessageDataType *wgm = (UA_UadpWriterGroupMessageDataType*)
51698 messageSettings->content.decoded.data;
51699
51700 networkMessage->publisherIdEnabled =
51701 ((u64)wgm->networkMessageContentMask &
51702 (u64)UA_UADPNETWORKMESSAGECONTENTMASK_PUBLISHERID) != 0;
51703 networkMessage->groupHeaderEnabled =
51704 ((u64)wgm->networkMessageContentMask &
51705 (u64)UA_UADPNETWORKMESSAGECONTENTMASK_GROUPHEADER) != 0;
51706 networkMessage->groupHeader.writerGroupIdEnabled =
51707 ((u64)wgm->networkMessageContentMask &
51708 (u64)UA_UADPNETWORKMESSAGECONTENTMASK_WRITERGROUPID) != 0;
51709 networkMessage->groupHeader.groupVersionEnabled =
51710 ((u64)wgm->networkMessageContentMask &
51711 (u64)UA_UADPNETWORKMESSAGECONTENTMASK_GROUPVERSION) != 0;
51712 networkMessage->groupHeader.networkMessageNumberEnabled =
51713 ((u64)wgm->networkMessageContentMask &
51714 (u64)UA_UADPNETWORKMESSAGECONTENTMASK_NETWORKMESSAGENUMBER) != 0;
51715 networkMessage->groupHeader.sequenceNumberEnabled =
51716 ((u64)wgm->networkMessageContentMask &
51717 (u64)UA_UADPNETWORKMESSAGECONTENTMASK_SEQUENCENUMBER) != 0;
51718 networkMessage->payloadHeaderEnabled =
51719 ((u64)wgm->networkMessageContentMask &
51720 (u64)UA_UADPNETWORKMESSAGECONTENTMASK_PAYLOADHEADER) != 0;
51721 networkMessage->timestampEnabled =
51722 ((u64)wgm->networkMessageContentMask &
51723 (u64)UA_UADPNETWORKMESSAGECONTENTMASK_TIMESTAMP) != 0;
51724 networkMessage->picosecondsEnabled =
51725 ((u64)wgm->networkMessageContentMask &
51726 (u64)UA_UADPNETWORKMESSAGECONTENTMASK_PICOSECONDS) != 0;
51727 networkMessage->dataSetClassIdEnabled =
51728 ((u64)wgm->networkMessageContentMask &
51729 (u64)UA_UADPNETWORKMESSAGECONTENTMASK_DATASETCLASSID) != 0;
51730 networkMessage->promotedFieldsEnabled =
51731 ((u64)wgm->networkMessageContentMask &
51732 (u64)UA_UADPNETWORKMESSAGECONTENTMASK_PROMOTEDFIELDS) != 0;
51733
51734 /* Set the SecurityHeader */
51735#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
51736 if(wg->config.securityMode > UA_MESSAGESECURITYMODE_NONE) {
51737 networkMessage->securityEnabled = true;
51738 networkMessage->securityHeader.networkMessageSigned = true;
51739 if(wg->config.securityMode >= UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
51740 networkMessage->securityHeader.networkMessageEncrypted = true;
51741 networkMessage->securityHeader.securityTokenId = wg->securityTokenId;
51742
51743 /* Generate the MessageNonce. Four random bytes followed by a four-byte
51744 * sequence number */
51745 UA_ByteString nonce = {4, networkMessage->securityHeader.messageNonce};
51746 UA_StatusCode rv = wg->config.securityPolicy->symmetricModule.
51747 generateNonce(wg->config.securityPolicy->policyContext, &nonce);
51748 if(rv != UA_STATUSCODE_GOOD)
51749 return rv;
51750 UA_Byte *pos = &networkMessage->securityHeader.messageNonce[4];
51751 const UA_Byte *end = &networkMessage->securityHeader.messageNonce[8];
51752 UA_UInt32_encodeBinary(&wg->nonceSequenceNumber, &pos, end);
51753 networkMessage->securityHeader.messageNonceSize = 8;
51754 }
51755#endif
51756
51757 networkMessage->version = 1;
51758 networkMessage->networkMessageType = UA_NETWORKMESSAGE_DATASET;
51759 networkMessage->publisherIdType = connection->config.publisherIdType;
51760 /* shallow copy of the PublisherId from connection configuration
51761 -> the configuration needs to be stable during publishing process
51762 -> it must not be cleaned after network message has been sent */
51763 networkMessage->publisherId = connection->config.publisherId;
51764
51765 if(networkMessage->groupHeader.sequenceNumberEnabled)
51766 networkMessage->groupHeader.sequenceNumber = wg->sequenceNumber;
51767
51768 if(networkMessage->groupHeader.groupVersionEnabled)
51769 networkMessage->groupHeader.groupVersion = wgm->groupVersion;
51770
51771 /* Compute the length of the dsm separately for the header */
51772 UA_UInt16 *dsmLengths = (UA_UInt16 *) UA_calloc(nmemb: dsmCount, size: sizeof(UA_UInt16));
51773 if(!dsmLengths)
51774 return UA_STATUSCODE_BADOUTOFMEMORY;
51775 for(UA_Byte i = 0; i < dsmCount; i++)
51776 dsmLengths[i] = (UA_UInt16) UA_DataSetMessage_calcSizeBinary(p: &dsm[i], NULL, currentOffset: 0);
51777
51778 networkMessage->payloadHeader.dataSetPayloadHeader.count = dsmCount;
51779 networkMessage->payloadHeader.dataSetPayloadHeader.dataSetWriterIds = writerIds;
51780 networkMessage->groupHeader.writerGroupId = wg->config.writerGroupId;
51781 /* number of the NetworkMessage inside a PublishingInterval */
51782 networkMessage->groupHeader.networkMessageNumber = 1;
51783 networkMessage->payload.dataSetPayload.sizes = dsmLengths;
51784 networkMessage->payload.dataSetPayload.dataSetMessages = dsm;
51785 return UA_STATUSCODE_GOOD;
51786}
51787
51788static UA_StatusCode
51789sendNetworkMessageBinary(UA_Server *server, UA_PubSubConnection *connection, UA_WriterGroup *wg,
51790 UA_DataSetMessage *dsm, UA_UInt16 *writerIds, UA_Byte dsmCount) {
51791 UA_NetworkMessage nm;
51792 memset(s: &nm, c: 0, n: sizeof(UA_NetworkMessage));
51793
51794 /* Fill the message structure */
51795 UA_StatusCode rv =
51796 generateNetworkMessage(connection, wg, dsm, writerIds, dsmCount,
51797 messageSettings: &wg->config.messageSettings,
51798 transportSettings: &wg->config.transportSettings, networkMessage: &nm);
51799 UA_CHECK_STATUS(rv, return rv);
51800
51801 /* Compute the message size. Add the overhead for the security signature.
51802 * There is no padding and the encryption incurs no size overhead. */
51803 size_t msgSize = UA_NetworkMessage_calcSizeBinary(p: &nm, NULL);
51804#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
51805 if(wg->config.securityMode > UA_MESSAGESECURITYMODE_NONE) {
51806 UA_PubSubSecurityPolicy *sp = wg->config.securityPolicy;
51807 msgSize += sp->symmetricModule.cryptoModule.
51808 signatureAlgorithm.getLocalSignatureSize(sp->policyContext);
51809 }
51810#endif
51811
51812 UA_ConnectionManager *cm = connection->cm;
51813 if(!cm)
51814 return UA_STATUSCODE_BADINTERNALERROR;
51815
51816 /* Select the wg sendchannel if configured */
51817 uintptr_t sendChannel = connection->sendChannel;
51818 if(wg->sendChannel != 0)
51819 sendChannel = wg->sendChannel;
51820 if(sendChannel == 0) {
51821 UA_LOG_ERROR_WRITERGROUP(server->config.logging, wg,
51822 "Cannot send, no open connection");
51823 return UA_STATUSCODE_BADINTERNALERROR;
51824 }
51825
51826 /* Allocate the buffer. Allocate on the stack if the buffer is small. */
51827 UA_ByteString buf = UA_BYTESTRING_NULL;
51828 rv = cm->allocNetworkBuffer(cm, sendChannel, &buf, msgSize);
51829 UA_CHECK_STATUS(rv, return rv);
51830
51831 /* Encode and encrypt the message */
51832 rv = encodeNetworkMessage(wg, nm: &nm, buf: &buf);
51833 if(rv != UA_STATUSCODE_GOOD) {
51834 cm->freeNetworkBuffer(cm, sendChannel, &buf);
51835 UA_free(ptr: nm.payload.dataSetPayload.sizes);
51836 return rv;
51837 }
51838
51839 /* Send out the message */
51840 sendNetworkMessageBuffer(server, wg, connection, connectionId: sendChannel, buffer: &buf);
51841
51842 UA_free(ptr: nm.payload.dataSetPayload.sizes);
51843 return UA_STATUSCODE_GOOD;
51844}
51845
51846static void
51847sampleOffsetPublishingValues(UA_Server *server, UA_WriterGroup *wg) {
51848 lockServer(server);
51849
51850 size_t fieldPos = 0;
51851 UA_DataSetWriter *dsw;
51852 LIST_FOREACH(dsw, &wg->writers, listEntry) {
51853 UA_PublishedDataSet *pds =
51854 UA_PublishedDataSet_findPDSbyId(server, identifier: dsw->connectedDataSet);
51855 if(!pds)
51856 continue;
51857
51858 /* Loop over the fields */
51859 UA_DataSetField *dsf;
51860 TAILQ_FOREACH(dsf, &pds->fields, listEntry) {
51861 /* Get the matching offset table entry */
51862 UA_NetworkMessageOffsetType contentType;
51863 do {
51864 fieldPos++;
51865 contentType = wg->bufferedMessage.offsets[fieldPos].contentType;
51866 } while(contentType != UA_PUBSUB_OFFSETTYPE_PAYLOAD_DATAVALUE &&
51867 contentType != UA_PUBSUB_OFFSETTYPE_PAYLOAD_DATAVALUE_EXTERNAL &&
51868 contentType != UA_PUBSUB_OFFSETTYPE_PAYLOAD_VARIANT &&
51869 contentType != UA_PUBSUB_OFFSETTYPE_PAYLOAD_VARIANT_EXTERNAL &&
51870 contentType != UA_PUBSUB_OFFSETTYPE_PAYLOAD_RAW &&
51871 contentType != UA_PUBSUB_OFFSETTYPE_PAYLOAD_RAW_EXTERNAL);
51872
51873 /* External data source is never sampled, but accessed directly in
51874 * the encoding */
51875 if(contentType == UA_PUBSUB_OFFSETTYPE_PAYLOAD_DATAVALUE_EXTERNAL ||
51876 contentType == UA_PUBSUB_OFFSETTYPE_PAYLOAD_VARIANT_EXTERNAL ||
51877 contentType == UA_PUBSUB_OFFSETTYPE_PAYLOAD_RAW_EXTERNAL)
51878 continue;
51879
51880 /* Sample the value into the offset table */
51881 UA_DataValue *dfv = &wg->bufferedMessage.offsets[fieldPos].content.value;
51882 UA_DataValue_clear(p: dfv);
51883 UA_PubSubDataSetField_sampleValue(server, field: dsf, value: dfv);
51884 }
51885 }
51886
51887 unlockServer(server);
51888}
51889
51890static void
51891publishWithOffsets(UA_Server *server, UA_WriterGroup *writerGroup,
51892 UA_PubSubConnection *connection) {
51893 UA_LOCK_ASSERT(&server->serviceMutex, 1);
51894 UA_assert(writerGroup->configurationFrozen);
51895
51896 /* Fixed size but no direct value access. Sample to get recent values into
51897 * the offset buffer structure. */
51898 if((writerGroup->config.rtLevel & UA_PUBSUB_RT_DIRECT_VALUE_ACCESS) == 0)
51899 sampleOffsetPublishingValues(server, wg: writerGroup);
51900
51901 UA_StatusCode res =
51902 UA_NetworkMessage_updateBufferedMessage(buffer: &writerGroup->bufferedMessage);
51903
51904 if(res != UA_STATUSCODE_GOOD) {
51905 UA_LOG_DEBUG_WRITERGROUP(server->config.logging, writerGroup,
51906 "PubSub sending. Unknown field type.");
51907 return;
51908 }
51909
51910 UA_ByteString *buf = &writerGroup->bufferedMessage.buffer;
51911
51912#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
51913 /* Send the encrypted buffered message if PubSub encryption is enabled */
51914 if(writerGroup->config.securityMode > UA_MESSAGESECURITYMODE_NONE) {
51915 size_t sigSize = writerGroup->config.securityPolicy->symmetricModule.cryptoModule.
51916 signatureAlgorithm.getLocalSignatureSize(writerGroup->securityPolicyContext);
51917
51918 UA_Byte payloadOffset = (UA_Byte)(writerGroup->bufferedMessage.payloadPosition -
51919 writerGroup->bufferedMessage.buffer.data);
51920 memcpy(writerGroup->bufferedMessage.encryptBuffer.data,
51921 writerGroup->bufferedMessage.buffer.data,
51922 writerGroup->bufferedMessage.buffer.length);
51923 res = encryptAndSign(writerGroup, writerGroup->bufferedMessage.nm,
51924 writerGroup->bufferedMessage.encryptBuffer.data,
51925 writerGroup->bufferedMessage.encryptBuffer.data + payloadOffset,
51926 writerGroup->bufferedMessage.encryptBuffer.data +
51927 writerGroup->bufferedMessage.encryptBuffer.length - sigSize);
51928
51929 if(res != UA_STATUSCODE_GOOD) {
51930 UA_LOG_ERROR_WRITERGROUP(server->config.logging, writerGroup,
51931 "PubSub Encryption failed");
51932 return;
51933 }
51934
51935 buf = &writerGroup->bufferedMessage.encryptBuffer;
51936 }
51937#endif
51938
51939 UA_ConnectionManager *cm = connection->cm;
51940 if(!cm)
51941 return;
51942
51943 /* Select the wg sendchannel if configured */
51944 uintptr_t sendChannel = connection->sendChannel;
51945 if(writerGroup->sendChannel != 0)
51946 sendChannel = writerGroup->sendChannel;
51947 if(sendChannel == 0) {
51948 UA_LOG_ERROR_WRITERGROUP(server->config.logging, writerGroup,
51949 "Cannot send, no open connection");
51950 return;
51951 }
51952
51953 /* Copy into the network buffer */
51954 UA_ByteString outBuf;
51955 res = cm->allocNetworkBuffer(cm, sendChannel, &outBuf, buf->length);
51956 if(res != UA_STATUSCODE_GOOD) {
51957 UA_LOG_ERROR_WRITERGROUP(server->config.logging, writerGroup,
51958 "PubSub message memory allocation failed");
51959 return;
51960 }
51961 memcpy(dest: outBuf.data, src: buf->data, n: buf->length);
51962 sendNetworkMessageBuffer(server, wg: writerGroup, connection, connectionId: sendChannel, buffer: &outBuf);
51963}
51964
51965static void
51966sendNetworkMessage(UA_Server *server, UA_WriterGroup *wg, UA_PubSubConnection *connection,
51967 UA_DataSetMessage *dsm, UA_UInt16 *writerIds, UA_Byte dsmCount) {
51968 UA_StatusCode res = UA_STATUSCODE_GOOD;
51969 switch(wg->config.encodingMimeType) {
51970 case UA_PUBSUB_ENCODING_UADP:
51971 res = sendNetworkMessageBinary(server, connection, wg, dsm, writerIds, dsmCount);
51972 break;
51973#ifdef UA_ENABLE_JSON_ENCODING
51974 case UA_PUBSUB_ENCODING_JSON:
51975 res = sendNetworkMessageJson(server, connection, wg, dsm, writerIds, dsmCount);
51976 break;
51977#endif
51978 default:
51979 res = UA_STATUSCODE_BADNOTSUPPORTED;
51980 break;
51981 }
51982
51983 /* If sending failed, disable all writer of the writergroup */
51984 if(res != UA_STATUSCODE_GOOD) {
51985 UA_LOG_ERROR_WRITERGROUP(server->config.logging, wg,
51986 "PubSub Publish: Could not send a NetworkMessage "
51987 "with status code %s", UA_StatusCode_name(res));
51988 UA_WriterGroup_setPubSubState(server, writerGroup: wg, state: UA_PUBSUBSTATE_ERROR, cause: res);
51989 }
51990}
51991
51992/* This callback triggers the collection and publish of NetworkMessages and the
51993 * contained DataSetMessages. */
51994void
51995UA_WriterGroup_publishCallback(UA_Server *server, UA_WriterGroup *writerGroup) {
51996 UA_assert(writerGroup != NULL);
51997 UA_assert(server != NULL);
51998
51999 lockServer(server);
52000
52001 UA_LOG_DEBUG_WRITERGROUP(server->config.logging, writerGroup, "Publish Callback");
52002
52003 /* Find the connection associated with the writer */
52004 UA_PubSubConnection *connection = writerGroup->linkedConnection;
52005 if(!connection) {
52006 UA_LOG_ERROR_WRITERGROUP(server->config.logging, writerGroup,
52007 "Publish failed. PubSubConnection invalid");
52008 UA_WriterGroup_setPubSubState(server, writerGroup, state: UA_PUBSUBSTATE_ERROR,
52009 UA_STATUSCODE_BADNOTCONNECTED);
52010 unlockServer(server);
52011 return;
52012 }
52013
52014 /* Realtime path - update the buffer message and send directly */
52015 if(writerGroup->config.rtLevel & UA_PUBSUB_RT_FIXED_SIZE) {
52016 publishWithOffsets(server, writerGroup, connection);
52017 unlockServer(server);
52018 return;
52019 }
52020
52021 /* Nothing to do? */
52022 if(writerGroup->writersCount == 0) {
52023 unlockServer(server);
52024 return;
52025 }
52026
52027 /* How many DSM can be sent in one NM? */
52028 UA_Byte maxDSM = (UA_Byte)writerGroup->config.maxEncapsulatedDataSetMessageCount;
52029 if(writerGroup->config.maxEncapsulatedDataSetMessageCount > UA_BYTE_MAX)
52030 maxDSM = UA_BYTE_MAX;
52031 if(maxDSM == 0)
52032 maxDSM = 1; /* Send at least one dsm */
52033
52034 /* It is possible to put several DataSetMessages into one NetworkMessage.
52035 * But only if they do not contain promoted fields. NM with promoted fields
52036 * are sent out right away. The others are kept in a buffer for
52037 * "batching". */
52038 size_t dsmCount = 0;
52039 UA_STACKARRAY(UA_UInt16, dsWriterIds, writerGroup->writersCount);
52040 UA_STACKARRAY(UA_DataSetMessage, dsmStore, writerGroup->writersCount);
52041
52042 UA_DataSetWriter *dsw;
52043 LIST_FOREACH(dsw, &writerGroup->writers, listEntry) {
52044 if(dsw->state != UA_PUBSUBSTATE_OPERATIONAL)
52045 continue;
52046
52047 /* Heartbeats are send when no dataset is attached */
52048 UA_Boolean heartbeat = UA_NodeId_isNull(p: &dsw->connectedDataSet);
52049 UA_PublishedDataSet *pds = (heartbeat) ? NULL :
52050 UA_PublishedDataSet_findPDSbyId(server, identifier: dsw->connectedDataSet);
52051 if(!heartbeat && !pds) {
52052 UA_LOG_ERROR_WRITER(server->config.logging, dsw,
52053 "PubSub Publish: PublishedDataSet not found");
52054 UA_DataSetWriter_setPubSubState(server, dataSetWriter: dsw, state: UA_PUBSUBSTATE_ERROR,
52055 UA_STATUSCODE_BADINTERNALERROR);
52056 continue;
52057 }
52058
52059 /* Generate the DSM */
52060 dsWriterIds[dsmCount] = dsw->config.dataSetWriterId;
52061 UA_StatusCode res =
52062 UA_DataSetWriter_generateDataSetMessage(server, dataSetMessage: &dsmStore[dsmCount], dataSetWriter: dsw);
52063 if(res != UA_STATUSCODE_GOOD) {
52064 UA_LOG_ERROR_WRITER(server->config.logging, dsw,
52065 "PubSub Publish: DataSetMessage creation failed");
52066 UA_DataSetWriter_setPubSubState(server, dataSetWriter: dsw, state: UA_PUBSUBSTATE_ERROR, cause: res);
52067 continue;
52068 }
52069
52070 /* There is no promoted field -> send right away */
52071 if(pds && pds->promotedFieldsCount > 0) {
52072 writerGroup->lastPublishTimeStamp = UA_DateTime_nowMonotonic();
52073 sendNetworkMessage(server, wg: writerGroup, connection, dsm: &dsmStore[dsmCount],
52074 writerIds: &dsWriterIds[dsmCount], dsmCount: 1);
52075
52076 /* Clean up the current store entry */
52077 if(writerGroup->config.rtLevel & UA_PUBSUB_RT_DIRECT_VALUE_ACCESS &&
52078 dsmStore[dsmCount].header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) {
52079 for(size_t i = 0; i < dsmStore[dsmCount].data.keyFrameData.fieldCount; ++i) {
52080 dsmStore[dsmCount].data.keyFrameData.dataSetFields[i].value.data = NULL;
52081 }
52082 }
52083 UA_DataSetMessage_clear(p: &dsmStore[dsmCount]);
52084
52085 continue; /* Don't increase the dsmCount, reuse the slot */
52086 }
52087
52088 dsmCount++;
52089 }
52090
52091 /* Send the NetworkMessages with batched DataSetMessages */
52092 UA_Byte nmDsmCount = 0;
52093 for(size_t i = 0; i < dsmCount; i += nmDsmCount) {
52094 /* How many dsm are batched in this iteration? */
52095 nmDsmCount = (i + maxDSM > dsmCount) ? (UA_Byte)(dsmCount - i) : maxDSM;
52096
52097 writerGroup->lastPublishTimeStamp = UA_DateTime_nowMonotonic();
52098 /* Send the batched messages */
52099 sendNetworkMessage(server, wg: writerGroup, connection, dsm: &dsmStore[i],
52100 writerIds: &dsWriterIds[i], dsmCount: nmDsmCount);
52101 }
52102
52103 /* Clean up DSM */
52104 for(size_t i = 0; i < dsmCount; i++) {
52105 if(writerGroup->config.rtLevel & UA_PUBSUB_RT_DIRECT_VALUE_ACCESS &&
52106 dsmStore[i].header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) {
52107 for(size_t j = 0; j < dsmStore[i].data.keyFrameData.fieldCount; ++j) {
52108 dsmStore[i].data.keyFrameData.dataSetFields[j].value.data = NULL;
52109 }
52110 }
52111 UA_DataSetMessage_clear(p: &dsmStore[i]);
52112 }
52113
52114 unlockServer(server);
52115}
52116
52117#endif /* UA_ENABLE_PUBSUB */
52118
52119/**** amalgamated original file "/src/pubsub/ua_pubsub_reader.c" ****/
52120
52121/* This Source Code Form is subject to the terms of the Mozilla Public
52122 * License, v. 2.0. If a copy of the MPL was not distributed with this
52123 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
52124 *
52125 * Copyright (c) 2017-2022 Fraunhofer IOSB (Author: Andreas Ebner)
52126 * Copyright (c) 2019 Fraunhofer IOSB (Author: Julius Pfrommer)
52127 * Copyright (c) 2019 Kalycito Infotech Private Limited
52128 * Copyright (c) 2021 Fraunhofer IOSB (Author: Jan Hermes)
52129 * Copyright (c) 2022 Siemens AG (Author: Thomas Fischer)
52130 * Copyright (c) 2022 Fraunhofer IOSB (Author: Noel Graf)
52131 */
52132
52133
52134#ifdef UA_ENABLE_PUBSUB /* conditional compilation */
52135
52136#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
52137#endif
52138
52139
52140#ifdef UA_ENABLE_PUBSUB_BUFMALLOC
52141#endif
52142
52143#ifdef UA_ENABLE_PUBSUB_MONITORING
52144static void
52145UA_DataSetReader_checkMessageReceiveTimeout(UA_Server *server, UA_DataSetReader *dsr);
52146
52147static void
52148UA_DataSetReader_handleMessageReceiveTimeout(UA_Server *server, UA_DataSetReader *dsr);
52149#endif
52150
52151static UA_Boolean
52152publisherIdIsMatching(UA_NetworkMessage *msg, UA_Variant publisherId) {
52153 if(!msg->publisherIdEnabled) {
52154 return true;
52155 }
52156 switch(msg->publisherIdType) {
52157 case UA_PUBLISHERIDTYPE_BYTE:
52158 return (publisherId.type == &UA_TYPES[UA_TYPES_BYTE] &&
52159 msg->publisherId.byte == *(UA_Byte*)publisherId.data);
52160 case UA_PUBLISHERIDTYPE_UINT16:
52161 return (publisherId.type == &UA_TYPES[UA_TYPES_UINT16] &&
52162 msg->publisherId.uint16 == *(UA_UInt16*)publisherId.data);
52163 case UA_PUBLISHERIDTYPE_UINT32:
52164 return (publisherId.type == &UA_TYPES[UA_TYPES_UINT32] &&
52165 msg->publisherId.uint32 == *(UA_UInt32*)publisherId.data);
52166 case UA_PUBLISHERIDTYPE_UINT64:
52167 return (publisherId.type == &UA_TYPES[UA_TYPES_UINT64] &&
52168 msg->publisherId.uint64 == *(UA_UInt64*)publisherId.data);
52169 case UA_PUBLISHERIDTYPE_STRING:
52170 return (publisherId.type == &UA_TYPES[UA_TYPES_STRING] &&
52171 UA_String_equal(p1: &msg->publisherId.string, p2: (UA_String*)publisherId.data));
52172 default:
52173 return false;
52174 }
52175 return true;
52176}
52177
52178UA_StatusCode
52179UA_DataSetReader_checkIdentifier(UA_Server *server, UA_NetworkMessage *msg,
52180 UA_DataSetReader *reader,
52181 UA_ReaderGroupConfig readerGroupConfig) {
52182 if(readerGroupConfig.encodingMimeType != UA_PUBSUB_ENCODING_JSON){
52183 if(!publisherIdIsMatching(msg, publisherId: reader->config.publisherId)) {
52184 return UA_STATUSCODE_BADNOTFOUND;
52185 }
52186 if(msg->groupHeaderEnabled && msg->groupHeader.writerGroupIdEnabled) {
52187 if(reader->config.writerGroupId != msg->groupHeader.writerGroupId) {
52188 UA_LOG_INFO_READER(server->config.logging, reader,
52189 "WriterGroupId doesn't match");
52190 return UA_STATUSCODE_BADNOTFOUND;
52191 }
52192 }
52193 if(msg->payloadHeaderEnabled) {
52194 UA_Byte totalDataSets = msg->payloadHeader.dataSetPayloadHeader.count;
52195 UA_Byte iterator = 0;
52196 for(iterator = 0; iterator < totalDataSets; iterator++) {
52197 if(reader->config.dataSetWriterId == msg->payloadHeader.dataSetPayloadHeader.dataSetWriterIds[iterator]) {
52198 return UA_STATUSCODE_GOOD;
52199 }
52200 }
52201 if (iterator == totalDataSets) {
52202 UA_LOG_INFO_READER(server->config.logging, reader, "DataSetWriterId doesn't match");
52203 return UA_STATUSCODE_BADNOTFOUND;
52204 }
52205 }
52206 return UA_STATUSCODE_GOOD;
52207 } else {
52208 if (!publisherIdIsMatching(msg, publisherId: reader->config.publisherId))
52209 return UA_STATUSCODE_BADNOTFOUND;
52210
52211 if(reader->config.dataSetWriterId == *msg->payloadHeader.dataSetPayloadHeader.dataSetWriterIds) {
52212 UA_LOG_DEBUG(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
52213 msg: "DataSetReader found. Process NetworkMessage");
52214 return UA_STATUSCODE_GOOD;
52215 }
52216 }
52217 return UA_STATUSCODE_BADNOTFOUND;
52218}
52219
52220UA_StatusCode
52221UA_DataSetReader_create(UA_Server *server, UA_NodeId readerGroupIdentifier,
52222 const UA_DataSetReaderConfig *dataSetReaderConfig,
52223 UA_NodeId *readerIdentifier) {
52224 UA_LOCK_ASSERT(&server->serviceMutex, 1);
52225
52226 /* Search the reader group by the given readerGroupIdentifier */
52227 UA_ReaderGroup *readerGroup = UA_ReaderGroup_findRGbyId(server, identifier: readerGroupIdentifier);
52228 if(readerGroup == NULL)
52229 return UA_STATUSCODE_BADNOTFOUND;
52230
52231 if(!dataSetReaderConfig)
52232 return UA_STATUSCODE_BADNOTFOUND;
52233
52234 if(readerGroup->configurationFrozen) {
52235 UA_LOG_WARNING_READERGROUP(server->config.logging, readerGroup,
52236 "Add DataSetReader failed, Subscriber configuration is frozen");
52237 return UA_STATUSCODE_BADCONFIGURATIONERROR;
52238 }
52239
52240 /* Allocate memory for new DataSetReader */
52241 UA_DataSetReader *newDataSetReader = (UA_DataSetReader *)
52242 UA_calloc(nmemb: 1, size: sizeof(UA_DataSetReader));
52243 if(!newDataSetReader)
52244 return UA_STATUSCODE_BADOUTOFMEMORY;
52245
52246 newDataSetReader->componentType = UA_PUBSUB_COMPONENT_DATASETREADER;
52247
52248 /* Copy the config into the new dataSetReader */
52249 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
52250 UA_DataSetReaderConfig_copy(src: dataSetReaderConfig, dst: &newDataSetReader->config);
52251 newDataSetReader->linkedReaderGroup = readerGroup->identifier;
52252
52253#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
52254 retVal = addDataSetReaderRepresentation(server, dataSetReader: newDataSetReader);
52255 if(retVal != UA_STATUSCODE_GOOD) {
52256 UA_LOG_ERROR_READERGROUP(server->config.logging, readerGroup,
52257 "Add DataSetReader failed, addDataSetReaderRepresentation failed");
52258 UA_DataSetReaderConfig_clear(cfg: &newDataSetReader->config);
52259 UA_free(ptr: newDataSetReader);
52260 newDataSetReader = 0;
52261 return retVal;
52262 }
52263#else
52264 UA_PubSubManager_generateUniqueNodeId(&server->pubSubManager,
52265 &newDataSetReader->identifier);
52266#endif
52267
52268#ifdef UA_ENABLE_PUBSUB_MONITORING
52269 /* Create message receive timeout timer */
52270 retVal = server->config.pubSubConfig.monitoringInterface.
52271 createMonitoring(server, newDataSetReader->identifier,
52272 UA_PUBSUB_COMPONENT_DATASETREADER,
52273 UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT,
52274 newDataSetReader,
52275 (void (*)(UA_Server *, void *))
52276 UA_DataSetReader_handleMessageReceiveTimeout);
52277 if(retVal != UA_STATUSCODE_GOOD) {
52278 UA_LOG_ERROR_READERGROUP(server->config.logging, readerGroup,
52279 "Add DataSetReader failed, create message "
52280 "receive timeout timer failed");
52281 UA_DataSetReaderConfig_clear(&newDataSetReader->config);
52282 UA_free(newDataSetReader);
52283 newDataSetReader = 0;
52284 return retVal;
52285 }
52286#endif /* UA_ENABLE_PUBSUB_MONITORING */
52287
52288 /* Add the new reader to the group. Add to the end of the linked list to
52289 * ensure the order for the realtime offsets is as expected. The received
52290 * DataSetMessages are matched via UA_DataSetReader_checkIdentifier for the
52291 * non-RT path. */
52292 UA_DataSetReader *after = LIST_FIRST(&readerGroup->readers);
52293 if(!after) {
52294 LIST_INSERT_HEAD(&readerGroup->readers, newDataSetReader, listEntry);
52295 } else {
52296 while(LIST_NEXT(after, listEntry))
52297 after = LIST_NEXT(after, listEntry);
52298 LIST_INSERT_AFTER(after, newDataSetReader, listEntry);
52299 }
52300 readerGroup->readersCount++;
52301
52302 if(!UA_String_isEmpty(s: &newDataSetReader->config.linkedStandaloneSubscribedDataSetName)) {
52303 // find sds by name
52304 UA_StandaloneSubscribedDataSet *subscribedDataSet =
52305 UA_StandaloneSubscribedDataSet_findSDSbyName(server,
52306 identifier: newDataSetReader->config.linkedStandaloneSubscribedDataSetName);
52307 if(subscribedDataSet != NULL) {
52308 if(subscribedDataSet->config.subscribedDataSetType != UA_PUBSUB_SDS_TARGET) {
52309 UA_LOG_ERROR_READER(server->config.logging, newDataSetReader,
52310 "Not implemented! Currently only SubscribedDataSet as "
52311 "TargetVariables is implemented");
52312 } else {
52313 if(subscribedDataSet->config.isConnected) {
52314 UA_LOG_ERROR_READER(server->config.logging, newDataSetReader,
52315 "SubscribedDataSet is already connected");
52316 } else {
52317 UA_LOG_DEBUG_READER(server->config.logging, newDataSetReader,
52318 "Found SubscribedDataSet");
52319 subscribedDataSet->config.isConnected = true;
52320 UA_DataSetMetaDataType_copy(
52321 src: &subscribedDataSet->config.dataSetMetaData,
52322 dst: &newDataSetReader->config.dataSetMetaData);
52323 UA_FieldTargetVariable *targetVars =
52324 (UA_FieldTargetVariable *)UA_calloc(
52325 nmemb: subscribedDataSet->config.subscribedDataSet.target
52326 .targetVariablesSize,
52327 size: sizeof(UA_FieldTargetVariable));
52328 for(size_t index = 0;
52329 index < subscribedDataSet->config.subscribedDataSet.target
52330 .targetVariablesSize;
52331 index++) {
52332 UA_FieldTargetDataType_copy(
52333 src: &subscribedDataSet->config.subscribedDataSet.target
52334 .targetVariables[index],
52335 dst: &targetVars[index].targetVariable);
52336 }
52337
52338 DataSetReader_createTargetVariables(server, dsr: newDataSetReader,
52339 targetVariablesSize: subscribedDataSet->config.subscribedDataSet.
52340 target.targetVariablesSize, targetVariables: targetVars);
52341 subscribedDataSet->connectedReader = newDataSetReader->identifier;
52342
52343 for(size_t index = 0;
52344 index < subscribedDataSet->config.subscribedDataSet.target
52345 .targetVariablesSize;
52346 index++) {
52347 UA_FieldTargetDataType_clear(p: &targetVars[index].targetVariable);
52348 }
52349
52350 UA_free(ptr: targetVars);
52351
52352#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
52353 connectDataSetReaderToDataSet(server, dsrId: newDataSetReader->identifier,
52354 standaloneSdsId: subscribedDataSet->identifier);
52355#endif
52356 }
52357 }
52358 }
52359 }
52360
52361 if(readerIdentifier)
52362 UA_NodeId_copy(src: &newDataSetReader->identifier, dst: readerIdentifier);
52363
52364 /* Set the ReaderGroup state after finalizing the configuration */
52365 if(readerGroup->state == UA_PUBSUBSTATE_OPERATIONAL ||
52366 readerGroup->state == UA_PUBSUBSTATE_PREOPERATIONAL) {
52367 retVal = UA_DataSetReader_setPubSubState(server, dataSetReader: newDataSetReader, state: readerGroup->state,
52368 UA_STATUSCODE_GOOD);
52369 if(retVal != UA_STATUSCODE_GOOD) {
52370 UA_LOG_ERROR_READERGROUP(server->config.logging, readerGroup,
52371 "Add DataSetReader failed, setPubSubState failed");
52372 }
52373 }
52374
52375
52376 return UA_STATUSCODE_GOOD;
52377}
52378
52379UA_StatusCode
52380UA_Server_addDataSetReader(UA_Server *server, UA_NodeId readerGroupIdentifier,
52381 const UA_DataSetReaderConfig *dataSetReaderConfig,
52382 UA_NodeId *readerIdentifier) {
52383 lockServer(server);
52384 UA_StatusCode res = UA_DataSetReader_create(server, readerGroupIdentifier,
52385 dataSetReaderConfig, readerIdentifier);
52386 unlockServer(server);
52387 return res;
52388}
52389
52390UA_StatusCode
52391UA_DataSetReader_remove(UA_Server *server, UA_DataSetReader *dsr) {
52392 if(dsr->configurationFrozen) {
52393 UA_LOG_WARNING_READER(server->config.logging, dsr,
52394 "Remove DataSetReader failed, "
52395 "Subscriber configuration is frozen");
52396 return UA_STATUSCODE_BADCONFIGURATIONERROR;
52397 }
52398
52399#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
52400 deleteNode(server, nodeId: dsr->identifier, true);
52401#endif
52402
52403#ifdef UA_ENABLE_PUBSUB_MONITORING
52404 /* Stop and remove message receive timeout timer */
52405 UA_StatusCode res = UA_STATUSCODE_GOOD;
52406 if(dsr->msgRcvTimeoutTimerRunning) {
52407 res = server->config.pubSubConfig.monitoringInterface.
52408 stopMonitoring(server, dsr->identifier, UA_PUBSUB_COMPONENT_DATASETREADER,
52409 UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT, dsr);
52410 if(res != UA_STATUSCODE_GOOD) {
52411 UA_LOG_ERROR_READER(server->config.logging, dsr,
52412 "Remove DataSetReader failed. Stop message "
52413 "receive timeout timer of DataSetReader '%.*s' failed.",
52414 (int) dsr->config.name.length, dsr->config.name.data);
52415 }
52416 }
52417
52418 res |= server->config.pubSubConfig.monitoringInterface.
52419 deleteMonitoring(server, dsr->identifier, UA_PUBSUB_COMPONENT_DATASETREADER,
52420 UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT, dsr);
52421 if(res != UA_STATUSCODE_GOOD) {
52422 UA_LOG_ERROR_READER(server->config.logging, dsr,
52423 "Remove DataSetReader failed. Delete message receive "
52424 "timeout timer of DataSetReader '%.*s' failed.",
52425 (int) dsr->config.name.length, dsr->config.name.data);
52426 }
52427#endif /* UA_ENABLE_PUBSUB_MONITORING */
52428 /* check if a Standalone-SubscribedDataSet is associated with this reader and disconnect it*/
52429 if(!UA_String_isEmpty(s: &dsr->config.linkedStandaloneSubscribedDataSetName)) {
52430 UA_StandaloneSubscribedDataSet *subscribedDataSet =
52431 UA_StandaloneSubscribedDataSet_findSDSbyName(
52432 server, identifier: dsr->config.linkedStandaloneSubscribedDataSetName);
52433 if(subscribedDataSet != NULL) {
52434 subscribedDataSet->config.isConnected = false;
52435 }
52436 }
52437
52438 /* Delete DataSetReader config */
52439 UA_DataSetReaderConfig_clear(cfg: &dsr->config);
52440
52441 /* Get the ReaderGroup. This must succeed since all Readers are removed from
52442 * the group before it is deleted in UA_ReaderGroup_remove.*/
52443 UA_ReaderGroup *rg = UA_ReaderGroup_findRGbyId(server, identifier: dsr->linkedReaderGroup);
52444 UA_assert(rg);
52445
52446 /* Remove DataSetReader from group */
52447 LIST_REMOVE(dsr, listEntry);
52448 rg->readersCount--;
52449
52450 /* THe offset buffer is only set when the dsr is frozen
52451 * UA_NetworkMessageOffsetBuffer_clear(&dsr->bufferedMessage); */
52452
52453 UA_NodeId_clear(p: &dsr->identifier);
52454 UA_NodeId_clear(p: &dsr->linkedReaderGroup);
52455
52456 /* Free memory allocated for DataSetReader */
52457 UA_free(ptr: dsr);
52458
52459 return UA_STATUSCODE_GOOD;
52460}
52461
52462UA_StatusCode
52463UA_Server_removeDataSetReader(UA_Server *server, UA_NodeId readerIdentifier) {
52464 lockServer(server);
52465 UA_DataSetReader *dsr = UA_ReaderGroup_findDSRbyId(server, identifier: readerIdentifier);
52466 if(!dsr) {
52467 unlockServer(server);
52468 return UA_STATUSCODE_BADNOTFOUND;
52469 }
52470 UA_StatusCode res = UA_DataSetReader_remove(server, dsr);
52471 unlockServer(server);
52472 return res;
52473}
52474
52475static UA_StatusCode
52476DataSetReader_updateConfig(UA_Server *server, UA_ReaderGroup *rg, UA_DataSetReader *dsr,
52477 const UA_DataSetReaderConfig *config) {
52478 UA_LOCK_ASSERT(&server->serviceMutex, 1);
52479
52480 if(dsr->configurationFrozen) {
52481 UA_LOG_WARNING_READER(server->config.logging, dsr,
52482 "Update DataSetReader config failed. "
52483 "Subscriber configuration is frozen.");
52484 return UA_STATUSCODE_BADCONFIGURATIONERROR;
52485 }
52486
52487 if(rg->configurationFrozen) {
52488 UA_LOG_WARNING_READER(server->config.logging, dsr,
52489 "Update DataSetReader config failed. "
52490 "Subscriber configuration is frozen.");
52491 return UA_STATUSCODE_BADCONFIGURATIONERROR;
52492 }
52493
52494 if(dsr->config.subscribedDataSetType != UA_PUBSUB_SDS_TARGET) {
52495 UA_LOG_WARNING_READER(server->config.logging, dsr,
52496 "Unsupported SubscribedDataSetType.");
52497 return UA_STATUSCODE_BADCONFIGURATIONERROR;
52498 }
52499
52500 /* The update functionality will be extended during the next PubSub batches.
52501 * Currently changes for writerGroupId, dataSetWriterId and TargetVariables are possible. */
52502 if(dsr->config.writerGroupId != config->writerGroupId)
52503 dsr->config.writerGroupId = config->writerGroupId;
52504 if(dsr->config.dataSetWriterId != config->dataSetWriterId)
52505 dsr->config.dataSetWriterId = config->dataSetWriterId;
52506
52507 UA_TargetVariables *oldTV = &dsr->config.subscribedDataSet.subscribedDataSetTarget;
52508 const UA_TargetVariables *newTV = &config->subscribedDataSet.subscribedDataSetTarget;
52509 if(oldTV->targetVariablesSize == newTV->targetVariablesSize) {
52510 for(size_t i = 0; i < newTV->targetVariablesSize; i++) {
52511 if(!UA_NodeId_equal(p1: &oldTV->targetVariables[i].targetVariable.targetNodeId,
52512 p2: &newTV->targetVariables[i].targetVariable.targetNodeId)) {
52513 DataSetReader_createTargetVariables(server, dsr,
52514 targetVariablesSize: newTV->targetVariablesSize,
52515 targetVariables: newTV->targetVariables);
52516 break;
52517 }
52518 }
52519 } else {
52520 DataSetReader_createTargetVariables(server, dsr, targetVariablesSize: newTV->targetVariablesSize,
52521 targetVariables: newTV->targetVariables);
52522 }
52523
52524 UA_StatusCode res = UA_STATUSCODE_GOOD;
52525#ifdef UA_ENABLE_PUBSUB_MONITORING
52526 if(dsr->config.messageReceiveTimeout != config->messageReceiveTimeout) {
52527 /* Update message receive timeout timer interval */
52528 dsr->config.messageReceiveTimeout = config->messageReceiveTimeout;
52529 res = server->config.pubSubConfig.monitoringInterface.
52530 updateMonitoringInterval(server, dsr->identifier,
52531 UA_PUBSUB_COMPONENT_DATASETREADER,
52532 UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT,
52533 dsr);
52534 if(res != UA_STATUSCODE_GOOD) {
52535 UA_LOG_ERROR_READER(server->config.logging, dsr,
52536 "Update DataSetReader message receive timeout timer failed.");
52537 }
52538 }
52539#endif /* UA_ENABLE_PUBSUB_MONITORING */
52540 return res;
52541}
52542
52543UA_StatusCode
52544UA_Server_DataSetReader_updateConfig(UA_Server *server, UA_NodeId dataSetReaderIdentifier,
52545 UA_NodeId readerGroupIdentifier,
52546 const UA_DataSetReaderConfig *config) {
52547 if(config == NULL)
52548 return UA_STATUSCODE_BADINVALIDARGUMENT;
52549
52550 lockServer(server);
52551 UA_DataSetReader *dsr = UA_ReaderGroup_findDSRbyId(server, identifier: dataSetReaderIdentifier);
52552 UA_ReaderGroup *rg = UA_ReaderGroup_findRGbyId(server, identifier: readerGroupIdentifier);
52553 if(!dsr || !rg) {
52554 unlockServer(server);
52555 return UA_STATUSCODE_BADNOTFOUND;
52556 }
52557 UA_StatusCode res = DataSetReader_updateConfig(server, rg, dsr, config);
52558 unlockServer(server);
52559 return res;
52560}
52561
52562UA_StatusCode
52563UA_Server_DataSetReader_getConfig(UA_Server *server, UA_NodeId dataSetReaderIdentifier,
52564 UA_DataSetReaderConfig *config) {
52565 if(!config)
52566 return UA_STATUSCODE_BADINVALIDARGUMENT;
52567 lockServer(server);
52568 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
52569 UA_DataSetReader *dsr = UA_ReaderGroup_findDSRbyId(server, identifier: dataSetReaderIdentifier);
52570 if(dsr)
52571 res = UA_DataSetReaderConfig_copy(src: &dsr->config, dst: config);
52572 unlockServer(server);
52573 return res;
52574}
52575
52576UA_StatusCode
52577UA_DataSetReaderConfig_copy(const UA_DataSetReaderConfig *src,
52578 UA_DataSetReaderConfig *dst) {
52579 memset(s: dst, c: 0, n: sizeof(UA_DataSetReaderConfig));
52580 UA_StatusCode retVal = UA_String_copy(src: &src->name, dst: &dst->name);
52581 if(retVal != UA_STATUSCODE_GOOD)
52582 return retVal;
52583
52584 retVal = UA_Variant_copy(src: &src->publisherId, dst: &dst->publisherId);
52585 if(retVal != UA_STATUSCODE_GOOD)
52586 return retVal;
52587
52588 dst->writerGroupId = src->writerGroupId;
52589 dst->dataSetWriterId = src->dataSetWriterId;
52590 dst->expectedEncoding = src->expectedEncoding;
52591 retVal = UA_DataSetMetaDataType_copy(src: &src->dataSetMetaData, dst: &dst->dataSetMetaData);
52592 if(retVal != UA_STATUSCODE_GOOD)
52593 return retVal;
52594
52595 dst->dataSetFieldContentMask = src->dataSetFieldContentMask;
52596 dst->messageReceiveTimeout = src->messageReceiveTimeout;
52597
52598 retVal = UA_ExtensionObject_copy(src: &src->messageSettings, dst: &dst->messageSettings);
52599 if(retVal != UA_STATUSCODE_GOOD)
52600 return retVal;
52601
52602 retVal = UA_ExtensionObject_copy(src: &src->transportSettings, dst: &dst->transportSettings);
52603 if(retVal != UA_STATUSCODE_GOOD)
52604 return retVal;
52605
52606 if(src->subscribedDataSetType == UA_PUBSUB_SDS_TARGET) {
52607 retVal = UA_TargetVariables_copy(src: &src->subscribedDataSet.subscribedDataSetTarget,
52608 dst: &dst->subscribedDataSet.subscribedDataSetTarget);
52609 if(retVal != UA_STATUSCODE_GOOD) {
52610 return retVal;
52611 }
52612 }
52613
52614 retVal = UA_String_copy(src: &src->linkedStandaloneSubscribedDataSetName, dst: &dst->linkedStandaloneSubscribedDataSetName);
52615
52616 return retVal;
52617}
52618
52619void
52620UA_DataSetReaderConfig_clear(UA_DataSetReaderConfig *cfg) {
52621 UA_String_clear(p: &cfg->name);
52622 UA_String_clear(p: &cfg->linkedStandaloneSubscribedDataSetName);
52623 UA_Variant_clear(p: &cfg->publisherId);
52624 UA_DataSetMetaDataType_clear(p: &cfg->dataSetMetaData);
52625 UA_ExtensionObject_clear(p: &cfg->messageSettings);
52626 UA_ExtensionObject_clear(p: &cfg->transportSettings);
52627 if(cfg->subscribedDataSetType == UA_PUBSUB_SDS_TARGET) {
52628 UA_TargetVariables_clear(subscribedDataSetTarget: &cfg->subscribedDataSet.subscribedDataSetTarget);
52629 }
52630}
52631
52632UA_StatusCode
52633UA_Server_DataSetReader_getState(UA_Server *server, UA_NodeId dataSetReaderIdentifier,
52634 UA_PubSubState *state) {
52635 if(!server || !state)
52636 return UA_STATUSCODE_BADINVALIDARGUMENT;
52637
52638 lockServer(server);
52639 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
52640 UA_DataSetReader *dsr = UA_ReaderGroup_findDSRbyId(server, identifier: dataSetReaderIdentifier);
52641 if(dsr) {
52642 res = UA_STATUSCODE_GOOD;
52643 *state = dsr->state;
52644 }
52645 unlockServer(server);
52646 return res;
52647}
52648
52649static UA_StatusCode
52650UA_DataSetReader_setState_disabled(UA_Server *server, UA_DataSetReader *dsr) {
52651 UA_StatusCode ret = UA_STATUSCODE_GOOD;
52652 switch(dsr->state) {
52653 case UA_PUBSUBSTATE_DISABLED:
52654 return UA_STATUSCODE_GOOD;
52655 case UA_PUBSUBSTATE_PAUSED:
52656 dsr->state = UA_PUBSUBSTATE_DISABLED;
52657 return UA_STATUSCODE_GOOD;
52658 case UA_PUBSUBSTATE_OPERATIONAL:
52659#ifdef UA_ENABLE_PUBSUB_MONITORING
52660 /* Stop MessageReceiveTimeout timer */
52661 if(dsr->msgRcvTimeoutTimerRunning == true) {
52662 ret = server->config.pubSubConfig.monitoringInterface.
52663 stopMonitoring(server, dsr->identifier,
52664 UA_PUBSUB_COMPONENT_DATASETREADER,
52665 UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT, dsr);
52666 if(ret == UA_STATUSCODE_GOOD) {
52667 dsr->msgRcvTimeoutTimerRunning = false;
52668 } else {
52669 UA_LOG_ERROR_READER(server->config.logging, dsr,
52670 "Disable ReaderGroup failed. Stop message receive "
52671 "timeout timer of DataSetReader '%.*s' failed.",
52672 (int) dsr->config.name.length, dsr->config.name.data);
52673 }
52674 }
52675#endif /* UA_ENABLE_PUBSUB_MONITORING */
52676 if(ret == UA_STATUSCODE_GOOD)
52677 dsr->state = UA_PUBSUBSTATE_DISABLED;
52678 return ret;
52679 case UA_PUBSUBSTATE_ERROR:
52680 break;
52681 default:
52682 UA_LOG_WARNING_READER(server->config.logging, dsr,
52683 "Received unknown PubSub state!");
52684 }
52685 return UA_STATUSCODE_BADINVALIDARGUMENT;
52686}
52687
52688/* State machine methods not part of the open62541 state machine API */
52689UA_StatusCode
52690UA_DataSetReader_setPubSubState(UA_Server *server,
52691 UA_DataSetReader *dataSetReader,
52692 UA_PubSubState state,
52693 UA_StatusCode cause) {
52694 UA_StatusCode ret = UA_STATUSCODE_GOOD;
52695 UA_PubSubState oldState = dataSetReader->state;
52696 switch(state) {
52697 case UA_PUBSUBSTATE_DISABLED:
52698 ret = UA_DataSetReader_setState_disabled(server, dsr: dataSetReader);
52699 break;
52700 case UA_PUBSUBSTATE_PAUSED:
52701 ret = UA_STATUSCODE_BADNOTSUPPORTED;
52702 break;
52703 case UA_PUBSUBSTATE_OPERATIONAL:
52704 case UA_PUBSUBSTATE_PREOPERATIONAL:
52705 case UA_PUBSUBSTATE_ERROR:
52706 dataSetReader->state = state;
52707 break;
52708 default:
52709 UA_LOG_WARNING_READER(server->config.logging, dataSetReader,
52710 "Received unknown PubSub state!");
52711 ret = UA_STATUSCODE_BADINVALIDARGUMENT;
52712 break;
52713 }
52714 if (state != oldState) {
52715 /* inform application about state change */
52716 UA_ServerConfig *config = &server->config;
52717 if(config->pubSubConfig.stateChangeCallback != 0) {
52718 config->pubSubConfig.
52719 stateChangeCallback(server, &dataSetReader->identifier, state, cause);
52720 }
52721 }
52722 return ret;
52723}
52724
52725UA_StatusCode
52726UA_FieldTargetVariable_copy(const UA_FieldTargetVariable *src, UA_FieldTargetVariable *dst) {
52727 /* Do a simple memcpy */
52728 memcpy(dest: dst, src: src, n: sizeof(UA_FieldTargetVariable));
52729 return UA_FieldTargetDataType_copy(src: &src->targetVariable, dst: &dst->targetVariable);
52730}
52731
52732UA_StatusCode
52733UA_TargetVariables_copy(const UA_TargetVariables *src, UA_TargetVariables *dst) {
52734 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
52735 memcpy(dest: dst, src: src, n: sizeof(UA_TargetVariables));
52736 if(src->targetVariablesSize > 0) {
52737 dst->targetVariables = (UA_FieldTargetVariable*)
52738 UA_calloc(nmemb: src->targetVariablesSize, size: sizeof(UA_FieldTargetVariable));
52739 if(!dst->targetVariables)
52740 return UA_STATUSCODE_BADOUTOFMEMORY;
52741 for(size_t i = 0; i < src->targetVariablesSize; i++)
52742 retVal |= UA_FieldTargetVariable_copy(src: &src->targetVariables[i], dst: &dst->targetVariables[i]);
52743 }
52744 return retVal;
52745}
52746
52747void
52748UA_TargetVariables_clear(UA_TargetVariables *subscribedDataSetTarget) {
52749 for(size_t i = 0; i < subscribedDataSetTarget->targetVariablesSize; i++) {
52750 UA_FieldTargetDataType_clear(p: &subscribedDataSetTarget->targetVariables[i].targetVariable);
52751 }
52752 if(subscribedDataSetTarget->targetVariablesSize > 0)
52753 UA_free(ptr: subscribedDataSetTarget->targetVariables);
52754 memset(s: subscribedDataSetTarget, c: 0, n: sizeof(UA_TargetVariables));
52755}
52756
52757/* This Method is used to initially set the SubscribedDataSet to
52758 * TargetVariablesType and to create the list of target Variables of a
52759 * SubscribedDataSetType. */
52760UA_StatusCode
52761DataSetReader_createTargetVariables(UA_Server *server, UA_DataSetReader *dsr,
52762 size_t targetVariablesSize,
52763 const UA_FieldTargetVariable *targetVariables) {
52764 UA_LOCK_ASSERT(&server->serviceMutex, 1);
52765
52766 if(dsr->configurationFrozen) {
52767 UA_LOG_WARNING_READER(server->config.logging, dsr,
52768 "Create Target Variables failed. "
52769 "Subscriber configuration is frozen.");
52770 return UA_STATUSCODE_BADCONFIGURATIONERROR;
52771 }
52772
52773 if(dsr->config.subscribedDataSet.subscribedDataSetTarget.targetVariablesSize > 0)
52774 UA_TargetVariables_clear(subscribedDataSetTarget: &dsr->config.subscribedDataSet.subscribedDataSetTarget);
52775
52776 /* Set subscribed dataset to TargetVariableType */
52777 dsr->config.subscribedDataSetType = UA_PUBSUB_SDS_TARGET;
52778 UA_TargetVariables tmp;
52779 tmp.targetVariablesSize = targetVariablesSize;
52780 tmp.targetVariables = (UA_FieldTargetVariable*)(uintptr_t)targetVariables;
52781 return UA_TargetVariables_copy(src: &tmp, dst: &dsr->config.subscribedDataSet.subscribedDataSetTarget);
52782}
52783
52784UA_StatusCode
52785UA_Server_DataSetReader_createTargetVariables(UA_Server *server,
52786 UA_NodeId dataSetReaderIdentifier,
52787 size_t targetVariablesSize,
52788 const UA_FieldTargetVariable *targetVariables) {
52789 lockServer(server);
52790 UA_DataSetReader *dataSetReader = UA_ReaderGroup_findDSRbyId(server, identifier: dataSetReaderIdentifier);
52791 if(!dataSetReader) {
52792 unlockServer(server);
52793 return UA_STATUSCODE_BADINVALIDARGUMENT;
52794 }
52795 UA_StatusCode res = DataSetReader_createTargetVariables(server, dsr: dataSetReader,
52796 targetVariablesSize, targetVariables);
52797 unlockServer(server);
52798 return res;
52799}
52800
52801/* This functionality of this API will be used in future to create mirror Variables - TODO */
52802/* UA_StatusCode
52803UA_Server_DataSetReader_createDataSetMirror(UA_Server *server, UA_String *parentObjectNodeName,
52804 UA_NodeId dataSetReaderIdentifier) {
52805 if((server == NULL) || (parentNode == NULL)) {
52806 return UA_STATUSCODE_BADINVALIDARGUMENT;
52807 }
52808
52809 UA_StatusCode retval = UA_STATUSCODE_GOOD;
52810 UA_DataSetReader* pDataSetReader = UA_ReaderGroup_findDSRbyId(server, dataSetReaderIdentifier);
52811 if(pDataSetReader == NULL) {
52812 return UA_STATUSCODE_BADINVALIDARGUMENT;
52813 }
52814
52815 if(pDataSetReader->configurationFrozen) {
52816 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_SERVER,
52817 "Add Target Variables failed. Subscriber configuration is frozen.");
52818 return UA_STATUSCODE_BADCONFIGURATIONERROR;
52819 } // TODO: Frozen configuration variable in TargetVariable structure
52820
52821 UA_TargetVariables targetVars;
52822 targetVars.targetVariablesSize = pDataSetReader->config.dataSetMetaData.fieldsSize;
52823 targetVars.targetVariables = (UA_FieldTargetVariable *)
52824 UA_calloc(targetVars.targetVariablesSize, sizeof(UA_FieldTargetVariable));
52825
52826 for(size_t i = 0; i < pDataSetReader->config.dataSetMetaData.fieldsSize; i++) {
52827 UA_VariableAttributes vAttr = UA_VariableAttributes_default;
52828 vAttr.valueRank = pDataSetReader->config.dataSetMetaData.fields[i].valueRank;
52829 if(pDataSetReader->config.dataSetMetaData.fields[i].arrayDimensionsSize > 0) {
52830 retval = UA_Array_copy(pDataSetReader->config.dataSetMetaData.fields[i].arrayDimensions,
52831 pDataSetReader->config.dataSetMetaData.fields[i].arrayDimensionsSize,
52832 (void**)&vAttr.arrayDimensions, &UA_TYPES[UA_TYPES_UINT32]);
52833 if(retval == UA_STATUSCODE_GOOD) {
52834 vAttr.arrayDimensionsSize =
52835 pDataSetReader->config.dataSetMetaData.fields[i].arrayDimensionsSize;
52836 }
52837
52838 }
52839
52840 vAttr.dataType = pDataSetReader->config.dataSetMetaData.fields[i].dataType;
52841
52842 vAttr.accessLevel = UA_ACCESSLEVELMASK_READ;
52843 UA_LocalizedText_copy(&pDataSetReader->config.dataSetMetaData.fields[i].description,
52844 &vAttr.description);
52845 UA_QualifiedName qn;
52846 UA_QualifiedName_init(&qn);
52847 char szTmpName[UA_MAX_SIZENAME];
52848 if(pDataSetReader->config.dataSetMetaData.fields[i].name.length > 0) {
52849 UA_UInt16 slen = UA_MAX_SIZENAME -1;
52850 vAttr.displayName.locale = UA_STRING("en-US");
52851 vAttr.displayName.text = pDataSetReader->config.dataSetMetaData.fields[i].name;
52852 if(pDataSetReader->config.dataSetMetaData.fields[i].name.length < slen) {
52853 slen = (UA_UInt16)pDataSetReader->config.dataSetMetaData.fields[i].name.length;
52854 mp_snprintf(szTmpName, sizeof(szTmpName), "%.*s", (int)slen,
52855 (const char*)pDataSetReader->config.dataSetMetaData.fields[i].name.data);
52856 }
52857
52858 szTmpName[slen] = '\0';
52859 qn = UA_QUALIFIEDNAME(1, szTmpName);
52860 }
52861 else {
52862 strcpy(szTmpName, "SubscribedVariable");
52863 vAttr.displayName = UA_LOCALIZEDTEXT("en-US", szTmpName);
52864 qn = UA_QUALIFIEDNAME(1, "SubscribedVariable");
52865 }
52866
52867 // Add variable to the given parent node
52868 UA_NodeId newNode;
52869 retval = UA_Server_addVariableNode(server, UA_NODEID_NULL, *parentNode,
52870 UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), qn,
52871 UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
52872 vAttr, NULL, &newNode);
52873 if(retval == UA_STATUSCODE_GOOD) {
52874 UA_LOG_INFO(server->config.logging, UA_LOGCATEGORY_USERLAND,
52875 "addVariableNode %s succeeded", szTmpName);
52876 }
52877 else {
52878 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_USERLAND,
52879 "addVariableNode: error 0x%" PRIx32, retval);
52880 }
52881
52882 targetVars.targetVariables[i].targetVariable.attributeId = UA_ATTRIBUTEID_VALUE;
52883 UA_NodeId_copy(&newNode, &targetVars.targetVariables[i].targetVariable.targetNodeId);
52884 UA_NodeId_clear(&newNode);
52885 if(vAttr.arrayDimensionsSize > 0) {
52886 UA_Array_delete(vAttr.arrayDimensions, vAttr.arrayDimensionsSize,
52887 &UA_TYPES[UA_TYPES_UINT32]);
52888 }
52889 }
52890
52891 UA_TargetVariables_clear(&targetVars);
52892 return retval;
52893}*/
52894
52895static void
52896DataSetReader_processRaw(UA_Server *server, UA_ReaderGroup *rg,
52897 UA_DataSetReader *dsr, UA_DataSetMessage* msg) {
52898 UA_LOG_TRACE_READER(server->config.logging, dsr, "Received RAW Frame");
52899 msg->data.keyFrameData.fieldCount = (UA_UInt16)
52900 dsr->config.dataSetMetaData.fieldsSize;
52901
52902 /* Start iteration from beginning of rawFields buffer */
52903 size_t offset = 0;
52904 msg->data.keyFrameData.rawFields.length = 0;
52905 for(size_t i = 0; i < dsr->config.dataSetMetaData.fieldsSize; i++) {
52906 /* TODO The datatype reference should be part of the internal
52907 * pubsub configuration to avoid the time-expensive lookup */
52908 const UA_DataType *type =
52909 UA_findDataTypeWithCustom(typeId: &dsr->config.dataSetMetaData.fields[i].dataType,
52910 customTypes: server->config.customDataTypes);
52911 msg->data.keyFrameData.rawFields.length += type->memSize;
52912 UA_STACKARRAY(UA_Byte, value, type->memSize);
52913 UA_StatusCode res =
52914 UA_decodeBinaryInternal(src: &msg->data.keyFrameData.rawFields,
52915 offset: &offset, dst: value, type, NULL);
52916 if(dsr->config.dataSetMetaData.fields[i].maxStringLength != 0) {
52917 if(type->typeKind == UA_DATATYPEKIND_STRING ||
52918 type->typeKind == UA_DATATYPEKIND_BYTESTRING) {
52919 UA_ByteString *bs = (UA_ByteString *) value;
52920 /* Check if length < maxStringLength, The types ByteString and
52921 * String are equal in their base definition */
52922 size_t lengthDifference =
52923 dsr->config.dataSetMetaData.fields[i].maxStringLength - bs->length;
52924 offset += lengthDifference;
52925 }
52926 }
52927 if(res != UA_STATUSCODE_GOOD) {
52928 UA_LOG_INFO_READER(server->config.logging, dsr,
52929 "Error during Raw-decode KeyFrame field %u: %s",
52930 (unsigned)i, UA_StatusCode_name(res));
52931 return;
52932 }
52933
52934 UA_FieldTargetVariable *tv =
52935 &dsr->config.subscribedDataSet.subscribedDataSetTarget.targetVariables[i];
52936
52937 if(tv->externalDataValue) {
52938 if(tv->beforeWrite)
52939 tv->beforeWrite(server, &dsr->identifier, &dsr->linkedReaderGroup,
52940 &tv->targetVariable.targetNodeId,
52941 tv->targetVariableContext, tv->externalDataValue);
52942 memcpy(dest: (*tv->externalDataValue)->value.data, src: value, n: type->memSize);
52943 if(tv->afterWrite)
52944 tv->afterWrite(server, &dsr->identifier, &dsr->linkedReaderGroup,
52945 &tv->targetVariable.targetNodeId,
52946 tv->targetVariableContext, tv->externalDataValue);
52947 continue; /* No dynamic allocation for fixed-size msg, no need to _clear */
52948 }
52949
52950 UA_WriteValue writeVal;
52951 UA_WriteValue_init(p: &writeVal);
52952 writeVal.attributeId = tv->targetVariable.attributeId;
52953 writeVal.indexRange = tv->targetVariable.receiverIndexRange;
52954 writeVal.nodeId = tv->targetVariable.targetNodeId;
52955 UA_Variant_setScalar(v: &writeVal.value.value, p: value, type);
52956 writeVal.value.hasValue = true;
52957 Operation_Write(server, session: &server->adminSession, NULL, wv: &writeVal, result: &res);
52958 UA_clear(p: value, type);
52959 if(res != UA_STATUSCODE_GOOD) {
52960 UA_LOG_INFO_READER(server->config.logging, dsr,
52961 "Error writing KeyFrame field %u: %s",
52962 (unsigned)i, UA_StatusCode_name(res));
52963 }
52964 }
52965}
52966
52967void
52968UA_DataSetReader_process(UA_Server *server, UA_ReaderGroup *rg,
52969 UA_DataSetReader *dsr, UA_DataSetMessage *msg) {
52970 if(!dsr || !rg || !msg || !server)
52971 return;
52972
52973 UA_LOG_DEBUG_READER(server->config.logging, dsr, "Received a network message");
52974
52975 if(!msg->header.dataSetMessageValid) {
52976 UA_LOG_INFO_READER(server->config.logging, dsr,
52977 "DataSetMessage is discarded: message is not valid");
52978 return;
52979 }
52980
52981 /* TODO: Check ConfigurationVersion */
52982 /* if(msg->header.configVersionMajorVersionEnabled) {
52983 * if(msg->header.configVersionMajorVersion !=
52984 * dsr->config.dataSetMetaData.configurationVersion.majorVersion) {
52985 * UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_SERVER,
52986 * "DataSetMessage is discarded: ConfigurationVersion "
52987 * "MajorVersion does not match");
52988 * return;
52989 * }
52990 * } */
52991
52992 if(msg->header.dataSetMessageType != UA_DATASETMESSAGE_DATAKEYFRAME) {
52993 UA_LOG_WARNING_READER(server->config.logging, dsr,
52994 "DataSetMessage is discarded: Only keyframes are supported");
52995 return;
52996 }
52997
52998#ifdef UA_ENABLE_PUBSUB_MONITORING
52999 UA_DataSetReader_checkMessageReceiveTimeout(server, dsr);
53000#endif
53001
53002 if(dsr->state != UA_PUBSUBSTATE_OPERATIONAL &&
53003 dsr->state != UA_PUBSUBSTATE_PREOPERATIONAL) {
53004 UA_LOG_WARNING_READER(server->config.logging, dsr,
53005 "Received a network message but not operational");
53006 return;
53007 }
53008
53009 /* Process message with raw encoding. We have no field-count information for
53010 * the message. */
53011 if(msg->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) {
53012 DataSetReader_processRaw(server, rg, dsr, msg);
53013 return;
53014 }
53015
53016 /* Received a heartbeat with no fields */
53017 if(msg->data.keyFrameData.fieldCount == 0) {
53018 dsr->lastHeartbeatReceived = UA_DateTime_nowMonotonic();
53019 return;
53020 }
53021
53022 /* Check whether the field count matches the configuration */
53023 size_t fieldCount = msg->data.keyFrameData.fieldCount;
53024 if(dsr->config.dataSetMetaData.fieldsSize != fieldCount) {
53025 UA_LOG_WARNING_READER(server->config.logging, dsr,
53026 "Number of fields does not match the DataSetMetaData configuration");
53027 return;
53028 }
53029
53030 if(dsr->config.subscribedDataSet.subscribedDataSetTarget.targetVariablesSize != fieldCount) {
53031 UA_LOG_WARNING_READER(server->config.logging, dsr,
53032 "Number of fields does not match the TargetVariables configuration");
53033 return;
53034 }
53035
53036 /* Write the message fields. RT has the external data value configured. */
53037 UA_StatusCode res = UA_STATUSCODE_GOOD;
53038 for(size_t i = 0; i < fieldCount; i++) {
53039 UA_DataValue *field = &msg->data.keyFrameData.dataSetFields[i];
53040 if(!field->hasValue)
53041 continue;
53042
53043 UA_FieldTargetVariable *tv =
53044 &dsr->config.subscribedDataSet.subscribedDataSetTarget.targetVariables[i];
53045
53046 /* RT-path: write directly into the target memory */
53047 if(tv->externalDataValue) {
53048 if(field->value.type != (*tv->externalDataValue)->value.type) {
53049 UA_LOG_WARNING_READER(server->config.logging, dsr, "Mismatching type");
53050 continue;
53051 }
53052
53053 if(tv->beforeWrite)
53054 tv->beforeWrite(server, &dsr->identifier, &dsr->linkedReaderGroup,
53055 &tv->targetVariable.targetNodeId,
53056 tv->targetVariableContext, tv->externalDataValue);
53057 memcpy(dest: (*tv->externalDataValue)->value.data,
53058 src: field->value.data, n: field->value.type->memSize);
53059 if(tv->afterWrite)
53060 tv->afterWrite(server, &dsr->identifier, &dsr->linkedReaderGroup,
53061 &tv->targetVariable.targetNodeId,
53062 tv->targetVariableContext, tv->externalDataValue);
53063 continue;
53064 }
53065
53066 /* Write via the Write-Service */
53067 UA_WriteValue writeVal;
53068 UA_WriteValue_init(p: &writeVal);
53069 writeVal.attributeId = tv->targetVariable.attributeId;
53070 writeVal.indexRange = tv->targetVariable.receiverIndexRange;
53071 writeVal.nodeId = tv->targetVariable.targetNodeId;
53072 writeVal.value = *field;
53073 Operation_Write(server, session: &server->adminSession, NULL, wv: &writeVal, result: &res);
53074 if(res != UA_STATUSCODE_GOOD)
53075 UA_LOG_INFO_READER(server->config.logging, dsr,
53076 "Error writing KeyFrame field %u: %s",
53077 (unsigned)i, UA_StatusCode_name(res));
53078 }
53079}
53080
53081#ifdef UA_ENABLE_PUBSUB_MONITORING
53082
53083static void
53084UA_DataSetReader_checkMessageReceiveTimeout(UA_Server *server,
53085 UA_DataSetReader *dsr) {
53086 UA_assert(server != 0);
53087 UA_assert(dsr != 0);
53088
53089 /* If previous reader state was error (because we haven't received messages
53090 * and ran into timeout) we should set the state back to operational */
53091 if(dsr->state == UA_PUBSUBSTATE_ERROR) {
53092 UA_DataSetReader_setPubSubState(server, dsr, UA_PUBSUBSTATE_OPERATIONAL,
53093 UA_STATUSCODE_GOOD);
53094 }
53095
53096 /* Stop message receive timeout timer */
53097 UA_StatusCode res;
53098 if(dsr->msgRcvTimeoutTimerRunning) {
53099 res = server->config.pubSubConfig.monitoringInterface.
53100 stopMonitoring(server, dsr->identifier, UA_PUBSUB_COMPONENT_DATASETREADER,
53101 UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT, dsr);
53102 if(res == UA_STATUSCODE_GOOD) {
53103 dsr->msgRcvTimeoutTimerRunning = false;
53104 } else {
53105 UA_LOG_ERROR_READER(server->config.logging, dsr,
53106 "DataSetReader '%.*s': stop receive timeout timer failed",
53107 (int)dsr->config.name.length, dsr->config.name.data);
53108 UA_DataSetReader_setPubSubState(server, dsr, UA_PUBSUBSTATE_ERROR,
53109 UA_STATUSCODE_BADINTERNALERROR);
53110 }
53111 }
53112
53113 /* Start message receive timeout timer */
53114 res = server->config.pubSubConfig.monitoringInterface.
53115 startMonitoring(server, dsr->identifier, UA_PUBSUB_COMPONENT_DATASETREADER,
53116 UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT, dsr);
53117 if(res == UA_STATUSCODE_GOOD) {
53118 UA_LOG_DEBUG_READER(server->config.logging, dsr,
53119 "Info: DataSetReader '%.*s': start receive timeout timer",
53120 (int)dsr->config.name.length, dsr->config.name.data);
53121 dsr->msgRcvTimeoutTimerRunning = true;
53122 } else {
53123 UA_LOG_ERROR_READER(server->config.logging, dsr,
53124 "Starting Message Receive Timeout timer failed.");
53125 UA_DataSetReader_setPubSubState(server, dsr, UA_PUBSUBSTATE_ERROR,
53126 UA_STATUSCODE_BADINTERNALERROR);
53127 }
53128}
53129
53130/* Timeout callback for DataSetReader MessageReceiveTimeout handling */
53131static void
53132UA_DataSetReader_handleMessageReceiveTimeout(UA_Server *server, UA_DataSetReader *dsr) {
53133 UA_assert(server);
53134 UA_assert(dsr);
53135
53136 if(dsr->componentType != UA_PUBSUB_COMPONENT_DATASETREADER) {
53137 UA_LOG_ERROR_READER(server->config.logging, dsr,
53138 "UA_DataSetReader_handleMessageReceiveTimeout(): "
53139 "input param is not of type DataSetReader");
53140 return;
53141 }
53142
53143 UA_LOG_DEBUG_READER(server->config.logging, dsr,
53144 "UA_DataSetReader_handleMessageReceiveTimeout(): "
53145 "MessageReceiveTimeout occurred at DataSetReader "
53146 "'%.*s': MessageReceiveTimeout = %f Timer Id = %u ",
53147 (int)dsr->config.name.length, dsr->config.name.data,
53148 dsr->config.messageReceiveTimeout,
53149 (UA_UInt32) dsr->msgRcvTimeoutTimerId);
53150
53151 UA_StatusCode res =
53152 UA_DataSetReader_setPubSubState(server, dsr, UA_PUBSUBSTATE_ERROR,
53153 UA_STATUSCODE_BADTIMEOUT);
53154 if(res != UA_STATUSCODE_GOOD) {
53155 UA_LOG_ERROR_READER(server->config.logging, dsr,
53156 "UA_DataSetReader_handleMessageReceiveTimeout(): "
53157 "setting pubsub state failed");
53158 }
53159}
53160#endif /* UA_ENABLE_PUBSUB_MONITORING */
53161
53162static void
53163processMessageWithReader(UA_Server *server, UA_ReaderGroup *readerGroup,
53164 UA_DataSetReader *reader, UA_NetworkMessage *msg) {
53165 UA_Byte totalDataSets = 1;
53166 if(msg->payloadHeaderEnabled)
53167 totalDataSets = msg->payloadHeader.dataSetPayloadHeader.count;
53168
53169 for(UA_Byte i = 0; i < totalDataSets; i++) {
53170 /* Map dataset reader to dataset message since multiple dataset reader
53171 * may read this network message. Otherwise the dataset message may be
53172 * written to the wrong dataset reader. */
53173 if(!msg->payloadHeaderEnabled ||
53174 (reader->config.dataSetWriterId == msg->payloadHeader.dataSetPayloadHeader.dataSetWriterIds[i])) {
53175 UA_LOG_DEBUG_READER(server->config.logging, reader,
53176 "Process Msg with DataSetReader!");
53177 UA_DataSetReader_process(server, rg: readerGroup, dsr: reader,
53178 msg: &msg->payload.dataSetPayload.dataSetMessages[i]);
53179 }
53180 }
53181}
53182
53183UA_Boolean
53184UA_ReaderGroup_process(UA_Server *server, UA_ReaderGroup *readerGroup,
53185 UA_NetworkMessage *nm) {
53186 UA_Boolean processed = false;
53187 UA_DataSetReader *reader;
53188
53189 /* Received a (first) message for the ReaderGroup.
53190 * Transition from PreOperational to Operational. */
53191 if(readerGroup->state == UA_PUBSUBSTATE_PREOPERATIONAL) {
53192 readerGroup->state = UA_PUBSUBSTATE_OPERATIONAL;
53193 UA_ServerConfig *config = &server->config;
53194 if(config->pubSubConfig.stateChangeCallback != 0) {
53195 config->pubSubConfig.stateChangeCallback(server, &readerGroup->identifier,
53196 readerGroup->state, UA_STATUSCODE_GOOD);
53197 }
53198 }
53199 LIST_FOREACH(reader, &readerGroup->readers, listEntry) {
53200 UA_StatusCode res =
53201 UA_DataSetReader_checkIdentifier(server, msg: nm, reader, readerGroupConfig: readerGroup->config);
53202 if(res != UA_STATUSCODE_GOOD)
53203 continue;
53204 processed = true;
53205 processMessageWithReader(server, readerGroup, reader, msg: nm);
53206 }
53207 return processed;
53208}
53209
53210/********************************************************************************
53211 * Functionality related to decoding, decrypting and processing network messages
53212 * as a subscriber
53213 ********************************************************************************/
53214
53215static UA_StatusCode
53216prepareOffsetBuffer(UA_Server *server, UA_DataSetReader *reader,
53217 UA_ByteString *buf, size_t *pos) {
53218 UA_NetworkMessage *nm = (UA_NetworkMessage*)UA_calloc(nmemb: 1, size: sizeof(UA_NetworkMessage));
53219 if(!nm)
53220 return UA_STATUSCODE_BADOUTOFMEMORY;
53221
53222 /* Decode using the non-rt decoding */
53223 UA_StatusCode rv = UA_NetworkMessage_decodeHeaders(src: buf, offset: pos, dst: nm);
53224 if(rv != UA_STATUSCODE_GOOD) {
53225 UA_NetworkMessage_clear(p: nm);
53226 UA_free(ptr: nm);
53227 return rv;
53228 }
53229 rv |= UA_NetworkMessage_decodePayload(src: buf, offset: pos, dst: nm, customTypes: server->config.customDataTypes, dsm: &reader->config.dataSetMetaData);
53230 rv |= UA_NetworkMessage_decodeFooters(src: buf, offset: pos, dst: nm);
53231 if(rv != UA_STATUSCODE_GOOD) {
53232 UA_NetworkMessage_clear(p: nm);
53233 UA_free(ptr: nm);
53234 return rv;
53235 }
53236
53237 /* Compute and store the offsets necessary to decode */
53238 size_t nmSize = UA_NetworkMessage_calcSizeBinary(p: nm, offsetBuffer: &reader->bufferedMessage);
53239 if(nmSize == 0) {
53240 UA_NetworkMessage_clear(p: nm);
53241 UA_free(ptr: nm);
53242 return UA_STATUSCODE_BADINTERNALERROR;
53243 }
53244
53245 /* Set the offset buffer in the reader */
53246 reader->bufferedMessage.nm = nm;
53247
53248 return rv;
53249}
53250
53251/*******************************/
53252/* Realtime Message Processing */
53253/*******************************/
53254
53255UA_Boolean
53256UA_ReaderGroup_decodeAndProcessRT(UA_Server *server, UA_ReaderGroup *readerGroup,
53257 UA_ByteString *buf) {
53258#ifdef UA_ENABLE_PUBSUB_BUFMALLOC
53259 useMembufAlloc();
53260#endif
53261
53262 size_t i = 0;
53263 size_t pos = 0;
53264 UA_Boolean match = false;
53265 UA_DataSetReader *dsr;
53266 UA_STACKARRAY(UA_Boolean, matches, readerGroup->readersCount);
53267#ifdef __clang_analyzer__
53268 memset(matches, 0, sizeof(UA_Boolean)* readerGroup->readersCount); /* Pacify warning */
53269#endif
53270
53271 /* Decode headers necessary for checking identifier. This can use malloc.
53272 * So enable membufAlloc if you need RT timings. */
53273 UA_NetworkMessage currentNetworkMessage;
53274 memset(s: &currentNetworkMessage, c: 0, n: sizeof(UA_NetworkMessage));
53275 UA_StatusCode rv = UA_NetworkMessage_decodeHeaders(src: buf, offset: &pos, dst: &currentNetworkMessage);
53276 if(rv != UA_STATUSCODE_GOOD) {
53277 UA_LOG_WARNING_READERGROUP(server->config.logging, readerGroup,
53278 "PubSub receive. decoding headers failed");
53279 goto error;
53280 }
53281
53282 /* Check if the message is intended for each reader individually */
53283 LIST_FOREACH(dsr, &readerGroup->readers, listEntry) {
53284 rv = UA_DataSetReader_checkIdentifier(server, msg: &currentNetworkMessage, reader: dsr, readerGroupConfig: readerGroup->config);
53285 matches[i] = (rv == UA_STATUSCODE_GOOD);
53286 i++;
53287 if(rv != UA_STATUSCODE_GOOD) {
53288 UA_LOG_INFO_READER(server->config.logging, dsr,
53289 "PubSub receive. Message intended for a different reader.");
53290 continue;
53291 }
53292 match = true;
53293 }
53294 if(!match)
53295 goto error;
53296 UA_assert(i == readerGroup->readersCount);
53297
53298 /* Decrypt the message once for all readers */
53299#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
53300 /* Keep pos to right after the header */
53301 rv = verifyAndDecryptNetworkMessage(server->config.logging, buf, &pos,
53302 &currentNetworkMessage, readerGroup);
53303 if(rv != UA_STATUSCODE_GOOD) {
53304 UA_LOG_WARNING_READERGROUP(server->config.logging, readerGroup,
53305 "Subscribe failed. verify and decrypt network "
53306 "message failed.");
53307 goto error;
53308 }
53309#endif
53310
53311 /* Reset back to the normal malloc before processing the message.
53312 * Any changes from here may be persisted longer than this.
53313 * The userland (from callbacks) might rely on that. */
53314 UA_NetworkMessage_clear(p: &currentNetworkMessage);
53315#ifdef UA_ENABLE_PUBSUB_BUFMALLOC
53316 useNormalAlloc();
53317#endif
53318
53319 /* Decode message for every reader. If this fails for one reader, abort overall. */
53320 i = 0;
53321 LIST_FOREACH(dsr, &readerGroup->readers, listEntry) {
53322 UA_assert(i < readerGroup->readersCount);
53323 UA_Boolean match = matches[i];
53324 i++;
53325 if(!match)
53326 continue;
53327
53328 pos = 0; /* reset */
53329 if(!dsr->bufferedMessage.nm) {
53330 /* This is the first message being received for the RT fastpath.
53331 * Prepare the offset buffer and set operational. */
53332 rv = prepareOffsetBuffer(server, reader: dsr, buf, pos: &pos);
53333 } else {
53334 /* Decode with offset information and update the networkMessage */
53335 rv = UA_NetworkMessage_updateBufferedNwMessage(buffer: &dsr->bufferedMessage, src: buf, bufferPosition: &pos);
53336 }
53337 if(rv != UA_STATUSCODE_GOOD) {
53338 UA_LOG_INFO_READER(server->config.logging, dsr,
53339 "PubSub decoding failed. Could not decode with "
53340 "status code %s.", UA_StatusCode_name(rv));
53341 return false;
53342 } else if (readerGroup->state == UA_PUBSUBSTATE_PREOPERATIONAL) {
53343 /* If pre-operational, set to operational after the first message was
53344 * processed */
53345 readerGroup->state = UA_PUBSUBSTATE_OPERATIONAL;
53346 UA_ServerConfig *config = &server->config;
53347 if(config->pubSubConfig.stateChangeCallback != 0) {
53348 config->pubSubConfig.stateChangeCallback(server, &readerGroup->identifier,
53349 readerGroup->state, UA_STATUSCODE_GOOD);
53350 }
53351 }
53352 }
53353
53354 /* Process the decoded messages */
53355 i = 0;
53356 LIST_FOREACH(dsr, &readerGroup->readers, listEntry) {
53357 UA_assert(i < readerGroup->readersCount);
53358 UA_Boolean match = matches[i];
53359 i++;
53360 if(!match)
53361 continue;
53362 UA_DataSetReader_process(server, rg: readerGroup, dsr,
53363 msg: dsr->bufferedMessage.nm->payload.dataSetPayload.dataSetMessages);
53364 }
53365
53366 return match;
53367
53368 error:
53369 UA_NetworkMessage_clear(p: &currentNetworkMessage);
53370#ifdef UA_ENABLE_PUBSUB_BUFMALLOC
53371 useNormalAlloc();
53372#endif
53373 return false;
53374}
53375
53376#endif /* UA_ENABLE_PUBSUB */
53377
53378/**** amalgamated original file "/src/pubsub/ua_pubsub_readergroup.c" ****/
53379
53380/* This Source Code Form is subject to the terms of the Mozilla Public
53381 * License, v. 2.0. If a copy of the MPL was not distributed with this
53382 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
53383 *
53384 * Copyright (c) 2017-2018 Fraunhofer IOSB (Author: Andreas Ebner)
53385 * Copyright (c) 2019 Fraunhofer IOSB (Author: Julius Pfrommer)
53386 * Copyright (c) 2019 Kalycito Infotech Private Limited
53387 * Copyright (c) 2021 Fraunhofer IOSB (Author: Jan Hermes)
53388 * Copyright (c) 2022 Linutronix GmbH (Author: Muddasir Shakil)
53389 *
53390 */
53391
53392
53393#ifdef UA_ENABLE_PUBSUB /* conditional compilation */
53394
53395#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
53396#endif
53397
53398UA_ReaderGroup *
53399UA_ReaderGroup_findRGbyId(UA_Server *server, UA_NodeId identifier) {
53400 UA_PubSubConnection *pubSubConnection;
53401 TAILQ_FOREACH(pubSubConnection, &server->pubSubManager.connections, listEntry){
53402 UA_ReaderGroup* readerGroup = NULL;
53403 LIST_FOREACH(readerGroup, &pubSubConnection->readerGroups, listEntry) {
53404 if(UA_NodeId_equal(p1: &identifier, p2: &readerGroup->identifier))
53405 return readerGroup;
53406 }
53407 }
53408 return NULL;
53409}
53410
53411UA_DataSetReader *
53412UA_ReaderGroup_findDSRbyId(UA_Server *server, UA_NodeId identifier) {
53413 UA_PubSubConnection *pubSubConnection;
53414 TAILQ_FOREACH(pubSubConnection, &server->pubSubManager.connections, listEntry){
53415 UA_ReaderGroup* readerGroup = NULL;
53416 LIST_FOREACH(readerGroup, &pubSubConnection->readerGroups, listEntry) {
53417 UA_DataSetReader *tmpReader;
53418 LIST_FOREACH(tmpReader, &readerGroup->readers, listEntry) {
53419 if(UA_NodeId_equal(p1: &tmpReader->identifier, p2: &identifier))
53420 return tmpReader;
53421 }
53422 }
53423 }
53424 return NULL;
53425}
53426
53427/* ReaderGroup Config Handling */
53428
53429UA_StatusCode
53430UA_ReaderGroupConfig_copy(const UA_ReaderGroupConfig *src,
53431 UA_ReaderGroupConfig *dst) {
53432 memcpy(dest: dst, src: src, n: sizeof(UA_ReaderGroupConfig));
53433 UA_StatusCode res = UA_STATUSCODE_GOOD;
53434 res |= UA_String_copy(src: &src->name, dst: &dst->name);
53435 res |= UA_KeyValueMap_copy(src: &src->groupProperties, dst: &dst->groupProperties);
53436 res |= UA_ExtensionObject_copy(src: &src->transportSettings, dst: &dst->transportSettings);
53437#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
53438 res = UA_String_copy(&src->securityGroupId, &dst->securityGroupId);
53439#endif
53440 if(res != UA_STATUSCODE_GOOD)
53441 UA_ReaderGroupConfig_clear(readerGroupConfig: dst);
53442 return res;
53443}
53444
53445void
53446UA_ReaderGroupConfig_clear(UA_ReaderGroupConfig *readerGroupConfig) {
53447 UA_String_clear(p: &readerGroupConfig->name);
53448 UA_KeyValueMap_clear(map: &readerGroupConfig->groupProperties);
53449 UA_ExtensionObject_clear(p: &readerGroupConfig->transportSettings);
53450#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
53451 UA_String_clear(&readerGroupConfig->securityGroupId);
53452#endif
53453}
53454
53455/* ReaderGroup Lifecycle */
53456
53457UA_StatusCode
53458UA_ReaderGroup_create(UA_Server *server, UA_NodeId connectionId,
53459 const UA_ReaderGroupConfig *rgc,
53460 UA_NodeId *readerGroupId) {
53461 /* Check for valid readergroup configuration */
53462 if(!rgc)
53463 return UA_STATUSCODE_BADINVALIDARGUMENT;
53464
53465 /* Search the connection by the given connectionIdentifier */
53466 UA_PubSubConnection *connection =
53467 UA_PubSubConnection_findConnectionbyId(server, connectionIdentifier: connectionId);
53468 if(!connection)
53469 return UA_STATUSCODE_BADNOTFOUND;
53470
53471 if(connection->configurationFreezeCounter > 0) {
53472 UA_LOG_WARNING_CONNECTION(server->config.logging, connection,
53473 "Adding ReaderGroup failed. "
53474 "Connection configuration is frozen.");
53475 return UA_STATUSCODE_BADCONFIGURATIONERROR;
53476 }
53477
53478 /* Allocate memory for new reader group and add settings */
53479 UA_ReaderGroup *newGroup = (UA_ReaderGroup *)UA_calloc(nmemb: 1, size: sizeof(UA_ReaderGroup));
53480 if(!newGroup)
53481 return UA_STATUSCODE_BADOUTOFMEMORY;
53482
53483 newGroup->componentType = UA_PUBSUB_COMPONENT_READERGROUP;
53484
53485 /* Deep copy of the config */
53486 UA_StatusCode retval = UA_ReaderGroupConfig_copy(src: rgc, dst: &newGroup->config);
53487 if(retval != UA_STATUSCODE_GOOD) {
53488 UA_free(ptr: newGroup);
53489 return retval;
53490 }
53491
53492 newGroup->linkedConnection = connection;
53493
53494 /* Add to the connection */
53495 LIST_INSERT_HEAD(&connection->readerGroups, newGroup, listEntry);
53496 connection->readerGroupsSize++;
53497
53498#ifdef UA_ENABLE_PUBSUB_SKS
53499 if(rgc->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
53500 rgc->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
53501 if(!UA_String_isEmpty(&rgc->securityGroupId) && rgc->securityPolicy) {
53502 /* Does the key storage already exist? */
53503 newGroup->keyStorage =
53504 UA_PubSubKeyStorage_findKeyStorage(server, rgc->securityGroupId);
53505
53506 if(!newGroup->keyStorage) {
53507 /* Create a new key storage */
53508 newGroup->keyStorage = (UA_PubSubKeyStorage *)
53509 UA_calloc(1, sizeof(UA_PubSubKeyStorage));
53510 if(!newGroup->keyStorage)
53511 return UA_STATUSCODE_BADOUTOFMEMORY;
53512 retval = UA_PubSubKeyStorage_init(server, newGroup->keyStorage,
53513 &rgc->securityGroupId,
53514 rgc->securityPolicy, 0, 0);
53515 if(retval != UA_STATUSCODE_GOOD) {
53516 UA_ReaderGroupConfig_clear(&newGroup->config);
53517 UA_free(newGroup);
53518 return retval;
53519 }
53520 }
53521
53522 /* Increase the ref count */
53523 newGroup->keyStorage->referenceCount++;
53524 }
53525 }
53526#endif
53527
53528#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
53529 retval |= addReaderGroupRepresentation(server, readerGroup: newGroup);
53530#else
53531 UA_PubSubManager_generateUniqueNodeId(&server->pubSubManager,
53532 &newGroup->identifier);
53533#endif
53534
53535
53536 if(readerGroupId)
53537 UA_NodeId_copy(src: &newGroup->identifier, dst: readerGroupId);
53538
53539 /* Trigger the connection to open a connection */
53540 UA_PubSubConnection_setPubSubState(server, c: connection,
53541 state: connection->state, UA_STATUSCODE_GOOD);
53542
53543 /* If the connection is operational, we still reset the state. We might open
53544 * a different (recv) connection internally when a readergroup is
53545 * present. */
53546 if(connection->state == UA_PUBSUBSTATE_OPERATIONAL ||
53547 connection->state == UA_PUBSUBSTATE_PREOPERATIONAL)
53548 UA_PubSubConnection_setPubSubState(server, c: connection,
53549 state: UA_PUBSUBSTATE_OPERATIONAL, UA_STATUSCODE_GOOD);
53550
53551 return retval;
53552}
53553
53554UA_StatusCode
53555UA_Server_addReaderGroup(UA_Server *server, UA_NodeId connectionIdentifier,
53556 const UA_ReaderGroupConfig *readerGroupConfig,
53557 UA_NodeId *readerGroupIdentifier) {
53558 lockServer(server);
53559 UA_StatusCode res =
53560 UA_ReaderGroup_create(server, connectionId: connectionIdentifier,
53561 rgc: readerGroupConfig, readerGroupId: readerGroupIdentifier);
53562 unlockServer(server);
53563 return res;
53564}
53565
53566UA_StatusCode
53567UA_ReaderGroup_remove(UA_Server *server, UA_ReaderGroup *rg) {
53568 UA_LOCK_ASSERT(&server->serviceMutex, 1);
53569
53570 if(rg->configurationFrozen) {
53571 UA_LOG_WARNING_READERGROUP(server->config.logging, rg,
53572 "Remove ReaderGroup failed. "
53573 "Subscriber configuration is frozen.");
53574 return UA_STATUSCODE_BADCONFIGURATIONERROR;
53575 }
53576
53577 UA_PubSubConnection *connection = rg->linkedConnection;
53578 UA_assert(connection);
53579 if(connection->configurationFreezeCounter > 0) {
53580 UA_LOG_WARNING_READERGROUP(server->config.logging, rg,
53581 "Deleting the ReaderGroup failed. "
53582 "PubSubConnection is frozen.");
53583 return UA_STATUSCODE_BADCONFIGURATIONERROR;
53584 }
53585
53586 /* Disable (and disconnect) and set the deleteFlag. This prevents a
53587 * reconnect and triggers the deletion when the last open socket is
53588 * closed. */
53589 rg->deleteFlag = true;
53590 UA_ReaderGroup_setPubSubState(server, readerGroup: rg, state: UA_PUBSUBSTATE_DISABLED, UA_STATUSCODE_GOOD);
53591
53592 UA_DataSetReader *dsr, *tmp_dsr;
53593 LIST_FOREACH_SAFE(dsr, &rg->readers, listEntry, tmp_dsr) {
53594 UA_DataSetReader_remove(server, dsr);
53595 }
53596
53597#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
53598 if(rg->config.securityPolicy && rg->securityPolicyContext) {
53599 rg->config.securityPolicy->deleteContext(rg->securityPolicyContext);
53600 rg->securityPolicyContext = NULL;
53601 }
53602#endif
53603
53604#ifdef UA_ENABLE_PUBSUB_SKS
53605 if(rg->keyStorage) {
53606 UA_PubSubKeyStorage_detachKeyStorage(server, rg->keyStorage);
53607 rg->keyStorage = NULL;
53608 }
53609#endif
53610
53611 if(rg->recvChannelsSize == 0) {
53612 /* Unlink from the connection */
53613 LIST_REMOVE(rg, listEntry);
53614 connection->readerGroupsSize--;
53615 rg->linkedConnection = NULL;
53616
53617 /* Actually remove the ReaderGroup */
53618#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
53619 deleteNode(server, nodeId: rg->identifier, true);
53620#endif
53621 UA_ReaderGroupConfig_clear(readerGroupConfig: &rg->config);
53622 UA_NodeId_clear(p: &rg->identifier);
53623 UA_free(ptr: rg);
53624 }
53625
53626 /* Update the connection state */
53627 UA_PubSubConnection_setPubSubState(server, c: connection, state: connection->state,
53628 UA_STATUSCODE_GOOD);
53629
53630 return UA_STATUSCODE_GOOD;
53631}
53632
53633UA_StatusCode
53634UA_Server_removeReaderGroup(UA_Server *server, UA_NodeId groupIdentifier) {
53635 lockServer(server);
53636 UA_ReaderGroup* readerGroup =
53637 UA_ReaderGroup_findRGbyId(server, identifier: groupIdentifier);
53638 if(!readerGroup) {
53639 unlockServer(server);
53640 return UA_STATUSCODE_BADNOTFOUND;
53641 }
53642 UA_StatusCode res = UA_ReaderGroup_remove(server, rg: readerGroup);
53643 unlockServer(server);
53644 return res;
53645}
53646
53647UA_StatusCode
53648UA_Server_ReaderGroup_getConfig(UA_Server *server, UA_NodeId readerGroupIdentifier,
53649 UA_ReaderGroupConfig *config) {
53650 if(!config)
53651 return UA_STATUSCODE_BADINVALIDARGUMENT;
53652
53653 lockServer(server);
53654
53655 /* Identify the readergroup through the readerGroupIdentifier */
53656 UA_ReaderGroup *currentReaderGroup =
53657 UA_ReaderGroup_findRGbyId(server, identifier: readerGroupIdentifier);
53658 if(!currentReaderGroup) {
53659 unlockServer(server);
53660 return UA_STATUSCODE_BADNOTFOUND;
53661 }
53662
53663 UA_StatusCode ret =
53664 UA_ReaderGroupConfig_copy(src: &currentReaderGroup->config, dst: config);
53665
53666 unlockServer(server);
53667 return ret;
53668}
53669
53670UA_StatusCode
53671UA_Server_ReaderGroup_getState(UA_Server *server, UA_NodeId readerGroupIdentifier,
53672 UA_PubSubState *state) {
53673 if((server == NULL) || (state == NULL))
53674 return UA_STATUSCODE_BADINVALIDARGUMENT;
53675 lockServer(server);
53676 UA_StatusCode ret = UA_STATUSCODE_BADNOTFOUND;
53677 UA_ReaderGroup *rg =
53678 UA_ReaderGroup_findRGbyId(server, identifier: readerGroupIdentifier);
53679 if(rg) {
53680 *state = rg->state;
53681 ret = UA_STATUSCODE_GOOD;
53682 }
53683 unlockServer(server);
53684 return ret;
53685}
53686
53687/* ReaderGroup State */
53688
53689static UA_StatusCode
53690UA_ReaderGroup_setPubSubState_disable(UA_Server *server,
53691 UA_ReaderGroup *rg,
53692 UA_StatusCode cause) {
53693 /* Disconnect if not already done */
53694 UA_ReaderGroup_disconnect(rg);
53695
53696 UA_DataSetReader *dataSetReader;
53697 switch(rg->state) {
53698 case UA_PUBSUBSTATE_DISABLED:
53699 return UA_STATUSCODE_GOOD;
53700 case UA_PUBSUBSTATE_PAUSED:
53701 break;
53702 case UA_PUBSUBSTATE_OPERATIONAL:
53703 case UA_PUBSUBSTATE_PREOPERATIONAL:
53704 LIST_FOREACH(dataSetReader, &rg->readers, listEntry) {
53705 UA_DataSetReader_setPubSubState(server, dataSetReader,
53706 state: UA_PUBSUBSTATE_DISABLED, cause);
53707 }
53708 rg->state = UA_PUBSUBSTATE_DISABLED;
53709 break;
53710 case UA_PUBSUBSTATE_ERROR:
53711 break;
53712 default:
53713 UA_LOG_WARNING_READERGROUP(server->config.logging, rg,
53714 "Unknown PubSub state!");
53715 return UA_STATUSCODE_BADINTERNALERROR;
53716 }
53717 return UA_STATUSCODE_GOOD;
53718}
53719
53720static UA_StatusCode
53721UA_ReaderGroup_setPubSubState_paused(UA_Server *server,
53722 UA_ReaderGroup *rg,
53723 UA_StatusCode cause) {
53724 UA_LOG_DEBUG_READERGROUP(server->config.logging, rg,
53725 "PubSub state paused is unsupported at the moment!");
53726 (void)cause;
53727 switch(rg->state) {
53728 case UA_PUBSUBSTATE_DISABLED:
53729 break;
53730 case UA_PUBSUBSTATE_PAUSED:
53731 return UA_STATUSCODE_GOOD;
53732 case UA_PUBSUBSTATE_OPERATIONAL:
53733 case UA_PUBSUBSTATE_PREOPERATIONAL:
53734 break;
53735 case UA_PUBSUBSTATE_ERROR:
53736 break;
53737 default:
53738 UA_LOG_WARNING_READERGROUP(server->config.logging, rg, "Unknown PubSub state!");
53739 return UA_STATUSCODE_BADINTERNALERROR;
53740 }
53741 return UA_STATUSCODE_BADNOTSUPPORTED;
53742}
53743
53744static UA_StatusCode
53745UA_ReaderGroup_setPubSubState_operational(UA_Server *server,
53746 UA_ReaderGroup *rg,
53747 UA_StatusCode cause) {
53748 UA_PubSubConnection *pubSubConnection = rg->linkedConnection;
53749 UA_StatusCode ret =
53750 UA_PubSubConnection_setPubSubState(server, c: pubSubConnection,
53751 state: UA_PUBSUBSTATE_OPERATIONAL,
53752 UA_STATUSCODE_GOOD);
53753 if(ret != UA_STATUSCODE_GOOD ||
53754 (pubSubConnection->state != UA_PUBSUBSTATE_OPERATIONAL &&
53755 pubSubConnection->state != UA_PUBSUBSTATE_PREOPERATIONAL)) {
53756 UA_LOG_WARNING_READERGROUP(server->config.logging, rg,
53757 "Connection not operational");
53758 return UA_STATUSCODE_BADINTERNALERROR;
53759 }
53760
53761 /* Connect if the ReaderGroup has dedicated connections */
53762 if(rg->recvChannelsSize == 0)
53763 ret = UA_ReaderGroup_connect(server, rg, false);
53764 if(ret != UA_STATUSCODE_GOOD) {
53765 UA_LOG_ERROR_READERGROUP(server->config.logging, rg, "Could not connect");
53766 UA_PubSubConnection_setPubSubState(server, c: pubSubConnection,
53767 state: UA_PUBSUBSTATE_ERROR, cause: ret);
53768 }
53769
53770 /* Set to preoperational until the first message was received */
53771 if(rg->state != UA_PUBSUBSTATE_OPERATIONAL)
53772 rg->state = UA_PUBSUBSTATE_PREOPERATIONAL;
53773
53774 /* Set all readers operational */
53775 UA_DataSetReader *dsr;
53776 LIST_FOREACH(dsr, &rg->readers, listEntry) {
53777 UA_DataSetReader_setPubSubState(server, dataSetReader: dsr,
53778 state: UA_PUBSUBSTATE_OPERATIONAL, cause);
53779 }
53780
53781 return UA_STATUSCODE_GOOD;
53782}
53783
53784static UA_StatusCode
53785UA_ReaderGroup_setPubSubState_error(UA_Server *server,
53786 UA_ReaderGroup *rg,
53787 UA_StatusCode cause) {
53788 UA_DataSetReader *dataSetReader;
53789 switch(rg->state) {
53790 case UA_PUBSUBSTATE_DISABLED:
53791 break;
53792 case UA_PUBSUBSTATE_PAUSED:
53793 break;
53794 case UA_PUBSUBSTATE_OPERATIONAL:
53795 case UA_PUBSUBSTATE_PREOPERATIONAL:
53796 LIST_FOREACH(dataSetReader, &rg->readers, listEntry){
53797 UA_DataSetReader_setPubSubState(server, dataSetReader, state: UA_PUBSUBSTATE_ERROR,
53798 cause);
53799 }
53800 break;
53801 case UA_PUBSUBSTATE_ERROR:
53802 return UA_STATUSCODE_GOOD;
53803 default:
53804 UA_LOG_WARNING_READERGROUP(server->config.logging, rg, "Unknown PubSub state!");
53805 return UA_STATUSCODE_BADINTERNALERROR;
53806 }
53807 rg->state = UA_PUBSUBSTATE_ERROR;
53808 return UA_STATUSCODE_GOOD;
53809}
53810
53811UA_StatusCode
53812UA_ReaderGroup_setPubSubState(UA_Server *server,
53813 UA_ReaderGroup *readerGroup,
53814 UA_PubSubState state,
53815 UA_StatusCode cause) {
53816 UA_LOCK_ASSERT(&server->serviceMutex, 1);
53817
53818 if(readerGroup->deleteFlag && state != UA_PUBSUBSTATE_DISABLED) {
53819 UA_LOG_WARNING_READERGROUP(server->config.logging, readerGroup,
53820 "The ReaderGroup is being deleted. Can only be disabled.");
53821 return UA_STATUSCODE_BADINTERNALERROR;
53822 }
53823
53824 UA_StatusCode ret = UA_STATUSCODE_BADINVALIDARGUMENT;
53825 UA_PubSubState oldState = readerGroup->state;
53826 switch(state) {
53827 case UA_PUBSUBSTATE_DISABLED:
53828 ret = UA_ReaderGroup_setPubSubState_disable(server, rg: readerGroup, cause);
53829 break;
53830 case UA_PUBSUBSTATE_PAUSED:
53831 ret = UA_ReaderGroup_setPubSubState_paused(server, rg: readerGroup, cause);
53832 break;
53833 case UA_PUBSUBSTATE_OPERATIONAL:
53834 ret = UA_ReaderGroup_setPubSubState_operational(server, rg: readerGroup, cause);
53835 break;
53836 case UA_PUBSUBSTATE_ERROR:
53837 ret = UA_ReaderGroup_setPubSubState_error(server, rg: readerGroup, cause);
53838 break;
53839 default:
53840 UA_LOG_WARNING_READERGROUP(server->config.logging, readerGroup,
53841 "Received unknown PubSub state!");
53842 break;
53843 }
53844
53845 /* inform application about state change */
53846 if(readerGroup->state != oldState) {
53847 UA_ServerConfig *pConfig = &server->config;
53848 if(pConfig->pubSubConfig.stateChangeCallback != 0) {
53849 pConfig->pubSubConfig.
53850 stateChangeCallback(server, &readerGroup->identifier,
53851 readerGroup->state, cause);
53852 }
53853 }
53854 return ret;
53855}
53856
53857UA_StatusCode
53858UA_Server_setReaderGroupOperational(UA_Server *server,
53859 const UA_NodeId readerGroupId) {
53860 lockServer(server);
53861 UA_StatusCode ret = UA_STATUSCODE_BADNOTFOUND;
53862 UA_ReaderGroup *rg = UA_ReaderGroup_findRGbyId(server, identifier: readerGroupId);
53863 if(rg) {
53864#ifdef UA_ENABLE_PUBSUB_SKS
53865 if(rg->keyStorage && rg->keyStorage->currentItem) {
53866 UA_StatusCode retval = UA_PubSubKeyStorage_activateKeyToChannelContext(
53867 server, rg->identifier, rg->config.securityGroupId);
53868 if(retval != UA_STATUSCODE_GOOD) {
53869 unlockServer(server);
53870 return retval;
53871 }
53872 }
53873#endif
53874 ret = UA_ReaderGroup_setPubSubState(server, readerGroup: rg, state: UA_PUBSUBSTATE_OPERATIONAL,
53875 UA_STATUSCODE_GOOD);
53876 }
53877 unlockServer(server);
53878 return ret;
53879}
53880
53881UA_StatusCode
53882UA_Server_setReaderGroupDisabled(UA_Server *server,
53883 const UA_NodeId readerGroupId) {
53884 lockServer(server);
53885 UA_StatusCode ret = UA_STATUSCODE_BADNOTFOUND;
53886 UA_ReaderGroup *rg = UA_ReaderGroup_findRGbyId(server, identifier: readerGroupId);
53887 if(rg)
53888 ret = UA_ReaderGroup_setPubSubState(server, readerGroup: rg, state: UA_PUBSUBSTATE_DISABLED,
53889 UA_STATUSCODE_BADRESOURCEUNAVAILABLE);
53890 unlockServer(server);
53891 return ret;
53892}
53893
53894#ifdef UA_ENABLE_PUBSUB_ENCRYPTION
53895UA_StatusCode
53896setReaderGroupEncryptionKeys(UA_Server *server, const UA_NodeId readerGroup,
53897 UA_UInt32 securityTokenId,
53898 const UA_ByteString signingKey,
53899 const UA_ByteString encryptingKey,
53900 const UA_ByteString keyNonce) {
53901 UA_ReaderGroup *rg = UA_ReaderGroup_findRGbyId(server, readerGroup);
53902 UA_CHECK_MEM(rg, return UA_STATUSCODE_BADNOTFOUND);
53903 if(rg->config.encodingMimeType == UA_PUBSUB_ENCODING_JSON) {
53904 UA_LOG_WARNING_READERGROUP(server->config.logging, rg,
53905 "JSON encoding is enabled. The message security is "
53906 "only defined for the UADP message mapping.");
53907 return UA_STATUSCODE_BADINTERNALERROR;
53908 }
53909 if(!rg->config.securityPolicy) {
53910 UA_LOG_WARNING_READERGROUP(server->config.logging, rg,
53911 "No SecurityPolicy configured for the ReaderGroup");
53912 return UA_STATUSCODE_BADINTERNALERROR;
53913 }
53914
53915 if(securityTokenId != rg->securityTokenId) {
53916 rg->securityTokenId = securityTokenId;
53917 rg->nonceSequenceNumber = 1;
53918 }
53919
53920 /* Create a new context */
53921 if(!rg->securityPolicyContext) {
53922 return rg->config.securityPolicy->
53923 newContext(rg->config.securityPolicy->policyContext,
53924 &signingKey, &encryptingKey, &keyNonce,
53925 &rg->securityPolicyContext);
53926 }
53927
53928 /* Update the context */
53929 return rg->config.securityPolicy->
53930 setSecurityKeys(rg->securityPolicyContext, &signingKey,
53931 &encryptingKey, &keyNonce);
53932}
53933
53934UA_StatusCode
53935UA_Server_setReaderGroupEncryptionKeys(UA_Server *server,
53936 const UA_NodeId readerGroup,
53937 UA_UInt32 securityTokenId,
53938 const UA_ByteString signingKey,
53939 const UA_ByteString encryptingKey,
53940 const UA_ByteString keyNonce) {
53941 lockServer(server);
53942 UA_StatusCode res = setReaderGroupEncryptionKeys(server, readerGroup,
53943 securityTokenId, signingKey,
53944 encryptingKey, keyNonce);
53945 unlockServer(server);
53946 return res;
53947}
53948#endif
53949
53950/* Freezing of the configuration */
53951
53952UA_StatusCode
53953UA_ReaderGroup_freezeConfiguration(UA_Server *server, UA_ReaderGroup *rg) {
53954 UA_LOCK_ASSERT(&server->serviceMutex, 1);
53955 if(rg->configurationFrozen)
53956 return UA_STATUSCODE_GOOD;
53957
53958 /* PubSubConnection freezeCounter++ */
53959 UA_PubSubConnection *pubSubConnection = rg->linkedConnection;
53960 pubSubConnection->configurationFreezeCounter++;
53961
53962 /* ReaderGroup freeze */
53963 /* TODO: Clarify on the freeze functionality in multiple DSR, multiple
53964 * networkMessage conf in a RG */
53965 rg->configurationFrozen = true;
53966
53967 /* DataSetReader freeze */
53968 UA_DataSetReader *dsr;
53969 UA_UInt16 dsrCount = 0;
53970 LIST_FOREACH(dsr, &rg->readers, listEntry){
53971 dsr->configurationFrozen = true;
53972 dsrCount++;
53973 /* TODO: Configuration frozen for subscribedDataSet once
53974 * UA_Server_DataSetReader_addTargetVariables API modified to support
53975 * adding target variable one by one or in a group stored in a list. */
53976 }
53977
53978 /* Not rt, we don't have to adjust anything */
53979 if((rg->config.rtLevel & UA_PUBSUB_RT_FIXED_SIZE) == 0)
53980 return UA_STATUSCODE_GOOD;
53981
53982 if(dsrCount > 1) {
53983 UA_LOG_WARNING_READERGROUP(server->config.logging, rg,
53984 "Multiple DSR in a readerGroup not supported in RT "
53985 "fixed size configuration");
53986 return UA_STATUSCODE_BADNOTIMPLEMENTED;
53987 }
53988
53989 dsr = LIST_FIRST(&rg->readers);
53990
53991 /* Support only to UADP encoding */
53992 if(dsr->config.messageSettings.content.decoded.type !=
53993 &UA_TYPES[UA_TYPES_UADPDATASETREADERMESSAGEDATATYPE]) {
53994 UA_LOG_WARNING_READER(server->config.logging, dsr,
53995 "PubSub-RT configuration fail: Non-RT capable encoding.");
53996 return UA_STATUSCODE_BADNOTSUPPORTED;
53997 }
53998
53999 /* Don't support string PublisherId for the fast-path (at this time) */
54000 if(!dsr->config.publisherId.type->pointerFree) {
54001 UA_LOG_WARNING_READER(server->config.logging, dsr,
54002 "PubSub-RT configuration fail: String PublisherId");
54003 return UA_STATUSCODE_BADNOTSUPPORTED;
54004 }
54005
54006 size_t fieldsSize = dsr->config.dataSetMetaData.fieldsSize;
54007 for(size_t i = 0; i < fieldsSize; i++) {
54008 /* TODO: Use the datasource from the node */
54009 /* UA_FieldTargetVariable *tv = */
54010 /* &dsr->config.subscribedDataSet.subscribedDataSetTarget.targetVariables[i]; */
54011 /* const UA_VariableNode *rtNode = (const UA_VariableNode *) */
54012 /* UA_NODESTORE_GET(server, &tv->targetVariable.targetNodeId); */
54013 /* if(!rtNode || */
54014 /* rtNode->valueBackend.backendType != UA_VALUEBACKENDTYPE_EXTERNAL) { */
54015 /* UA_LOG_WARNING_READER(server->config.logging, dsr, */
54016 /* "PubSub-RT configuration fail: PDS contains field " */
54017 /* "without external data source."); */
54018 /* UA_NODESTORE_RELEASE(server, (const UA_Node *) rtNode); */
54019 /* return UA_STATUSCODE_BADNOTSUPPORTED; */
54020 /* } */
54021
54022 /* /\* Set the external data source in the tv *\/ */
54023 /* tv->externalDataValue = rtNode->valueBackend.backend.external.value; */
54024
54025 /* UA_NODESTORE_RELEASE(server, (const UA_Node *) rtNode); */
54026
54027 UA_FieldMetaData *field = &dsr->config.dataSetMetaData.fields[i];
54028 if((UA_NodeId_equal(p1: &field->dataType, p2: &UA_TYPES[UA_TYPES_STRING].typeId) ||
54029 UA_NodeId_equal(p1: &field->dataType, p2: &UA_TYPES[UA_TYPES_BYTESTRING].typeId)) &&
54030 field->maxStringLength == 0) {
54031 UA_LOG_WARNING_READER(server->config.logging, dsr,
54032 "PubSub-RT configuration fail: "
54033 "PDS contains String/ByteString with dynamic length.");
54034 return UA_STATUSCODE_BADNOTSUPPORTED;
54035 } else if(!UA_DataType_isNumeric(type: UA_findDataType(typeId: &field->dataType)) &&
54036 !UA_NodeId_equal(p1: &field->dataType, p2: &UA_TYPES[UA_TYPES_BOOLEAN].typeId)) {
54037 UA_LOG_WARNING_READER(server->config.logging, dsr,
54038 "PubSub-RT configuration fail: "
54039 "PDS contains variable with dynamic size.");
54040 return UA_STATUSCODE_BADNOTSUPPORTED;
54041 }
54042 }
54043
54044 /* Reset the OffsetBuffer. The OffsetBuffer for a frozen configuration is
54045 * generated when the first message is received. So we know the exact
54046 * settings which headers are present, etc. Until then the ReaderGroup is
54047 * "PreOperational". */
54048 UA_NetworkMessageOffsetBuffer_clear(nmob: &dsr->bufferedMessage);
54049
54050 /* Set the current state again. This can move the state from Operational to
54051 * PreOperational. */
54052 return UA_ReaderGroup_setPubSubState(server, readerGroup: rg, state: rg->state, UA_STATUSCODE_GOOD);
54053}
54054
54055UA_StatusCode
54056UA_Server_freezeReaderGroupConfiguration(UA_Server *server,
54057 const UA_NodeId readerGroupId) {
54058 lockServer(server);
54059 UA_ReaderGroup *rg = UA_ReaderGroup_findRGbyId(server, identifier: readerGroupId);
54060 if(!rg) {
54061 unlockServer(server);
54062 return UA_STATUSCODE_BADNOTFOUND;
54063 }
54064 UA_StatusCode res = UA_ReaderGroup_freezeConfiguration(server, rg);
54065 unlockServer(server);
54066 return res;
54067}
54068
54069UA_StatusCode
54070UA_ReaderGroup_unfreezeConfiguration(UA_Server *server, UA_ReaderGroup *rg) {
54071 UA_LOCK_ASSERT(&server->serviceMutex, 1);
54072
54073 /* Already unfrozen */
54074 if(!rg->configurationFrozen)
54075 return UA_STATUSCODE_GOOD;
54076
54077 /* PubSubConnection freezeCounter-- */
54078 UA_PubSubConnection *pubSubConnection = rg->linkedConnection;
54079 pubSubConnection->configurationFreezeCounter--;
54080
54081 /* ReaderGroup unfreeze */
54082 rg->configurationFrozen = false;
54083
54084 /* DataSetReader unfreeze */
54085 UA_DataSetReader *dataSetReader;
54086 LIST_FOREACH(dataSetReader, &rg->readers, listEntry) {
54087 dataSetReader->configurationFrozen = false;
54088 UA_NetworkMessageOffsetBuffer_clear(nmob: &dataSetReader->bufferedMessage);
54089 }
54090
54091 return UA_STATUSCODE_GOOD;
54092}
54093
54094UA_StatusCode
54095UA_Server_unfreezeReaderGroupConfiguration(UA_Server *server,
54096 const UA_NodeId readerGroupId) {
54097 lockServer(server);
54098 UA_ReaderGroup *rg = UA_ReaderGroup_findRGbyId(server, identifier: readerGroupId);
54099 if(!rg) {
54100 unlockServer(server);
54101 return UA_STATUSCODE_BADNOTFOUND;
54102 }
54103 UA_StatusCode res = UA_ReaderGroup_unfreezeConfiguration(server, rg);
54104 unlockServer(server);
54105 return res;
54106}
54107
54108#endif /* UA_ENABLE_PUBSUB */
54109
54110/**** amalgamated original file "/src/pubsub/ua_pubsub_manager.c" ****/
54111
54112/* This Source Code Form is subject to the terms of the Mozilla Public
54113 * License, v. 2.0. If a copy of the MPL was not distributed with this
54114 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
54115 *
54116 * Copyright (c) 2017-2022 Fraunhofer IOSB (Author: Andreas Ebner)
54117 * Copyright (c) 2018 Fraunhofer IOSB (Author: Julius Pfrommer)
54118 * Copyright (c) 2021 Fraunhofer IOSB (Author: Jan Hermes)
54119 * Copyright (c) 2022 Siemens AG (Author: Thomas Fischer)
54120 * Copyright (c) 2022 Fraunhofer IOSB (Author: Noel Graf)
54121 * Copyright (c) 2022 Linutronix GmbH (Author: Muddasir Shakil)
54122 */
54123
54124
54125#ifdef UA_ENABLE_PUBSUB /* conditional compilation */
54126
54127#ifdef UA_ENABLE_PUBSUB_SKS
54128#endif
54129
54130#define UA_DATETIMESTAMP_2000 125911584000000000
54131#define UA_RESERVEID_FIRST_ID 0x8000
54132
54133static void
54134UA_PubSubManager_addTopic(UA_PubSubManager *pubSubManager, UA_TopicAssign *topicAssign) {
54135 TAILQ_INSERT_TAIL(&pubSubManager->topicAssign, topicAssign, listEntry);
54136 pubSubManager->topicAssignSize++;
54137}
54138
54139static UA_TopicAssign *
54140UA_TopicAssign_new(UA_ReaderGroup *readerGroup,
54141 UA_String topic, const UA_Logger *logger) {
54142 UA_TopicAssign *topicAssign = (UA_TopicAssign *)
54143 UA_calloc(nmemb: 1, size: sizeof(UA_TopicAssign));
54144 if(!topicAssign) {
54145 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SERVER,
54146 msg: "PubSub TopicAssign creation failed. Out of Memory.");
54147 return NULL;
54148 }
54149 topicAssign->rgIdentifier = readerGroup;
54150 topicAssign->topic = topic;
54151 return topicAssign;
54152}
54153
54154UA_StatusCode
54155UA_PubSubManager_addPubSubTopicAssign(UA_Server *server, UA_ReaderGroup *readerGroup, UA_String topic) {
54156 UA_PubSubManager *pubSubManager = &server->pubSubManager;
54157 UA_TopicAssign *topicAssign = UA_TopicAssign_new(readerGroup, topic, logger: server->config.logging);
54158 UA_PubSubManager_addTopic(pubSubManager, topicAssign);
54159 return UA_STATUSCODE_GOOD;
54160}
54161
54162static enum ZIP_CMP
54163cmpReserveId(const void *a, const void *b) {
54164 const UA_ReserveId *aa = (const UA_ReserveId*)a;
54165 const UA_ReserveId *bb = (const UA_ReserveId*)b;
54166 if(aa->id != bb->id)
54167 return (aa->id < bb->id) ? ZIP_CMP_LESS : ZIP_CMP_MORE;
54168 if(aa->reserveIdType != bb->reserveIdType)
54169 return (aa->reserveIdType < bb->reserveIdType) ? ZIP_CMP_LESS : ZIP_CMP_MORE;
54170 return (enum ZIP_CMP)UA_order(p1: &aa->transportProfileUri,
54171 p2: &bb->transportProfileUri, type: &UA_TYPES[UA_TYPES_STRING]);
54172}
54173
54174ZIP_FUNCTIONS(UA_ReserveIdTree, UA_ReserveId, treeEntry, UA_ReserveId, id, cmpReserveId)
54175
54176static UA_ReserveId *
54177UA_ReserveId_new(UA_Server *server, UA_UInt16 id, UA_String transportProfileUri,
54178 UA_ReserveIdType reserveIdType, UA_NodeId sessionId) {
54179 UA_ReserveId *reserveId = (UA_ReserveId *)
54180 UA_calloc(nmemb: 1, size: sizeof(UA_ReserveId));
54181 if(!reserveId) {
54182 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
54183 msg: "PubSub ReserveId creation failed. Out of Memory.");
54184 return NULL;
54185 }
54186 reserveId->id = id;
54187 reserveId->reserveIdType = reserveIdType;
54188 UA_String_copy(src: &transportProfileUri, dst: &reserveId->transportProfileUri);
54189 reserveId->sessionId = sessionId;
54190
54191 return reserveId;
54192}
54193
54194static UA_Boolean
54195UA_ReserveId_isFree(UA_Server *server, UA_UInt16 id,
54196 UA_String transportProfileUri, UA_ReserveIdType reserveIdType) {
54197 UA_PubSubManager *pubSubManager = &server->pubSubManager;
54198
54199 /* Is the id already in use? */
54200 UA_ReserveId compare;
54201 compare.id = id;
54202 compare.reserveIdType = reserveIdType;
54203 compare.transportProfileUri = transportProfileUri;
54204 if(ZIP_FIND(UA_ReserveIdTree, &pubSubManager->reserveIds, &compare))
54205 return false;
54206
54207 UA_PubSubConnection *tmpConnection;
54208 TAILQ_FOREACH(tmpConnection, &server->pubSubManager.connections, listEntry) {
54209 UA_WriterGroup *writerGroup;
54210 LIST_FOREACH(writerGroup, &tmpConnection->writerGroups, listEntry) {
54211 if(reserveIdType == UA_WRITER_GROUP) {
54212 if(UA_String_equal(p1: &tmpConnection->config.transportProfileUri,
54213 p2: &transportProfileUri) &&
54214 writerGroup->config.writerGroupId == id)
54215 return false;
54216 /* reserveIdType == UA_DATA_SET_WRITER */
54217 } else {
54218 UA_DataSetWriter *currentWriter;
54219 LIST_FOREACH(currentWriter, &writerGroup->writers, listEntry) {
54220 if(UA_String_equal(p1: &tmpConnection->config.transportProfileUri,
54221 p2: &transportProfileUri) &&
54222 currentWriter->config.dataSetWriterId == id)
54223 return false;
54224 }
54225 }
54226 }
54227 }
54228 return true;
54229}
54230
54231static UA_UInt16
54232UA_ReserveId_createId(UA_Server *server, UA_NodeId sessionId,
54233 UA_String transportProfileUri, UA_ReserveIdType reserveIdType) {
54234 /* Total number of possible Ids */
54235 UA_UInt16 numberOfIds = 0x8000;
54236 /* Contains next possible free Id */
54237 static UA_UInt16 next_id_writerGroup = UA_RESERVEID_FIRST_ID;
54238 static UA_UInt16 next_id_writer = UA_RESERVEID_FIRST_ID;
54239 UA_UInt16 next_id;
54240 UA_Boolean is_free = false;
54241
54242 if(reserveIdType == UA_WRITER_GROUP)
54243 next_id = next_id_writerGroup;
54244 else
54245 next_id = next_id_writer;
54246
54247 for(;numberOfIds > 0;numberOfIds--) {
54248 if(next_id < UA_RESERVEID_FIRST_ID)
54249 next_id = UA_RESERVEID_FIRST_ID;
54250 is_free = UA_ReserveId_isFree(server, id: next_id, transportProfileUri, reserveIdType);
54251 if(is_free)
54252 break;
54253 next_id++;
54254 }
54255 if(!is_free) {
54256 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
54257 msg: "PubSub ReserveId creation failed. No free ID could be found.");
54258 return 0;
54259 }
54260
54261 if(reserveIdType == UA_WRITER_GROUP)
54262 next_id_writerGroup = (UA_UInt16)(next_id + 1);
54263 else
54264 next_id_writer = (UA_UInt16)(next_id + 1);
54265
54266 UA_ReserveId *reserveId =
54267 UA_ReserveId_new(server, id: next_id, transportProfileUri, reserveIdType, sessionId);
54268 if(!reserveId)
54269 return 0;
54270 UA_PubSubManager *pubSubManager = &server->pubSubManager;
54271 ZIP_INSERT(UA_ReserveIdTree, &pubSubManager->reserveIds, reserveId);
54272 pubSubManager->reserveIdsSize++;
54273 return next_id;
54274}
54275
54276static void *
54277removeReserveId(void *context, UA_ReserveId *elem) {
54278 UA_String_clear(p: &elem->transportProfileUri);
54279 UA_free(ptr: elem);
54280 return NULL;
54281}
54282
54283struct RemoveInactiveReserveIdContext {
54284 UA_Server *server;
54285 UA_ReserveIdTree newTree;
54286};
54287
54288/* Remove ReserveIds that are not attached to any session */
54289static void *
54290removeInactiveReserveId(void *context, UA_ReserveId *elem) {
54291 struct RemoveInactiveReserveIdContext *ctx =
54292 (struct RemoveInactiveReserveIdContext*)context;
54293
54294 if(UA_NodeId_equal(p1: &ctx->server->adminSession.sessionId, p2: &elem->sessionId))
54295 goto still_active;
54296
54297 session_list_entry *session;
54298 LIST_FOREACH(session, &ctx->server->sessions, pointers) {
54299 if(UA_NodeId_equal(p1: &session->session.sessionId, p2: &elem->sessionId))
54300 goto still_active;
54301 }
54302
54303 ctx->server->pubSubManager.reserveIdsSize--;
54304 UA_String_clear(p: &elem->transportProfileUri);
54305 UA_free(ptr: elem);
54306 return NULL;
54307
54308 still_active:
54309 ZIP_INSERT(UA_ReserveIdTree, &ctx->newTree, elem);
54310 return NULL;
54311}
54312
54313void
54314UA_PubSubManager_freeIds(UA_Server *server) {
54315 struct RemoveInactiveReserveIdContext removeCtx;
54316 removeCtx.server = server;
54317 removeCtx.newTree.root = NULL;
54318 ZIP_ITER(UA_ReserveIdTree, &server->pubSubManager.reserveIds,
54319 removeInactiveReserveId, &removeCtx);
54320 server->pubSubManager.reserveIds = removeCtx.newTree;
54321}
54322
54323UA_StatusCode
54324UA_PubSubManager_reserveIds(UA_Server *server, UA_NodeId sessionId, UA_UInt16 numRegWriterGroupIds,
54325 UA_UInt16 numRegDataSetWriterIds, UA_String transportProfileUri,
54326 UA_UInt16 **writerGroupIds, UA_UInt16 **dataSetWriterIds) {
54327 UA_PubSubManager_freeIds(server);
54328
54329 /* Check the validation of the transportProfileUri */
54330 UA_String profile_1 = UA_STRING(chars: "http://opcfoundation.org/UA-Profile/Transport/pubsub-mqtt-uadp");
54331 UA_String profile_2 = UA_STRING(chars: "http://opcfoundation.org/UA-Profile/Transport/pubsub-mqtt-json");
54332 UA_String profile_3 = UA_STRING(chars: "http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp");
54333 if(!UA_String_equal(p1: &transportProfileUri, p2: &profile_1) &&
54334 !UA_String_equal(p1: &transportProfileUri, p2: &profile_2) &&
54335 !UA_String_equal(p1: &transportProfileUri, p2: &profile_3)) {
54336 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
54337 msg: "PubSub ReserveId creation failed. No valid transport profile uri.");
54338 return UA_STATUSCODE_BADINVALIDARGUMENT;
54339 }
54340 *writerGroupIds = (UA_UInt16*)UA_Array_new(size: numRegWriterGroupIds, type: &UA_TYPES[UA_TYPES_UINT16]);
54341 *dataSetWriterIds = (UA_UInt16*)UA_Array_new(size: numRegDataSetWriterIds, type: &UA_TYPES[UA_TYPES_UINT16]);
54342
54343 for(int i = 0; i < numRegWriterGroupIds; i++) {
54344 (*writerGroupIds)[i] =
54345 UA_ReserveId_createId(server, sessionId, transportProfileUri, reserveIdType: UA_WRITER_GROUP);
54346 }
54347 for(int i = 0; i < numRegDataSetWriterIds; i++) {
54348 (*dataSetWriterIds)[i] =
54349 UA_ReserveId_createId(server, sessionId, transportProfileUri, reserveIdType: UA_DATA_SET_WRITER);
54350 }
54351 return UA_STATUSCODE_GOOD;
54352}
54353
54354/* Calculate the time difference between current time and UTC (00:00) on January
54355 * 1, 2000. */
54356UA_UInt32
54357UA_PubSubConfigurationVersionTimeDifference(void) {
54358 UA_UInt32 timeDiffSince2000 = (UA_UInt32) (UA_DateTime_now() - UA_DATETIMESTAMP_2000);
54359 return timeDiffSince2000;
54360}
54361
54362static UA_StatusCode
54363addStandaloneSubscribedDataSet(UA_Server *server,
54364 const UA_StandaloneSubscribedDataSetConfig *sdsConfig,
54365 UA_NodeId *sdsIdentifier) {
54366 UA_LOCK_ASSERT(&server->serviceMutex, 1);
54367
54368 if(!sdsConfig){
54369 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
54370 msg: "SubscribedDataSet creation failed. No config passed in.");
54371 return UA_STATUSCODE_BADINVALIDARGUMENT;
54372 }
54373
54374 UA_StandaloneSubscribedDataSetConfig tmpSubscribedDataSetConfig;
54375 memset(s: &tmpSubscribedDataSetConfig, c: 0, n: sizeof(UA_StandaloneSubscribedDataSetConfig));
54376 if(UA_StandaloneSubscribedDataSetConfig_copy(src: sdsConfig, dst: &tmpSubscribedDataSetConfig) != UA_STATUSCODE_GOOD){
54377 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
54378 msg: "SubscribedDataSet creation failed. Configuration copy failed.");
54379 return UA_STATUSCODE_BADINTERNALERROR;
54380 }
54381 //create new PDS and add to UA_PubSubManager
54382 UA_StandaloneSubscribedDataSet *newSubscribedDataSet = (UA_StandaloneSubscribedDataSet *)
54383 UA_calloc(nmemb: 1, size: sizeof(UA_StandaloneSubscribedDataSet));
54384 if(!newSubscribedDataSet) {
54385 UA_StandaloneSubscribedDataSetConfig_clear(sdsConfig: &tmpSubscribedDataSetConfig);
54386 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
54387 msg: "SubscribedDataSet creation failed. Out of Memory.");
54388 return UA_STATUSCODE_BADOUTOFMEMORY;
54389 }
54390
54391 newSubscribedDataSet->config = tmpSubscribedDataSetConfig;
54392 newSubscribedDataSet->connectedReader = UA_NODEID_NULL;
54393
54394 TAILQ_INSERT_TAIL(&server->pubSubManager.subscribedDataSets, newSubscribedDataSet, listEntry);
54395 server->pubSubManager.subscribedDataSetsSize++;
54396
54397#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
54398 addStandaloneSubscribedDataSetRepresentation(server, subscribedDataSet: newSubscribedDataSet);
54399#else
54400 UA_PubSubManager_generateUniqueNodeId(&server->pubSubManager, &newSubscribedDataSet->identifier);
54401#endif
54402
54403 if(sdsIdentifier)
54404 UA_NodeId_copy(src: &newSubscribedDataSet->identifier, dst: sdsIdentifier);
54405
54406 return UA_STATUSCODE_GOOD;
54407}
54408
54409UA_StatusCode
54410UA_Server_addStandaloneSubscribedDataSet(UA_Server *server,
54411 const UA_StandaloneSubscribedDataSetConfig *sdsConfig,
54412 UA_NodeId *sdsIdentifier) {
54413 lockServer(server);
54414 UA_StatusCode res = addStandaloneSubscribedDataSet(server, sdsConfig, sdsIdentifier);
54415 unlockServer(server);
54416 return res;
54417}
54418
54419static UA_StatusCode
54420removeStandaloneSubscribedDataSet(UA_Server *server, const UA_NodeId sds) {
54421 UA_LOCK_ASSERT(&server->serviceMutex, 1);
54422
54423 UA_StandaloneSubscribedDataSet *subscribedDataSet =
54424 UA_StandaloneSubscribedDataSet_findSDSbyId(server, identifier: sds);
54425 if(!subscribedDataSet){
54426 return UA_STATUSCODE_BADNOTFOUND;
54427 }
54428
54429 //search for referenced readers.
54430 UA_PubSubConnection *tmpConnectoin;
54431 TAILQ_FOREACH(tmpConnectoin, &server->pubSubManager.connections, listEntry){
54432 UA_ReaderGroup *readerGroup;
54433 LIST_FOREACH(readerGroup, &tmpConnectoin->readerGroups, listEntry){
54434 UA_DataSetReader *currentReader, *tmpReader;
54435 LIST_FOREACH_SAFE(currentReader, &readerGroup->readers, listEntry, tmpReader){
54436 if(UA_NodeId_equal(p1: &currentReader->identifier, p2: &subscribedDataSet->connectedReader)){
54437 UA_DataSetReader_remove(server, dsr: currentReader);
54438 goto done;
54439 }
54440 }
54441 }
54442 }
54443
54444 done:
54445
54446#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
54447 deleteNode(server, nodeId: subscribedDataSet->identifier, true);
54448#endif
54449
54450 UA_StandaloneSubscribedDataSet_clear(server, subscribedDataSet);
54451 server->pubSubManager.subscribedDataSetsSize--;
54452
54453 TAILQ_REMOVE(&server->pubSubManager.subscribedDataSets, subscribedDataSet, listEntry);
54454 UA_free(ptr: subscribedDataSet);
54455 return UA_STATUSCODE_GOOD;
54456}
54457
54458UA_StatusCode
54459UA_Server_removeStandaloneSubscribedDataSet(UA_Server *server, const UA_NodeId sds) {
54460 lockServer(server);
54461 UA_StatusCode res = removeStandaloneSubscribedDataSet(server, sds);
54462 unlockServer(server);
54463 return res;
54464}
54465
54466/* Generate a new unique NodeId. This NodeId will be used for the information
54467 * model representation of PubSub entities. */
54468#ifndef UA_ENABLE_PUBSUB_INFORMATIONMODEL
54469void
54470UA_PubSubManager_generateUniqueNodeId(UA_PubSubManager *psm, UA_NodeId *nodeId) {
54471 *nodeId = UA_NODEID_NUMERIC(1, ++psm->uniqueIdCount);
54472}
54473#endif
54474
54475UA_Guid
54476UA_PubSubManager_generateUniqueGuid(UA_Server *server) {
54477 while(true) {
54478 UA_NodeId testId = UA_NODEID_GUID(nsIndex: 1, guid: UA_Guid_random());
54479 const UA_Node *testNode = UA_NODESTORE_GET(server, nodeId: &testId);
54480 if(!testNode)
54481 return testId.identifier.guid;
54482 UA_NODESTORE_RELEASE(server, testNode);
54483 }
54484}
54485
54486static UA_UInt64
54487generateRandomUInt64(UA_Server *server) {
54488 UA_UInt64 id = 0;
54489 UA_Guid ident = UA_Guid_random();
54490
54491 id = id + ident.data1;
54492 id = (id << 32) + ident.data2;
54493 id = (id << 16) + ident.data3;
54494 return id;
54495}
54496
54497/* Initialization the PubSub configuration. */
54498void
54499UA_PubSubManager_init(UA_Server *server, UA_PubSubManager *pubSubManager) {
54500 //TODO: Using the Mac address to generate the defaultPublisherId.
54501 // In the future, this can be retrieved from the eventloop.
54502 pubSubManager->defaultPublisherId = generateRandomUInt64(server);
54503
54504 TAILQ_INIT(&pubSubManager->connections);
54505 TAILQ_INIT(&pubSubManager->publishedDataSets);
54506 TAILQ_INIT(&pubSubManager->subscribedDataSets);
54507 TAILQ_INIT(&pubSubManager->topicAssign);
54508
54509#ifdef UA_ENABLE_PUBSUB_SKS
54510 TAILQ_INIT(&pubSubManager->securityGroups);
54511#endif
54512}
54513
54514void
54515UA_PubSubManager_shutdown(UA_Server *server, UA_PubSubManager *pubSubManager) {
54516 UA_PubSubConnection *tmpConnection;
54517 TAILQ_FOREACH(tmpConnection, &server->pubSubManager.connections, listEntry) {
54518 UA_PubSubConnection_setPubSubState(server, c: tmpConnection,
54519 state: UA_PUBSUBSTATE_DISABLED, UA_STATUSCODE_GOOD);
54520 }
54521}
54522
54523/* Delete the current PubSub configuration including all nested members. This
54524 * action also delete the configured PubSub transport Layers. */
54525void
54526UA_PubSubManager_delete(UA_Server *server, UA_PubSubManager *pubSubManager) {
54527 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
54528 msg: "PubSub cleanup was called.");
54529 UA_LOCK_ASSERT(&server->serviceMutex, 1);
54530
54531 /* Remove Connections - this also remove WriterGroups and ReaderGroups */
54532 UA_PubSubConnection *tmpConnection1, *tmpConnection2;
54533 TAILQ_FOREACH_SAFE(tmpConnection1, &server->pubSubManager.connections,
54534 listEntry, tmpConnection2) {
54535 UA_PubSubConnection_delete(server, c: tmpConnection1);
54536 }
54537
54538 /* Remove the DataSets */
54539 UA_PublishedDataSet *tmpPDS1, *tmpPDS2;
54540 TAILQ_FOREACH_SAFE(tmpPDS1, &server->pubSubManager.publishedDataSets,
54541 listEntry, tmpPDS2){
54542 UA_PublishedDataSet_remove(server, publishedDataSet: tmpPDS1);
54543 }
54544
54545 /* Remove the TopicAssigns */
54546 UA_TopicAssign *tmpTopicAssign1, *tmpTopicAssign2;
54547 TAILQ_FOREACH_SAFE(tmpTopicAssign1, &server->pubSubManager.topicAssign,
54548 listEntry, tmpTopicAssign2){
54549 server->pubSubManager.topicAssignSize--;
54550 TAILQ_REMOVE(&server->pubSubManager.topicAssign, tmpTopicAssign1, listEntry);
54551 UA_free(ptr: tmpTopicAssign1);
54552 }
54553
54554 /* Remove the ReserveIds*/
54555 ZIP_ITER(UA_ReserveIdTree, &server->pubSubManager.reserveIds, removeReserveId, NULL);
54556 server->pubSubManager.reserveIdsSize = 0;
54557
54558 /* Delete subscribed datasets */
54559 UA_StandaloneSubscribedDataSet *tmpSDS1, *tmpSDS2;
54560 TAILQ_FOREACH_SAFE(tmpSDS1, &server->pubSubManager.subscribedDataSets, listEntry, tmpSDS2){
54561 removeStandaloneSubscribedDataSet(server, sds: tmpSDS1->identifier);
54562 }
54563
54564#ifdef UA_ENABLE_PUBSUB_SKS
54565 /* Remove the SecurityGroups */
54566 UA_SecurityGroup *tmpSG1, *tmpSG2;
54567 TAILQ_FOREACH_SAFE(tmpSG1, &server->pubSubManager.securityGroups, listEntry, tmpSG2) {
54568 removeSecurityGroup(server, tmpSG1);
54569 }
54570
54571 /* Remove the keyStorages */
54572 UA_PubSubKeyStorage *ks, *ksTmp;
54573 LIST_FOREACH_SAFE(ks, &server->pubSubManager.pubSubKeyList, keyStorageList, ksTmp) {
54574 UA_PubSubKeyStorage_delete(server, ks);
54575 }
54576#endif
54577}
54578
54579#ifdef UA_ENABLE_PUBSUB_MONITORING
54580
54581static UA_StatusCode
54582UA_PubSubComponent_createMonitoring(UA_Server *server, UA_NodeId Id, UA_PubSubComponentEnumType eComponentType,
54583 UA_PubSubMonitoringType eMonitoringType, void *data, UA_ServerCallback callback) {
54584
54585 if(!server || !data)
54586 return UA_STATUSCODE_BADINVALIDARGUMENT;
54587
54588 UA_StatusCode ret = UA_STATUSCODE_GOOD;
54589 switch (eComponentType) {
54590 case UA_PUBSUB_COMPONENT_DATASETREADER: {
54591 UA_DataSetReader *reader = (UA_DataSetReader*) data;
54592 switch (eMonitoringType) {
54593 case UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT:
54594 UA_LOG_DEBUG(server->config.logging, UA_LOGCATEGORY_SERVER, "UA_PubSubComponent_createMonitoring(): DataSetReader '%.*s' "
54595 "- MessageReceiveTimeout", (UA_Int32) reader->config.name.length, reader->config.name.data);
54596 reader->msgRcvTimeoutTimerCallback = callback;
54597 break;
54598 default:
54599 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER, "UA_PubSubComponent_createMonitoring(): DataSetReader '%.*s' "
54600 "DataSetReader does not support timeout type '%i'", (UA_Int32) reader->config.name.length, reader->config.name.data,
54601 eMonitoringType);
54602 ret = UA_STATUSCODE_BADNOTSUPPORTED;
54603 break;
54604 }
54605 break;
54606 }
54607 default:
54608 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
54609 "Error UA_PubSubComponent_createMonitoring(): PubSub component type '%i' is not supported", eComponentType);
54610 ret = UA_STATUSCODE_BADNOTSUPPORTED;
54611 break;
54612 }
54613 return ret;
54614}
54615
54616static void
54617monitoringReceiveTimeoutOnce(UA_Server *server, void *data) {
54618 UA_DataSetReader *reader = (UA_DataSetReader*)data;
54619 reader->msgRcvTimeoutTimerCallback(server, reader);
54620 UA_EventLoop *el = server->config.eventLoop;
54621 el->removeCyclicCallback(el, reader->msgRcvTimeoutTimerId);
54622 reader->msgRcvTimeoutTimerId = 0;
54623}
54624
54625static UA_StatusCode
54626UA_PubSubComponent_startMonitoring(UA_Server *server, UA_NodeId Id,
54627 UA_PubSubComponentEnumType eComponentType,
54628 UA_PubSubMonitoringType eMonitoringType, void *data) {
54629 if(!server || !data)
54630 return UA_STATUSCODE_BADINVALIDARGUMENT;
54631
54632 UA_StatusCode ret = UA_STATUSCODE_GOOD;
54633 switch (eComponentType) {
54634 case UA_PUBSUB_COMPONENT_DATASETREADER: {
54635 UA_DataSetReader *reader = (UA_DataSetReader*) data;
54636 switch (eMonitoringType) {
54637 case UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT: {
54638 if(reader->config.messageReceiveTimeout == 0) {
54639 UA_LOG_WARNING_READER(server->config.logging, reader,
54640 "Cannot monitor timeout for messageReceiveTimeout == 0");
54641 return UA_STATUSCODE_GOOD;
54642 }
54643
54644 /* use a timed callback, because one notification is enough,
54645 * we assume that MessageReceiveTimeout configuration is in
54646 * [ms], we do not handle or check fractions */
54647 UA_EventLoop *el = server->config.eventLoop;
54648 ret = el->addCyclicCallback(el, (UA_Callback)monitoringReceiveTimeoutOnce,
54649 server, reader, reader->config.messageReceiveTimeout,
54650 NULL, UA_TIMER_HANDLE_CYCLEMISS_WITH_CURRENTTIME,
54651 &reader->msgRcvTimeoutTimerId);
54652 if(ret == UA_STATUSCODE_GOOD) {
54653 UA_LOG_DEBUG(server->config.logging, UA_LOGCATEGORY_SERVER,
54654 "UA_PubSubComponent_startMonitoring(): DataSetReader '%.*s'- "
54655 "MessageReceiveTimeout: MessageReceiveTimeout = '%f' "
54656 "Timer Id = '%u'", (UA_Int32) reader->config.name.length,
54657 reader->config.name.data, reader->config.messageReceiveTimeout,
54658 (UA_UInt32) reader->msgRcvTimeoutTimerId);
54659 } else {
54660 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
54661 "Error UA_PubSubComponent_startMonitoring(): DataSetReader "
54662 "'%.*s' - MessageReceiveTimeout: start timer failed",
54663 (UA_Int32) reader->config.name.length, reader->config.name.data);
54664 }
54665 break;
54666 }
54667 default:
54668 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
54669 "UA_PubSubComponent_startMonitoring(): DataSetReader '%.*s' "
54670 "DataSetReader does not support timeout type '%i'",
54671 (UA_Int32) reader->config.name.length, reader->config.name.data,
54672 eMonitoringType);
54673 ret = UA_STATUSCODE_BADNOTSUPPORTED;
54674 break;
54675 }
54676 break;
54677 }
54678 default:
54679 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
54680 "Error UA_PubSubComponent_startMonitoring(): PubSub component "
54681 "type '%i' is not supported", eComponentType);
54682 ret = UA_STATUSCODE_BADNOTSUPPORTED;
54683 break;
54684 }
54685 return ret;
54686}
54687
54688static UA_StatusCode
54689UA_PubSubComponent_stopMonitoring(UA_Server *server, UA_NodeId Id,
54690 UA_PubSubComponentEnumType eComponentType,
54691 UA_PubSubMonitoringType eMonitoringType, void *data) {
54692 if(!server || !data)
54693 return UA_STATUSCODE_BADINVALIDARGUMENT;
54694
54695 UA_StatusCode ret = UA_STATUSCODE_GOOD;
54696 switch (eComponentType) {
54697 case UA_PUBSUB_COMPONENT_DATASETREADER: {
54698 UA_DataSetReader *reader = (UA_DataSetReader*) data;
54699 switch (eMonitoringType) {
54700 case UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT: {
54701 UA_EventLoop *el = server->config.eventLoop;
54702 el->removeCyclicCallback(el, reader->msgRcvTimeoutTimerId);
54703 UA_LOG_DEBUG(server->config.logging, UA_LOGCATEGORY_SERVER,
54704 "UA_PubSubComponent_stopMonitoring(): DataSetReader '%.*s' - "
54705 "MessageReceiveTimeout: MessageReceiveTimeout = '%f' "
54706 "Timer Id = '%u'", (UA_Int32) reader->config.name.length,
54707 reader->config.name.data, reader->config.messageReceiveTimeout,
54708 (UA_UInt32) reader->msgRcvTimeoutTimerId);
54709 break;
54710 }
54711 default:
54712 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
54713 "UA_PubSubComponent_stopMonitoring(): DataSetReader '%.*s' "
54714 "DataSetReader does not support timeout type '%i'",
54715 (UA_Int32) reader->config.name.length, reader->config.name.data,
54716 eMonitoringType);
54717 ret = UA_STATUSCODE_BADNOTSUPPORTED;
54718 break;
54719 }
54720 break;
54721 }
54722 default:
54723 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
54724 "Error UA_PubSubComponent_stopMonitoring(): PubSub component type '%i' "
54725 "is not supported", eComponentType);
54726 ret = UA_STATUSCODE_BADNOTSUPPORTED;
54727 break;
54728 }
54729 return ret;
54730}
54731
54732static UA_StatusCode
54733UA_PubSubComponent_updateMonitoringInterval(UA_Server *server, UA_NodeId Id,
54734 UA_PubSubComponentEnumType eComponentType,
54735 UA_PubSubMonitoringType eMonitoringType, void *data) {
54736 if(!server || !data)
54737 return UA_STATUSCODE_BADINVALIDARGUMENT;
54738
54739 UA_StatusCode ret = UA_STATUSCODE_GOOD;
54740 switch (eComponentType) {
54741 case UA_PUBSUB_COMPONENT_DATASETREADER: {
54742 UA_DataSetReader *reader = (UA_DataSetReader*) data;
54743 switch (eMonitoringType) {
54744 case UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT: {
54745 UA_EventLoop *el = server->config.eventLoop;
54746 ret = el->modifyCyclicCallback(el, reader->msgRcvTimeoutTimerId,
54747 reader->config.messageReceiveTimeout, NULL,
54748 UA_TIMER_HANDLE_CYCLEMISS_WITH_CURRENTTIME);
54749 if (ret == UA_STATUSCODE_GOOD) {
54750 UA_LOG_DEBUG(server->config.logging, UA_LOGCATEGORY_SERVER,
54751 "UA_PubSubComponent_updateMonitoringInterval(): "
54752 "DataSetReader '%.*s' - MessageReceiveTimeout: new "
54753 "MessageReceiveTimeout = '%f' Timer Id = '%u'",
54754 (UA_Int32) reader->config.name.length, reader->config.name.data,
54755 reader->config.messageReceiveTimeout,
54756 (UA_UInt32) reader->msgRcvTimeoutTimerId);
54757 } else {
54758 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
54759 "Error UA_PubSubComponent_updateMonitoringInterval(): "
54760 "DataSetReader '%.*s': update timer interval failed",
54761 (UA_Int32) reader->config.name.length, reader->config.name.data);
54762 }
54763 break;
54764 }
54765 default:
54766 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
54767 "UA_PubSubComponent_createMonitoring(): DataSetReader '%.*s' "
54768 "DataSetReader does not support timeout type '%i'",
54769 (UA_Int32) reader->config.name.length, reader->config.name.data,
54770 eMonitoringType);
54771 ret = UA_STATUSCODE_BADNOTSUPPORTED;
54772 break;
54773 }
54774 break;
54775 }
54776 default:
54777 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
54778 "Error UA_PubSubComponent_updateMonitoringInterval(): "
54779 "PubSub component type '%i' is not supported", eComponentType);
54780 ret = UA_STATUSCODE_BADNOTSUPPORTED;
54781 break;
54782 }
54783 return ret;
54784}
54785
54786static UA_StatusCode
54787UA_PubSubComponent_deleteMonitoring(UA_Server *server, UA_NodeId Id,
54788 UA_PubSubComponentEnumType eComponentType,
54789 UA_PubSubMonitoringType eMonitoringType, void *data) {
54790
54791 if(!server || !data)
54792 return UA_STATUSCODE_BADINVALIDARGUMENT;
54793
54794 UA_StatusCode ret = UA_STATUSCODE_GOOD;
54795 switch (eComponentType) {
54796 case UA_PUBSUB_COMPONENT_DATASETREADER: {
54797 UA_DataSetReader *reader = (UA_DataSetReader*) data;
54798 switch (eMonitoringType) {
54799 case UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT:
54800 UA_LOG_DEBUG(server->config.logging, UA_LOGCATEGORY_SERVER,
54801 "UA_PubSubComponent_deleteMonitoring(): DataSetReader '%.*s' - "
54802 "MessageReceiveTimeout: Timer Id = '%u'",
54803 (UA_Int32)reader->config.name.length, reader->config.name.data,
54804 (UA_UInt32) reader->msgRcvTimeoutTimerId);
54805 break;
54806 default:
54807 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
54808 "UA_PubSubComponent_deleteMonitoring(): DataSetReader '%.*s' "
54809 "DataSetReader does not support timeout type '%i'",
54810 (UA_Int32) reader->config.name.length, reader->config.name.data,
54811 eMonitoringType);
54812 ret = UA_STATUSCODE_BADNOTSUPPORTED;
54813 break;
54814 }
54815 break;
54816 }
54817 default:
54818 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
54819 "Error UA_PubSubComponent_deleteMonitoring(): PubSub component type "
54820 "'%i' is not supported", eComponentType);
54821 ret = UA_STATUSCODE_BADNOTSUPPORTED;
54822 break;
54823 }
54824 return ret;
54825}
54826
54827UA_StatusCode
54828UA_PubSubManager_setDefaultMonitoringCallbacks(UA_PubSubMonitoringInterface *monitoringInterface) {
54829 if (monitoringInterface == NULL) {
54830 return UA_STATUSCODE_BADINVALIDARGUMENT;
54831 }
54832 monitoringInterface->createMonitoring = UA_PubSubComponent_createMonitoring;
54833 monitoringInterface->startMonitoring = UA_PubSubComponent_startMonitoring;
54834 monitoringInterface->stopMonitoring = UA_PubSubComponent_stopMonitoring;
54835 monitoringInterface->updateMonitoringInterval = UA_PubSubComponent_updateMonitoringInterval;
54836 monitoringInterface->deleteMonitoring = UA_PubSubComponent_deleteMonitoring;
54837 return UA_STATUSCODE_GOOD;
54838}
54839
54840#endif /* UA_ENABLE_PUBSUB_MONITORING */
54841
54842#endif /* UA_ENABLE_PUBSUB */
54843
54844/**** amalgamated original file "/src/pubsub/ua_pubsub_ns0.c" ****/
54845
54846/* This Source Code Form is subject to the terms of the Mozilla Public
54847 * License, v. 2.0. If a copy of the MPL was not distributed with this
54848 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
54849 *
54850 * Copyright (c) 2017-2022 Fraunhofer IOSB (Author: Andreas Ebner)
54851 * Copyright (c) 2019-2021 Kalycito Infotech Private Limited
54852 * Copyright (c) 2020 Yannick Wallerer, Siemens AG
54853 * Copyright (c) 2020-2022 Thomas Fischer, Siemens AG
54854 * Copyright (c) 2022 Linutronix GmbH (Author: Muddasir Shakil)
54855 */
54856
54857
54858#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL /* conditional compilation */
54859
54860typedef struct {
54861 UA_NodeId parentNodeId;
54862 UA_UInt32 parentClassifier;
54863 UA_UInt32 elementClassiefier;
54864} UA_NodePropertyContext;
54865
54866static UA_StatusCode
54867writePubSubNs0VariableArray(UA_Server *server, const UA_NodeId id, void *v,
54868 size_t length, const UA_DataType *type) {
54869 UA_LOCK_ASSERT(&server->serviceMutex, 1);
54870 UA_Variant var;
54871 UA_Variant_init(p: &var);
54872 UA_Variant_setArray(v: &var, array: v, arraySize: length, type);
54873 return writeValueAttribute(server, nodeId: id, value: &var);
54874}
54875
54876static UA_NodeId
54877findSingleChildNode(UA_Server *server, UA_QualifiedName targetName,
54878 UA_NodeId referenceTypeId, UA_NodeId startingNode){
54879 UA_LOCK_ASSERT(&server->serviceMutex, 1);
54880 UA_NodeId resultNodeId;
54881 UA_RelativePathElement rpe;
54882 UA_RelativePathElement_init(p: &rpe);
54883 rpe.referenceTypeId = referenceTypeId;
54884 rpe.isInverse = false;
54885 rpe.includeSubtypes = false;
54886 rpe.targetName = targetName;
54887 UA_BrowsePath bp;
54888 UA_BrowsePath_init(p: &bp);
54889 bp.startingNode = startingNode;
54890 bp.relativePath.elementsSize = 1;
54891 bp.relativePath.elements = &rpe;
54892 UA_BrowsePathResult bpr = translateBrowsePathToNodeIds(server, browsePath: &bp);
54893 if(bpr.statusCode != UA_STATUSCODE_GOOD ||
54894 bpr.targetsSize < 1)
54895 return UA_NODEID_NULL;
54896 UA_StatusCode res = UA_NodeId_copy(src: &bpr.targets[0].targetId.nodeId, dst: &resultNodeId);
54897 if(res != UA_STATUSCODE_GOOD){
54898 UA_BrowsePathResult_clear(p: &bpr);
54899 return UA_NODEID_NULL;
54900 }
54901 UA_BrowsePathResult_clear(p: &bpr);
54902 return resultNodeId;
54903}
54904
54905static void
54906onReadLocked(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
54907 const UA_NodeId *nodeid, void *context,
54908 const UA_NumericRange *range, const UA_DataValue *data) {
54909 UA_LOCK_ASSERT(&server->serviceMutex, 1);
54910
54911 const UA_NodePropertyContext *nodeContext = (const UA_NodePropertyContext*)context;
54912 const UA_NodeId *myNodeId = &nodeContext->parentNodeId;
54913
54914 UA_PublishedVariableDataType *pvd = NULL;
54915 UA_PublishedDataSet *publishedDataSet = NULL;
54916
54917 UA_Variant value;
54918 UA_Variant_init(p: &value);
54919
54920 switch(nodeContext->parentClassifier){
54921 case UA_NS0ID_PUBSUBCONNECTIONTYPE: {
54922 UA_PubSubConnection *pubSubConnection =
54923 UA_PubSubConnection_findConnectionbyId(server, connectionIdentifier: *myNodeId);
54924 switch(nodeContext->elementClassiefier) {
54925 case UA_NS0ID_PUBSUBCONNECTIONTYPE_PUBLISHERID:
54926 switch (pubSubConnection->config.publisherIdType) {
54927 case UA_PUBLISHERIDTYPE_BYTE:
54928 UA_Variant_setScalar(v: &value, p: &pubSubConnection->config.publisherId.byte,
54929 type: &UA_TYPES[UA_TYPES_BYTE]);
54930 break;
54931 case UA_PUBLISHERIDTYPE_UINT16:
54932 UA_Variant_setScalar(v: &value, p: &pubSubConnection->config.publisherId.uint16,
54933 type: &UA_TYPES[UA_TYPES_UINT16]);
54934 break;
54935 case UA_PUBLISHERIDTYPE_UINT32:
54936 UA_Variant_setScalar(v: &value, p: &pubSubConnection->config.publisherId.uint32,
54937 type: &UA_TYPES[UA_TYPES_UINT32]);
54938 break;
54939 case UA_PUBLISHERIDTYPE_UINT64:
54940 UA_Variant_setScalar(v: &value, p: &pubSubConnection->config.publisherId.uint64,
54941 type: &UA_TYPES[UA_TYPES_UINT64]);
54942 break;
54943 case UA_PUBLISHERIDTYPE_STRING:
54944 UA_Variant_setScalar(v: &value, p: &pubSubConnection->config.publisherId.string,
54945 type: &UA_TYPES[UA_TYPES_STRING]);
54946 break;
54947 default:
54948 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
54949 msg: "Read error! Unknown PublisherId type.");
54950 }
54951 break;
54952 default:
54953 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
54954 msg: "Read error! Unknown property.");
54955 }
54956 break;
54957 }
54958 case UA_NS0ID_DATASETREADERTYPE: {
54959 UA_DataSetReader *dataSetReader = UA_ReaderGroup_findDSRbyId(server, identifier: *myNodeId);
54960 if(!dataSetReader)
54961 return;
54962
54963 switch(nodeContext->elementClassiefier) {
54964 case UA_NS0ID_DATASETREADERTYPE_PUBLISHERID:
54965 UA_Variant_setScalar(v: &value, p: dataSetReader->config.publisherId.data,
54966 type: dataSetReader->config.publisherId.type);
54967 break;
54968 default:
54969 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
54970 msg: "Read error! Unknown property.");
54971 }
54972 break;
54973 }
54974 case UA_NS0ID_WRITERGROUPTYPE: {
54975 UA_WriterGroup *writerGroup = UA_WriterGroup_findWGbyId(server, identifier: *myNodeId);
54976 if(!writerGroup)
54977 return;
54978 switch(nodeContext->elementClassiefier){
54979 case UA_NS0ID_WRITERGROUPTYPE_PUBLISHINGINTERVAL:
54980 UA_Variant_setScalar(v: &value, p: &writerGroup->config.publishingInterval,
54981 type: &UA_TYPES[UA_TYPES_DURATION]);
54982 break;
54983 default:
54984 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
54985 msg: "Read error! Unknown property.");
54986 }
54987 break;
54988 }
54989 case UA_NS0ID_DATASETWRITERTYPE: {
54990 UA_DataSetWriter *dataSetWriter = UA_DataSetWriter_findDSWbyId(server, identifier: *myNodeId);
54991 if(!dataSetWriter)
54992 return;
54993
54994 switch(nodeContext->elementClassiefier) {
54995 case UA_NS0ID_DATASETWRITERTYPE_DATASETWRITERID:
54996 UA_Variant_setScalar(v: &value, p: &dataSetWriter->config.dataSetWriterId,
54997 type: &UA_TYPES[UA_TYPES_UINT16]);
54998 break;
54999 default:
55000 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55001 msg: "Read error! Unknown property.");
55002 }
55003 break;
55004 }
55005 case UA_NS0ID_PUBLISHEDDATAITEMSTYPE: {
55006 publishedDataSet = UA_PublishedDataSet_findPDSbyId(server, identifier: *myNodeId);
55007 if(!publishedDataSet)
55008 return;
55009 switch(nodeContext->elementClassiefier) {
55010 case UA_NS0ID_PUBLISHEDDATAITEMSTYPE_PUBLISHEDDATA: {
55011 pvd = (UA_PublishedVariableDataType *)
55012 UA_calloc(nmemb: publishedDataSet->fieldSize, size: sizeof(UA_PublishedVariableDataType));
55013 size_t counter = 0;
55014 UA_DataSetField *field;
55015 TAILQ_FOREACH(field, &publishedDataSet->fields, listEntry) {
55016 pvd[counter].attributeId = UA_ATTRIBUTEID_VALUE;
55017 pvd[counter].publishedVariable =
55018 field->config.field.variable.publishParameters.publishedVariable;
55019 UA_NodeId_copy(src: &field->config.field.variable.publishParameters.publishedVariable,
55020 dst: &pvd[counter].publishedVariable);
55021 counter++;
55022 }
55023 UA_Variant_setArray(v: &value, array: pvd, arraySize: publishedDataSet->fieldSize,
55024 type: &UA_TYPES[UA_TYPES_PUBLISHEDVARIABLEDATATYPE]);
55025 break;
55026 }
55027 case UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETMETADATA: {
55028 UA_Variant_setScalar(v: &value, p: &publishedDataSet->dataSetMetaData,
55029 type: &UA_TYPES[UA_TYPES_DATASETMETADATATYPE]);
55030 break;
55031 }
55032 case UA_NS0ID_PUBLISHEDDATAITEMSTYPE_CONFIGURATIONVERSION: {
55033 UA_Variant_setScalar(v: &value, p: &publishedDataSet->dataSetMetaData.configurationVersion,
55034 type: &UA_TYPES[UA_TYPES_CONFIGURATIONVERSIONDATATYPE]);
55035 break;
55036 }
55037 default:
55038 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55039 msg: "Read error! Unknown property.");
55040 }
55041 break;
55042 }
55043 case UA_NS0ID_STANDALONESUBSCRIBEDDATASETREFDATATYPE: {
55044 UA_StandaloneSubscribedDataSet *sds =
55045 UA_StandaloneSubscribedDataSet_findSDSbyId(server, identifier: *myNodeId);
55046 switch(nodeContext->elementClassiefier) {
55047 case UA_NS0ID_STANDALONESUBSCRIBEDDATASETTYPE_ISCONNECTED: {
55048 UA_Variant_setScalar(v: &value, p: &sds->config.isConnected,
55049 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
55050 break;
55051 }
55052 case UA_NS0ID_STANDALONESUBSCRIBEDDATASETTYPE_DATASETMETADATA: {
55053 UA_Variant_setScalar(v: &value, p: &sds->config.dataSetMetaData,
55054 type: &UA_TYPES[UA_TYPES_DATASETMETADATATYPE]);
55055 break;
55056 }
55057 default:
55058 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55059 msg: "Read error! Unknown property.");
55060 }
55061 break;
55062 }
55063 default:
55064 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55065 msg: "Read error! Unknown parent element.");
55066 }
55067
55068 writeValueAttribute(server, nodeId: *nodeid, value: &value);
55069 if(pvd && publishedDataSet) {
55070 UA_Array_delete(p: pvd, size: publishedDataSet->fieldSize,
55071 type: &UA_TYPES[UA_TYPES_PUBLISHEDVARIABLEDATATYPE]);
55072 }
55073}
55074
55075static void
55076onRead(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
55077 const UA_NodeId *nodeid, void *context,
55078 const UA_NumericRange *range, const UA_DataValue *data) {
55079 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55080 onReadLocked(server, sessionId, sessionContext, nodeid, context, range, data);
55081}
55082
55083static void
55084onWriteLocked(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
55085 const UA_NodeId *nodeId, void *nodeContext,
55086 const UA_NumericRange *range, const UA_DataValue *data) {
55087 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55088 UA_NodePropertyContext *npc = (UA_NodePropertyContext *)nodeContext;
55089
55090 UA_WriterGroup *writerGroup = NULL;
55091 UA_StatusCode res = UA_STATUSCODE_GOOD;
55092 switch(npc->parentClassifier) {
55093 case UA_NS0ID_PUBSUBCONNECTIONTYPE:
55094 //no runtime writable attributes
55095 break;
55096 case UA_NS0ID_WRITERGROUPTYPE: {
55097 writerGroup = UA_WriterGroup_findWGbyId(server, identifier: npc->parentNodeId);
55098 if(!writerGroup)
55099 return;
55100 UA_WriterGroupConfig writerGroupConfig;
55101 memset(s: &writerGroupConfig, c: 0, n: sizeof(writerGroupConfig));
55102 switch(npc->elementClassiefier) {
55103 case UA_NS0ID_WRITERGROUPTYPE_PUBLISHINGINTERVAL:
55104 if(!UA_Variant_hasScalarType(v: &data->value, type: &UA_TYPES[UA_TYPES_DURATION]) &&
55105 !UA_Variant_hasScalarType(v: &data->value, type: &UA_TYPES[UA_TYPES_DOUBLE])) {
55106 res = UA_STATUSCODE_BADTYPEMISMATCH;
55107 goto cleanup;
55108 }
55109 res = UA_WriterGroupConfig_copy(src: &writerGroup->config, dst: &writerGroupConfig);
55110 if(res != UA_STATUSCODE_GOOD)
55111 goto cleanup;
55112 writerGroupConfig.publishingInterval = *((UA_Duration *) data->value.data);
55113 UA_WriterGroup_updateConfig(server, wg: writerGroup, config: &writerGroupConfig);
55114 UA_WriterGroupConfig_clear(writerGroupConfig: &writerGroupConfig);
55115 break;
55116 default:
55117 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55118 msg: "Write error! Unknown property element.");
55119 }
55120 break;
55121 }
55122 default:
55123 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55124 msg: "Read error! Unknown parent element.");
55125 }
55126
55127 cleanup:
55128 if(res != UA_STATUSCODE_GOOD) {
55129 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55130 msg: "Changing the ReaderGroupConfig failed with status %s",
55131 UA_StatusCode_name(code: res));
55132 }
55133}
55134
55135static void
55136onWrite(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext,
55137 const UA_NodeId *nodeId, void *nodeContext,
55138 const UA_NumericRange *range, const UA_DataValue *data) {
55139 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55140 onWriteLocked(server, sessionId, sessionContext, nodeId, nodeContext, range, data);
55141}
55142
55143static UA_StatusCode
55144addVariableValueSource(UA_Server *server, UA_ValueCallback valueCallback,
55145 UA_NodeId node, UA_NodePropertyContext *context){
55146 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55147 setNodeContext(server, nodeId: node, nodeContext: context);
55148 return setVariableNode_valueCallback(server, nodeId: node, callback: valueCallback);
55149}
55150
55151static UA_StatusCode
55152addPubSubConnectionConfig(UA_Server *server, UA_PubSubConnectionDataType *pubsubConnection,
55153 UA_NodeId *connectionId) {
55154 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55155
55156 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
55157 UA_NetworkAddressUrlDataType networkAddressUrl;
55158 memset(s: &networkAddressUrl, c: 0, n: sizeof(networkAddressUrl));
55159 UA_ExtensionObject *eo = &pubsubConnection->address;
55160 if(eo->encoding == UA_EXTENSIONOBJECT_DECODED &&
55161 eo->content.decoded.type == &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]) {
55162 void *data = eo->content.decoded.data;
55163 retVal =
55164 UA_NetworkAddressUrlDataType_copy(src: (UA_NetworkAddressUrlDataType *)data,
55165 dst: &networkAddressUrl);
55166 if(retVal != UA_STATUSCODE_GOOD)
55167 return retVal;
55168 }
55169
55170 UA_PubSubConnectionConfig connectionConfig;
55171 memset(s: &connectionConfig, c: 0, n: sizeof(UA_PubSubConnectionConfig));
55172 connectionConfig.transportProfileUri = pubsubConnection->transportProfileUri;
55173 connectionConfig.name = pubsubConnection->name;
55174 //TODO set real connection state
55175 connectionConfig.enabled = pubsubConnection->enabled;
55176 //connectionConfig.enabled = pubSubConnection.enabled;
55177 UA_Variant_setScalar(v: &connectionConfig.address, p: &networkAddressUrl,
55178 type: &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]);
55179
55180 if (pubsubConnection->publisherId.type == &UA_TYPES[UA_TYPES_BYTE]) {
55181 connectionConfig.publisherIdType = UA_PUBLISHERIDTYPE_BYTE;
55182 connectionConfig.publisherId.byte = *((UA_Byte*)pubsubConnection->publisherId.data);
55183 } else if (pubsubConnection->publisherId.type == &UA_TYPES[UA_TYPES_UINT16]) {
55184 connectionConfig.publisherIdType = UA_PUBLISHERIDTYPE_UINT16;
55185 connectionConfig.publisherId.uint16 = *((UA_UInt16*)pubsubConnection->publisherId.data);
55186 } else if (pubsubConnection->publisherId.type == &UA_TYPES[UA_TYPES_UINT32]) {
55187 connectionConfig.publisherIdType = UA_PUBLISHERIDTYPE_UINT32;
55188 connectionConfig.publisherId.uint32 = *((UA_UInt32*)pubsubConnection->publisherId.data);
55189 } else if (pubsubConnection->publisherId.type == &UA_TYPES[UA_TYPES_UINT64]) {
55190 connectionConfig.publisherIdType = UA_PUBLISHERIDTYPE_UINT64;
55191 connectionConfig.publisherId.uint64 = *((UA_UInt64*)pubsubConnection->publisherId.data);
55192 } else if (pubsubConnection->publisherId.type == &UA_TYPES[UA_TYPES_STRING]) {
55193 connectionConfig.publisherIdType = UA_PUBLISHERIDTYPE_STRING;
55194 UA_String_copy(src: (UA_String *) pubsubConnection->publisherId.data,
55195 dst: &connectionConfig.publisherId.string);
55196 } else {
55197 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55198 msg: "Unsupported PublisherId Type used.");
55199 return UA_STATUSCODE_BADCONFIGURATIONERROR;
55200 }
55201
55202 retVal |= UA_PubSubConnection_create(server, cc: &connectionConfig, cId: connectionId);
55203 UA_NetworkAddressUrlDataType_clear(p: &networkAddressUrl);
55204 return retVal;
55205}
55206
55207/**
55208 * **WriterGroup handling**
55209 *
55210 * The WriterGroup (WG) is part of the connection and contains the primary
55211 * configuration parameters for the message creation. */
55212static UA_StatusCode
55213addWriterGroupConfig(UA_Server *server, UA_NodeId connectionId,
55214 UA_WriterGroupDataType *writerGroup, UA_NodeId *writerGroupId){
55215 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55216
55217 /* Now we create a new WriterGroupConfig and add the group to the existing
55218 * PubSubConnection. */
55219 UA_WriterGroupConfig writerGroupConfig;
55220 memset(s: &writerGroupConfig, c: 0, n: sizeof(UA_WriterGroupConfig));
55221 writerGroupConfig.name = writerGroup->name;
55222 writerGroupConfig.publishingInterval = writerGroup->publishingInterval;
55223 writerGroupConfig.enabled = writerGroup->enabled;
55224 writerGroupConfig.writerGroupId = writerGroup->writerGroupId;
55225 writerGroupConfig.priority = writerGroup->priority;
55226
55227 UA_ExtensionObject *eoWG = &writerGroup->messageSettings;
55228 UA_UadpWriterGroupMessageDataType uadpWriterGroupMessage;
55229 UA_JsonWriterGroupMessageDataType jsonWriterGroupMessage;
55230 if(eoWG->encoding == UA_EXTENSIONOBJECT_DECODED){
55231 writerGroupConfig.messageSettings.encoding = UA_EXTENSIONOBJECT_DECODED;
55232 if(eoWG->content.decoded.type == &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE]){
55233 writerGroupConfig.encodingMimeType = UA_PUBSUB_ENCODING_UADP;
55234 if(UA_UadpWriterGroupMessageDataType_copy(
55235 src: (UA_UadpWriterGroupMessageDataType *)eoWG->content.decoded.data,
55236 dst: &uadpWriterGroupMessage) != UA_STATUSCODE_GOOD) {
55237 return UA_STATUSCODE_BADOUTOFMEMORY;
55238 }
55239 writerGroupConfig.messageSettings.content.decoded.type = &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE];
55240 writerGroupConfig.messageSettings.content.decoded.data = &uadpWriterGroupMessage;
55241 } else if(eoWG->content.decoded.type == &UA_TYPES[UA_TYPES_JSONWRITERGROUPMESSAGEDATATYPE]) {
55242 writerGroupConfig.encodingMimeType = UA_PUBSUB_ENCODING_JSON;
55243 if(UA_JsonWriterGroupMessageDataType_copy(
55244 src: (UA_JsonWriterGroupMessageDataType *)eoWG->content.decoded.data,
55245 dst: &jsonWriterGroupMessage) != UA_STATUSCODE_GOOD) {
55246 return UA_STATUSCODE_BADOUTOFMEMORY;
55247 }
55248 writerGroupConfig.messageSettings.content.decoded.type = &UA_TYPES[UA_TYPES_JSONWRITERGROUPMESSAGEDATATYPE];
55249 writerGroupConfig.messageSettings.content.decoded.data = &jsonWriterGroupMessage;
55250 }
55251 }
55252
55253 eoWG = &writerGroup->transportSettings;
55254 UA_BrokerWriterGroupTransportDataType brokerWriterGroupTransport;
55255 UA_DatagramWriterGroupTransportDataType datagramWriterGroupTransport;
55256 if(eoWG->encoding == UA_EXTENSIONOBJECT_DECODED) {
55257 writerGroupConfig.transportSettings.encoding = UA_EXTENSIONOBJECT_DECODED;
55258 if(eoWG->content.decoded.type == &UA_TYPES[UA_TYPES_BROKERWRITERGROUPTRANSPORTDATATYPE]) {
55259 if(UA_BrokerWriterGroupTransportDataType_copy(
55260 src: (UA_BrokerWriterGroupTransportDataType*)eoWG->content.decoded.data,
55261 dst: &brokerWriterGroupTransport) != UA_STATUSCODE_GOOD) {
55262 return UA_STATUSCODE_BADOUTOFMEMORY;
55263 }
55264 writerGroupConfig.transportSettings.content.decoded.type = &UA_TYPES[UA_TYPES_BROKERWRITERGROUPTRANSPORTDATATYPE];
55265 writerGroupConfig.transportSettings.content.decoded.data = &brokerWriterGroupTransport;
55266 } else if(eoWG->content.decoded.type == &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORTDATATYPE]) {
55267 if(UA_DatagramWriterGroupTransportDataType_copy(
55268 src: (UA_DatagramWriterGroupTransportDataType *)eoWG->content.decoded.data,
55269 dst: &datagramWriterGroupTransport) != UA_STATUSCODE_GOOD) {
55270 return UA_STATUSCODE_BADOUTOFMEMORY;
55271 }
55272 writerGroupConfig.transportSettings.content.decoded.type = &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORTDATATYPE];
55273 writerGroupConfig.transportSettings.content.decoded.data = &datagramWriterGroupTransport;
55274 }
55275 }
55276 if (writerGroupConfig.encodingMimeType == UA_PUBSUB_ENCODING_JSON
55277 && (writerGroupConfig.transportSettings.encoding != UA_EXTENSIONOBJECT_DECODED ||
55278 writerGroupConfig.transportSettings.content.decoded.type !=
55279 &UA_TYPES[UA_TYPES_BROKERWRITERGROUPTRANSPORTDATATYPE])) {
55280 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55281 msg: "JSON encoding is supported only for MQTT transport");
55282 return UA_STATUSCODE_BADCONFIGURATIONERROR;
55283 }
55284
55285 return UA_WriterGroup_create(server, connection: connectionId, writerGroupConfig: &writerGroupConfig, writerGroupIdentifier: writerGroupId);
55286}
55287
55288/**
55289 * **DataSetWriter handling**
55290 *
55291 * A DataSetWriter (DSW) is the glue between the WG and the PDS. The DSW is
55292 * linked to exactly one PDS and contains additional informations for the
55293 * message generation. */
55294static UA_StatusCode
55295addDataSetWriterConfig(UA_Server *server, const UA_NodeId *writerGroupId,
55296 UA_DataSetWriterDataType *dataSetWriter,
55297 UA_NodeId *dataSetWriterId) {
55298 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55299
55300 UA_NodeId publishedDataSetId = UA_NODEID_NULL;
55301 UA_PublishedDataSet *tmpPDS;
55302 TAILQ_FOREACH(tmpPDS, &server->pubSubManager.publishedDataSets, listEntry){
55303 if(UA_String_equal(p1: &dataSetWriter->dataSetName, p2: &tmpPDS->config.name)) {
55304 publishedDataSetId = tmpPDS->identifier;
55305 break;
55306 }
55307 }
55308
55309 if(UA_NodeId_isNull(p: &publishedDataSetId))
55310 return UA_STATUSCODE_BADPARENTNODEIDINVALID;
55311
55312 /* We need now a DataSetWriter within the WriterGroup. This means we must
55313 * create a new DataSetWriterConfig and add call the addWriterGroup function. */
55314 UA_DataSetWriterConfig dataSetWriterConfig;
55315 memset(s: &dataSetWriterConfig, c: 0, n: sizeof(UA_DataSetWriterConfig));
55316 dataSetWriterConfig.name = dataSetWriter->name;
55317 dataSetWriterConfig.dataSetWriterId = dataSetWriter->dataSetWriterId;
55318 dataSetWriterConfig.keyFrameCount = dataSetWriter->keyFrameCount;
55319 dataSetWriterConfig.dataSetFieldContentMask = dataSetWriter->dataSetFieldContentMask;
55320 return UA_DataSetWriter_create(server, writerGroup: *writerGroupId, dataSet: publishedDataSetId,
55321 dataSetWriterConfig: &dataSetWriterConfig, writerIdentifier: dataSetWriterId);
55322}
55323
55324/**
55325 * **ReaderGroup**
55326 *
55327 * ReaderGroup is used to group a list of DataSetReaders. All ReaderGroups are
55328 * created within a PubSubConnection and automatically deleted if the connection
55329 * is removed. All network message related filters are only available in the DataSetReader. */
55330/* Add ReaderGroup to the created connection */
55331static UA_StatusCode
55332addReaderGroupConfig(UA_Server *server, UA_NodeId connectionId,
55333 UA_ReaderGroupDataType *readerGroup,
55334 UA_NodeId *readerGroupId) {
55335 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55336
55337 UA_ReaderGroupConfig readerGroupConfig;
55338 memset(s: &readerGroupConfig, c: 0, n: sizeof(UA_ReaderGroupConfig));
55339 readerGroupConfig.name = readerGroup->name;
55340 return UA_ReaderGroup_create(server, connectionId,
55341 rgc: &readerGroupConfig, readerGroupId);
55342}
55343
55344/**
55345 * **SubscribedDataSet**
55346 *
55347 * Set SubscribedDataSet type to TargetVariables data type.
55348 * Add subscribedvariables to the DataSetReader */
55349static UA_StatusCode
55350addSubscribedVariables(UA_Server *server, UA_NodeId dataSetReaderId,
55351 UA_DataSetReaderDataType *dataSetReader,
55352 UA_DataSetMetaDataType *pMetaData) {
55353 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55354
55355 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
55356 UA_ExtensionObject *eoTargetVar = &dataSetReader->subscribedDataSet;
55357 if(eoTargetVar->encoding != UA_EXTENSIONOBJECT_DECODED ||
55358 eoTargetVar->content.decoded.type != &UA_TYPES[UA_TYPES_TARGETVARIABLESDATATYPE])
55359 return UA_STATUSCODE_BADUNEXPECTEDERROR;
55360
55361 const UA_TargetVariablesDataType *targetVars =
55362 (UA_TargetVariablesDataType*)eoTargetVar->content.decoded.data;
55363
55364 UA_NodeId folderId;
55365 UA_String folderName = pMetaData->name;
55366 UA_ObjectAttributes oAttr = UA_ObjectAttributes_default;
55367 UA_QualifiedName folderBrowseName;
55368 if(folderName.length > 0) {
55369 oAttr.displayName.locale = UA_STRING(chars: "");
55370 oAttr.displayName.text = folderName;
55371 folderBrowseName.namespaceIndex = 1;
55372 folderBrowseName.name = folderName;
55373 } else {
55374 oAttr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Subscribed Variables");
55375 folderBrowseName = UA_QUALIFIEDNAME(nsIndex: 1, chars: "Subscribed Variables");
55376 }
55377
55378 addNode(server, nodeClass: UA_NODECLASS_OBJECT, requestedNewNodeId: UA_NODEID_NULL,
55379 parentNodeId: UA_NODEID_NUMERIC (nsIndex: 0, UA_NS0ID_OBJECTSFOLDER),
55380 referenceTypeId: UA_NODEID_NUMERIC (nsIndex: 0, UA_NS0ID_ORGANIZES),
55381 browseName: folderBrowseName,
55382 typeDefinition: UA_NODEID_NUMERIC (nsIndex: 0, UA_NS0ID_BASEOBJECTTYPE),
55383 attr: &oAttr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
55384 NULL, outNewNodeId: &folderId);
55385
55386 /* The SubscribedDataSet option TargetVariables defines a list of Variable
55387 * mappings between received DataSet fields and target Variables in the
55388 * Subscriber AddressSpace. The values subscribed from the Publisher are
55389 * updated in the value field of these variables */
55390
55391 /* Create the TargetVariables with respect to DataSetMetaData fields */
55392 UA_FieldTargetVariable *targetVarsData = (UA_FieldTargetVariable *)
55393 UA_calloc(nmemb: targetVars->targetVariablesSize, size: sizeof(UA_FieldTargetVariable));
55394 for(size_t i = 0; i < targetVars->targetVariablesSize; i++) {
55395 /* Prepare the output structure */
55396 UA_FieldTargetDataType_init(p: &targetVarsData[i].targetVariable);
55397 targetVarsData[i].targetVariable.attributeId = targetVars->targetVariables[i].attributeId;
55398
55399 /* Add variable for the field */
55400 UA_VariableAttributes vAttr = UA_VariableAttributes_default;
55401 vAttr.description = pMetaData->fields[i].description;
55402 vAttr.displayName.locale = UA_STRING(chars: "");
55403 vAttr.displayName.text = pMetaData->fields[i].name;
55404 vAttr.dataType = pMetaData->fields[i].dataType;
55405 UA_QualifiedName varname = {1, pMetaData->fields[i].name};
55406 retVal |= addNode(server, nodeClass: UA_NODECLASS_VARIABLE,
55407 requestedNewNodeId: targetVars->targetVariables[i].targetNodeId,
55408 parentNodeId: folderId, referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55409 browseName: varname, typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEDATAVARIABLETYPE),
55410 attr: &vAttr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],
55411 NULL, outNewNodeId: &targetVarsData[i].targetVariable.targetNodeId);
55412
55413 }
55414 UA_DataSetReader *dsr = UA_ReaderGroup_findDSRbyId(server, identifier: dataSetReaderId);
55415 if(dsr) {
55416 retVal = DataSetReader_createTargetVariables(server, dsr,
55417 targetVariablesSize: targetVars->targetVariablesSize,
55418 targetVariables: targetVarsData);
55419 } else {
55420 retVal = UA_STATUSCODE_BADINTERNALERROR;
55421 }
55422 for(size_t j = 0; j < targetVars->targetVariablesSize; j++)
55423 UA_FieldTargetDataType_clear(p: &targetVarsData[j].targetVariable);
55424 UA_free(ptr: targetVarsData);
55425 return retVal;
55426}
55427
55428/**
55429 * **DataSetReader**
55430 *
55431 * DataSetReader can receive NetworkMessages with the DataSetMessage
55432 * of interest sent by the Publisher. DataSetReader provides
55433 * the configuration necessary to receive and process DataSetMessages
55434 * on the Subscriber side. DataSetReader must be linked with a
55435 * SubscribedDataSet and be contained within a ReaderGroup. */
55436static UA_StatusCode
55437addDataSetReaderConfig(UA_Server *server, UA_NodeId readerGroupId,
55438 UA_DataSetReaderDataType *dataSetReader,
55439 UA_NodeId *dataSetReaderId) {
55440 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55441
55442 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
55443 UA_DataSetReaderConfig readerConfig;
55444 memset(s: &readerConfig, c: 0, n: sizeof(UA_DataSetReaderConfig));
55445 readerConfig.name = dataSetReader->name;
55446 readerConfig.publisherId = dataSetReader->publisherId;
55447 readerConfig.writerGroupId = dataSetReader->writerGroupId;
55448 readerConfig.dataSetWriterId = dataSetReader->dataSetWriterId;
55449
55450 /* Setting up Meta data configuration in DataSetReader */
55451 UA_DataSetMetaDataType *pMetaData;
55452 pMetaData = &readerConfig.dataSetMetaData;
55453 UA_DataSetMetaDataType_init (p: pMetaData);
55454 pMetaData->name = dataSetReader->dataSetMetaData.name;
55455 pMetaData->fieldsSize = dataSetReader->dataSetMetaData.fieldsSize;
55456 pMetaData->fields = (UA_FieldMetaData*)UA_Array_new (size: pMetaData->fieldsSize,
55457 type: &UA_TYPES[UA_TYPES_FIELDMETADATA]);
55458 for(size_t i = 0; i < pMetaData->fieldsSize; i++){
55459 UA_FieldMetaData_init (p: &pMetaData->fields[i]);
55460 UA_NodeId_copy (src: &dataSetReader->dataSetMetaData.fields[i].dataType,
55461 dst: &pMetaData->fields[i].dataType);
55462 pMetaData->fields[i].builtInType = dataSetReader->dataSetMetaData.fields[i].builtInType;
55463 pMetaData->fields[i].name = dataSetReader->dataSetMetaData.fields[i].name;
55464 pMetaData->fields[i].valueRank = dataSetReader->dataSetMetaData.fields[i].valueRank;
55465 }
55466
55467 retVal |= UA_DataSetReader_create(server, readerGroupIdentifier: readerGroupId,
55468 dataSetReaderConfig: &readerConfig, readerIdentifier: dataSetReaderId);
55469 if(retVal != UA_STATUSCODE_GOOD) {
55470 UA_free(ptr: pMetaData->fields);
55471 return retVal;
55472 }
55473
55474 retVal |= addSubscribedVariables(server, dataSetReaderId: *dataSetReaderId, dataSetReader, pMetaData);
55475 UA_free(ptr: pMetaData->fields);
55476 return retVal;
55477}
55478
55479/*************************************************/
55480/* PubSubConnection */
55481/*************************************************/
55482
55483UA_StatusCode
55484addPubSubConnectionRepresentation(UA_Server *server, UA_PubSubConnection *connection) {
55485 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
55486 if(connection->config.name.length > 512)
55487 return UA_STATUSCODE_BADOUTOFMEMORY;
55488 char connectionName[513];
55489 memcpy(dest: connectionName, src: connection->config.name.data, n: connection->config.name.length);
55490 connectionName[connection->config.name.length] = '\0';
55491
55492 UA_ObjectAttributes attr = UA_ObjectAttributes_default;
55493 attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: connectionName);
55494 retVal |= addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
55495 requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 1, identifier: 0), /* Generate a new id */
55496 parentNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE),
55497 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPUBSUBCONNECTION),
55498 browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: connectionName),
55499 typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBSUBCONNECTIONTYPE),
55500 attr: (const UA_NodeAttributes*)&attr,
55501 attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
55502 NULL, outNewNodeId: &connection->identifier);
55503
55504 attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Address");
55505 retVal |= addNode(server, nodeClass: UA_NODECLASS_OBJECT, requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 1, identifier: 0),
55506 parentNodeId: connection->identifier, referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55507 browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "Address"),
55508 typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_NETWORKADDRESSURLTYPE),
55509 attr: &attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], NULL, NULL);
55510
55511 retVal |= addNode_finish(server, session: &server->adminSession, nodeId: &connection->identifier);
55512
55513 UA_NodeId addressNode =
55514 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "Address"),
55515 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55516 startingNode: connection->identifier);
55517 UA_NodeId urlNode =
55518 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "Url"),
55519 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT), startingNode: addressNode);
55520 UA_NodeId interfaceNode =
55521 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "NetworkInterface"),
55522 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT), startingNode: addressNode);
55523 UA_NodeId publisherIdNode =
55524 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "PublisherId"),
55525 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY), startingNode: connection->identifier);
55526 UA_NodeId connectionPropertyNode =
55527 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "ConnectionProperties"),
55528 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
55529 startingNode: connection->identifier);
55530 UA_NodeId transportProfileUri =
55531 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "TransportProfileUri"),
55532 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55533 startingNode: connection->identifier);
55534
55535 if(UA_NodeId_isNull(p: &addressNode) || UA_NodeId_isNull(p: &urlNode) ||
55536 UA_NodeId_isNull(p: &interfaceNode) || UA_NodeId_isNull(p: &publisherIdNode) ||
55537 UA_NodeId_isNull(p: &connectionPropertyNode) ||
55538 UA_NodeId_isNull(p: &transportProfileUri)) {
55539 return UA_STATUSCODE_BADNOTFOUND;
55540 }
55541
55542 retVal |= writePubSubNs0VariableArray(server, id: connectionPropertyNode,
55543 v: connection->config.connectionProperties.map,
55544 length: connection->config.connectionProperties.mapSize,
55545 type: &UA_TYPES[UA_TYPES_KEYVALUEPAIR]);
55546
55547 UA_NetworkAddressUrlDataType *networkAddressUrl=
55548 ((UA_NetworkAddressUrlDataType*)connection->config.address.data);
55549 UA_Variant value;
55550 UA_Variant_init(p: &value);
55551
55552 UA_Variant_setScalar(v: &value, p: &networkAddressUrl->url, type: &UA_TYPES[UA_TYPES_STRING]);
55553 writeValueAttribute(server, nodeId: urlNode, value: &value);
55554
55555 UA_Variant_setScalar(v: &value, p: &networkAddressUrl->networkInterface, type: &UA_TYPES[UA_TYPES_STRING]);
55556 writeValueAttribute(server, nodeId: interfaceNode, value: &value);
55557
55558 UA_Variant_setScalar(v: &value, p: &connection->config.transportProfileUri, type: &UA_TYPES[UA_TYPES_STRING]);
55559 writeValueAttribute(server, nodeId: transportProfileUri, value: &value);
55560
55561 UA_NodePropertyContext *connectionPublisherIdContext =
55562 (UA_NodePropertyContext *)UA_malloc(size: sizeof(UA_NodePropertyContext));
55563 connectionPublisherIdContext->parentNodeId = connection->identifier;
55564 connectionPublisherIdContext->parentClassifier = UA_NS0ID_PUBSUBCONNECTIONTYPE;
55565 connectionPublisherIdContext->elementClassiefier =
55566 UA_NS0ID_PUBSUBCONNECTIONTYPE_PUBLISHERID;
55567 UA_ValueCallback valueCallback;
55568 valueCallback.onRead = onRead;
55569 valueCallback.onWrite = NULL;
55570 retVal |= addVariableValueSource(server, valueCallback, node: publisherIdNode,
55571 context: connectionPublisherIdContext);
55572
55573 if(server->config.pubSubConfig.enableInformationModelMethods) {
55574 retVal |= addRef(server, sourceId: connection->identifier,
55575 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55576 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDWRITERGROUP), true);
55577 retVal |= addRef(server, sourceId: connection->identifier,
55578 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55579 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDREADERGROUP), true);
55580 retVal |= addRef(server, sourceId: connection->identifier,
55581 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55582 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBSUBCONNECTIONTYPE_REMOVEGROUP), true);
55583 }
55584 return retVal;
55585}
55586
55587static UA_StatusCode
55588addPubSubConnectionLocked(UA_Server *server,
55589 const UA_NodeId *sessionId, void *sessionHandle,
55590 const UA_NodeId *methodId, void *methodContext,
55591 const UA_NodeId *objectId, void *objectContext,
55592 size_t inputSize, const UA_Variant *input,
55593 size_t outputSize, UA_Variant *output) {
55594 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55595
55596 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
55597 UA_PubSubConnectionDataType *pubSubConnection =
55598 (UA_PubSubConnectionDataType *) input[0].data;
55599
55600 //call API function and create the connection
55601 UA_NodeId connectionId;
55602 retVal |= addPubSubConnectionConfig(server, pubsubConnection: pubSubConnection, connectionId: &connectionId);
55603 if(retVal != UA_STATUSCODE_GOOD) {
55604 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55605 msg: "addPubSubConnection failed");
55606 return retVal;
55607 }
55608
55609 for(size_t i = 0; i < pubSubConnection->writerGroupsSize; i++) {
55610 UA_NodeId writerGroupId;
55611 UA_WriterGroupDataType *writerGroup = &pubSubConnection->writerGroups[i];
55612 retVal |= addWriterGroupConfig(server, connectionId, writerGroup, writerGroupId: &writerGroupId);
55613 if(retVal != UA_STATUSCODE_GOOD) {
55614 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55615 msg: "addWriterGroup failed");
55616 return retVal;
55617 }
55618
55619 for(size_t j = 0; j < writerGroup->dataSetWritersSize; j++) {
55620 UA_DataSetWriterDataType *dataSetWriter = &writerGroup->dataSetWriters[j];
55621 retVal |= addDataSetWriterConfig(server, writerGroupId: &writerGroupId, dataSetWriter, NULL);
55622 if(retVal != UA_STATUSCODE_GOOD) {
55623 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55624 msg: "addDataSetWriter failed");
55625 return retVal;
55626 }
55627 }
55628
55629 /* TODO: Need to handle the UA_Server_setWriterGroupOperational based on
55630 * the status variable in information model */
55631 UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, identifier: writerGroupId);
55632 if(!wg)
55633 continue;
55634 if(pubSubConnection->enabled) {
55635 UA_WriterGroup_freezeConfiguration(server, wg);
55636 UA_WriterGroup_setPubSubState(server, writerGroup: wg, state: UA_PUBSUBSTATE_OPERATIONAL,
55637 UA_STATUSCODE_GOOD);
55638 } else {
55639 UA_WriterGroup_setPubSubState(server, writerGroup: wg, state: UA_PUBSUBSTATE_DISABLED,
55640 UA_STATUSCODE_BADINTERNALERROR);
55641 }
55642 }
55643
55644 for(size_t i = 0; i < pubSubConnection->readerGroupsSize; i++){
55645 UA_NodeId readerGroupId;
55646 UA_ReaderGroupDataType *readerGroup = &pubSubConnection->readerGroups[i];
55647 retVal |= addReaderGroupConfig(server, connectionId, readerGroup, readerGroupId: &readerGroupId);
55648 if(retVal != UA_STATUSCODE_GOOD) {
55649 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55650 msg: "addReaderGroup failed");
55651 return retVal;
55652 }
55653
55654 for(size_t j = 0; j < readerGroup->dataSetReadersSize; j++) {
55655 UA_NodeId dataSetReaderId;
55656 UA_DataSetReaderDataType *dataSetReader = &readerGroup->dataSetReaders[j];
55657 retVal |= addDataSetReaderConfig(server, readerGroupId,
55658 dataSetReader, dataSetReaderId: &dataSetReaderId);
55659 if(retVal != UA_STATUSCODE_GOOD) {
55660 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55661 msg: "addDataSetReader failed");
55662 return retVal;
55663 }
55664
55665 }
55666
55667 /* TODO: Need to handle the UA_Server_setReaderGroupOperational based on
55668 * the status variable in information model */
55669 UA_ReaderGroup *rg = UA_ReaderGroup_findRGbyId(server, identifier: readerGroupId);
55670 if(!rg)
55671 continue;
55672 if(pubSubConnection->enabled) {
55673 UA_ReaderGroup_freezeConfiguration(server, rg);
55674 UA_ReaderGroup_setPubSubState(server, readerGroup: rg, state: UA_PUBSUBSTATE_OPERATIONAL,
55675 UA_STATUSCODE_GOOD);
55676 } else {
55677 UA_ReaderGroup_setPubSubState(server, readerGroup: rg, state: UA_PUBSUBSTATE_DISABLED,
55678 UA_STATUSCODE_BADINTERNALERROR);
55679 }
55680 }
55681
55682 /* Set ouput value */
55683 UA_Variant_setScalarCopy(v: output, p: &connectionId, type: &UA_TYPES[UA_TYPES_NODEID]);
55684 return UA_STATUSCODE_GOOD;
55685}
55686
55687static UA_StatusCode
55688addPubSubConnectionAction(UA_Server *server,
55689 const UA_NodeId *sessionId, void *sessionHandle,
55690 const UA_NodeId *methodId, void *methodContext,
55691 const UA_NodeId *objectId, void *objectContext,
55692 size_t inputSize, const UA_Variant *input,
55693 size_t outputSize, UA_Variant *output) {
55694 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55695 return addPubSubConnectionLocked(server, sessionId, sessionHandle,
55696 methodId, methodContext,
55697 objectId, objectContext,
55698 inputSize, input, outputSize, output);
55699}
55700
55701static UA_StatusCode
55702removeConnectionAction(UA_Server *server,
55703 const UA_NodeId *sessionId, void *sessionHandle,
55704 const UA_NodeId *methodId, void *methodContext,
55705 const UA_NodeId *objectId, void *objectContext,
55706 size_t inputSize, const UA_Variant *input,
55707 size_t outputSize, UA_Variant *output){
55708 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
55709 UA_NodeId nodeToRemove = *((UA_NodeId *) input[0].data);
55710 retVal |= UA_Server_removePubSubConnection(server, connection: nodeToRemove);
55711 if(retVal == UA_STATUSCODE_BADNOTFOUND)
55712 retVal = UA_STATUSCODE_BADNODEIDUNKNOWN;
55713 return retVal;
55714}
55715
55716/**********************************************/
55717/* DataSetReader */
55718/**********************************************/
55719
55720UA_StatusCode
55721addDataSetReaderRepresentation(UA_Server *server, UA_DataSetReader *dataSetReader){
55722 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55723
55724 if(dataSetReader->config.name.length > 512)
55725 return UA_STATUSCODE_BADCONFIGURATIONERROR;
55726
55727 char dsrName[513];
55728 memcpy(dest: dsrName, src: dataSetReader->config.name.data, n: dataSetReader->config.name.length);
55729 dsrName[dataSetReader->config.name.length] = '\0';
55730
55731 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
55732 UA_NodeId publisherIdNode, writerGroupIdNode, dataSetwriterIdNode;
55733
55734 UA_ObjectAttributes object_attr = UA_ObjectAttributes_default;
55735 object_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: dsrName);
55736 retVal = addNode(server, nodeClass: UA_NODECLASS_OBJECT, requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 1, identifier: 0), /* create an id */
55737 parentNodeId: dataSetReader->linkedReaderGroup,
55738 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASDATASETREADER),
55739 browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: dsrName),
55740 typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETREADERTYPE),
55741 attr: &object_attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
55742 NULL, outNewNodeId: &dataSetReader->identifier);
55743
55744 /* Add childNodes such as PublisherId, WriterGroupId and DataSetWriterId in
55745 * DataSetReader object */
55746 publisherIdNode = findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "PublisherId"),
55747 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
55748 startingNode: dataSetReader->identifier);
55749 writerGroupIdNode = findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "WriterGroupId"),
55750 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
55751 startingNode: dataSetReader->identifier);
55752 dataSetwriterIdNode = findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "DataSetWriterId"),
55753 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
55754 startingNode: dataSetReader->identifier);
55755
55756 if(UA_NodeId_isNull(p: &publisherIdNode) ||
55757 UA_NodeId_isNull(p: &writerGroupIdNode) ||
55758 UA_NodeId_isNull(p: &dataSetwriterIdNode)) {
55759 return UA_STATUSCODE_BADNOTFOUND;
55760 }
55761
55762 UA_NodePropertyContext *dataSetReaderPublisherIdContext =
55763 (UA_NodePropertyContext *) UA_malloc(size: sizeof(UA_NodePropertyContext));
55764 dataSetReaderPublisherIdContext->parentNodeId = dataSetReader->identifier;
55765 dataSetReaderPublisherIdContext->parentClassifier = UA_NS0ID_DATASETREADERTYPE;
55766 dataSetReaderPublisherIdContext->elementClassiefier = UA_NS0ID_DATASETREADERTYPE_PUBLISHERID;
55767 UA_ValueCallback valueCallback;
55768 valueCallback.onRead = onRead;
55769 valueCallback.onWrite = NULL;
55770 retVal |= addVariableValueSource(server, valueCallback, node: publisherIdNode,
55771 context: dataSetReaderPublisherIdContext);
55772
55773 /* Update childNode with values from Publisher */
55774 UA_Variant value;
55775 UA_Variant_init(p: &value);
55776 UA_Variant_setScalar(v: &value, p: &dataSetReader->config.writerGroupId,
55777 type: &UA_TYPES[UA_TYPES_UINT16]);
55778 writeValueAttribute(server, nodeId: writerGroupIdNode, value: &value);
55779 UA_Variant_setScalar(v: &value, p: &dataSetReader->config.dataSetWriterId,
55780 type: &UA_TYPES[UA_TYPES_UINT16]);
55781 writeValueAttribute(server, nodeId: dataSetwriterIdNode, value: &value);
55782 return retVal;
55783}
55784
55785static UA_StatusCode
55786addDataSetReaderLocked(UA_Server *server,
55787 const UA_NodeId *sessionId, void *sessionHandle,
55788 const UA_NodeId *methodId, void *methodContext,
55789 const UA_NodeId *objectId, void *objectContext,
55790 size_t inputSize, const UA_Variant *input,
55791 size_t outputSize, UA_Variant *output){
55792 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55793 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
55794 UA_ReaderGroup *rg = UA_ReaderGroup_findRGbyId(server, identifier: *objectId);
55795 if(rg->configurationFrozen) {
55796 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55797 msg: "AddDataSetReader cannot be done because ReaderGroup config frozen");
55798 return UA_STATUSCODE_BAD;
55799 }
55800
55801 UA_NodeId dataSetReaderId;
55802 UA_DataSetReaderDataType *dataSetReader= (UA_DataSetReaderDataType *) input[0].data;
55803 retVal |= addDataSetReaderConfig(server, readerGroupId: *objectId, dataSetReader, dataSetReaderId: &dataSetReaderId);
55804 if(retVal != UA_STATUSCODE_GOOD) {
55805 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
55806 msg: "AddDataSetReader failed");
55807 return retVal;
55808 }
55809
55810 UA_Variant_setScalarCopy(v: output, p: &dataSetReaderId, type: &UA_TYPES[UA_TYPES_NODEID]);
55811 return retVal;
55812}
55813
55814static UA_StatusCode
55815addDataSetReaderAction(UA_Server *server,
55816 const UA_NodeId *sessionId, void *sessionHandle,
55817 const UA_NodeId *methodId, void *methodContext,
55818 const UA_NodeId *objectId, void *objectContext,
55819 size_t inputSize, const UA_Variant *input,
55820 size_t outputSize, UA_Variant *output){
55821 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55822 return addDataSetReaderLocked(server, sessionId, sessionHandle,
55823 methodId, methodContext, objectId, objectContext,
55824 inputSize, input, outputSize, output);
55825}
55826
55827static UA_StatusCode
55828removeDataSetReaderAction(UA_Server *server,
55829 const UA_NodeId *sessionId, void *sessionHandle,
55830 const UA_NodeId *methodId, void *methodContext,
55831 const UA_NodeId *objectId, void *objectContext,
55832 size_t inputSize, const UA_Variant *input,
55833 size_t outputSize, UA_Variant *output){
55834 UA_NodeId nodeToRemove = *((UA_NodeId *)input[0].data);
55835 return UA_Server_removeDataSetReader(server, readerIdentifier: nodeToRemove);
55836}
55837
55838/*************************************************/
55839/* PublishedDataSet */
55840/*************************************************/
55841static UA_StatusCode
55842addDataSetFolderAction(UA_Server *server,
55843 const UA_NodeId *sessionId, void *sessionHandle,
55844 const UA_NodeId *methodId, void *methodContext,
55845 const UA_NodeId *objectId, void *objectContext,
55846 size_t inputSize, const UA_Variant *input,
55847 size_t outputSize, UA_Variant *output){
55848 /* defined in R 1.04 9.1.4.5.7 */
55849 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
55850 UA_String newFolderName = *((UA_String *) input[0].data);
55851 UA_NodeId generatedId;
55852 UA_ObjectAttributes objectAttributes = UA_ObjectAttributes_default;
55853 UA_LocalizedText name = {UA_STRING(chars: ""), newFolderName};
55854 objectAttributes.displayName = name;
55855 retVal |= UA_Server_addObjectNode(server, requestedNewNodeId: UA_NODEID_NULL, parentNodeId: *objectId,
55856 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0,UA_NS0ID_ORGANIZES),
55857 browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "DataSetFolder"),
55858 typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETFOLDERTYPE),
55859 attr: objectAttributes, NULL, outNewNodeId: &generatedId);
55860 UA_Variant_setScalarCopy(v: output, p: &generatedId, type: &UA_TYPES[UA_TYPES_NODEID]);
55861
55862 if(server->config.pubSubConfig.enableInformationModelMethods) {
55863 retVal |= UA_Server_addReference(server, sourceId: generatedId,
55864 refTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55865 targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMS), true);
55866 retVal |= UA_Server_addReference(server, sourceId: generatedId,
55867 refTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55868 targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEPUBLISHEDDATASET), true);
55869 retVal |= UA_Server_addReference(server, sourceId: generatedId,
55870 refTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55871 targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETFOLDERTYPE_ADDDATASETFOLDER), true);
55872 retVal |= UA_Server_addReference(server, sourceId: generatedId,
55873 refTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55874 targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEDATASETFOLDER), true);
55875 }
55876 return retVal;
55877}
55878
55879static UA_StatusCode
55880removeDataSetFolderAction(UA_Server *server,
55881 const UA_NodeId *sessionId, void *sessionHandle,
55882 const UA_NodeId *methodId, void *methodContext,
55883 const UA_NodeId *objectId, void *objectContext,
55884 size_t inputSize, const UA_Variant *input,
55885 size_t outputSize, UA_Variant *output) {
55886 UA_NodeId nodeToRemove = *((UA_NodeId *) input[0].data);
55887 return UA_Server_deleteNode(server, nodeId: nodeToRemove, true);
55888}
55889
55890UA_StatusCode
55891addPublishedDataItemsRepresentation(UA_Server *server,
55892 UA_PublishedDataSet *publishedDataSet) {
55893 UA_LOCK_ASSERT(&server->serviceMutex, 1);
55894
55895 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
55896 if(publishedDataSet->config.name.length > 512)
55897 return UA_STATUSCODE_BADOUTOFMEMORY;
55898 char pdsName[513];
55899 memcpy(dest: pdsName, src: publishedDataSet->config.name.data, n: publishedDataSet->config.name.length);
55900 pdsName[publishedDataSet->config.name.length] = '\0';
55901
55902 UA_ObjectAttributes object_attr = UA_ObjectAttributes_default;
55903 object_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: pdsName);
55904 retVal = addNode(server, nodeClass: UA_NODECLASS_OBJECT, requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 1, identifier: 0), /* Create a new id */
55905 parentNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS),
55906 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55907 browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: pdsName),
55908 typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHEDDATAITEMSTYPE),
55909 attr: &object_attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
55910 NULL, outNewNodeId: &publishedDataSet->identifier);
55911 UA_CHECK_STATUS(retVal, return retVal);
55912
55913 UA_ValueCallback valueCallback;
55914 valueCallback.onRead = onRead;
55915 valueCallback.onWrite = NULL;
55916 //ToDo: Need to move the browse name from namespaceindex 0 to 1
55917 UA_NodeId configurationVersionNode =
55918 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "ConfigurationVersion"),
55919 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
55920 startingNode: publishedDataSet->identifier);
55921 if(UA_NodeId_isNull(p: &configurationVersionNode))
55922 return UA_STATUSCODE_BADNOTFOUND;
55923
55924 UA_NodePropertyContext *configurationVersionContext = (UA_NodePropertyContext *)
55925 UA_malloc(size: sizeof(UA_NodePropertyContext));
55926 configurationVersionContext->parentNodeId = publishedDataSet->identifier;
55927 configurationVersionContext->parentClassifier = UA_NS0ID_PUBLISHEDDATAITEMSTYPE;
55928 configurationVersionContext->elementClassiefier =
55929 UA_NS0ID_PUBLISHEDDATAITEMSTYPE_CONFIGURATIONVERSION;
55930 retVal |= addVariableValueSource(server, valueCallback, node: configurationVersionNode,
55931 context: configurationVersionContext);
55932
55933 UA_NodeId publishedDataNode =
55934 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "PublishedData"),
55935 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
55936 startingNode: publishedDataSet->identifier);
55937 if(UA_NodeId_isNull(p: &publishedDataNode))
55938 return UA_STATUSCODE_BADNOTFOUND;
55939
55940 UA_NodePropertyContext * publishingIntervalContext = (UA_NodePropertyContext *)
55941 UA_malloc(size: sizeof(UA_NodePropertyContext));
55942 publishingIntervalContext->parentNodeId = publishedDataSet->identifier;
55943 publishingIntervalContext->parentClassifier = UA_NS0ID_PUBLISHEDDATAITEMSTYPE;
55944 publishingIntervalContext->elementClassiefier = UA_NS0ID_PUBLISHEDDATAITEMSTYPE_PUBLISHEDDATA;
55945 retVal |= addVariableValueSource(server, valueCallback, node: publishedDataNode,
55946 context: publishingIntervalContext);
55947
55948 UA_NodeId dataSetMetaDataNode =
55949 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "DataSetMetaData"),
55950 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
55951 startingNode: publishedDataSet->identifier);
55952 if(UA_NodeId_isNull(p: &dataSetMetaDataNode))
55953 return UA_STATUSCODE_BADNOTFOUND;
55954
55955 UA_NodePropertyContext *metaDataContext = (UA_NodePropertyContext *)
55956 UA_malloc(size: sizeof(UA_NodePropertyContext));
55957 metaDataContext->parentNodeId = publishedDataSet->identifier;
55958 metaDataContext->parentClassifier = UA_NS0ID_PUBLISHEDDATAITEMSTYPE;
55959 metaDataContext->elementClassiefier = UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETMETADATA;
55960 retVal |= addVariableValueSource(server, valueCallback,
55961 node: dataSetMetaDataNode, context: metaDataContext);
55962
55963 if(server->config.pubSubConfig.enableInformationModelMethods) {
55964 retVal |= addRef(server, sourceId: publishedDataSet->identifier,
55965 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55966 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHEDDATAITEMSTYPE_ADDVARIABLES), true);
55967 retVal |= addRef(server, sourceId: publishedDataSet->identifier,
55968 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
55969 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHEDDATAITEMSTYPE_REMOVEVARIABLES), true);
55970 }
55971 return retVal;
55972}
55973
55974static UA_StatusCode
55975addPublishedDataItemsAction(UA_Server *server,
55976 const UA_NodeId *sessionId, void *sessionHandle,
55977 const UA_NodeId *methodId, void *methodContext,
55978 const UA_NodeId *objectId, void *objectContext,
55979 size_t inputSize, const UA_Variant *input,
55980 size_t outputSize, UA_Variant *output){
55981 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
55982 size_t fieldNameAliasesSize = input[1].arrayLength;
55983 UA_String * fieldNameAliases = (UA_String *) input[1].data;
55984 size_t fieldFlagsSize = input[2].arrayLength;
55985 UA_DataSetFieldFlags * fieldFlags = (UA_DataSetFieldFlags *) input[2].data;
55986 size_t variablesToAddSize = input[3].arrayLength;
55987 UA_PublishedVariableDataType *eoAddVar =
55988 (UA_PublishedVariableDataType *)input[3].data;
55989
55990 if(fieldNameAliasesSize != fieldFlagsSize ||
55991 fieldFlagsSize != variablesToAddSize)
55992 return UA_STATUSCODE_BADINVALIDARGUMENT;
55993
55994 UA_PublishedDataSetConfig publishedDataSetConfig;
55995 memset(s: &publishedDataSetConfig, c: 0, n: sizeof(publishedDataSetConfig));
55996 publishedDataSetConfig.name = *((UA_String *) input[0].data);
55997 publishedDataSetConfig.publishedDataSetType = UA_PUBSUB_DATASET_PUBLISHEDITEMS;
55998
55999 UA_NodeId dataSetItemsNodeId;
56000 retVal |= UA_Server_addPublishedDataSet(server, publishedDataSetConfig: &publishedDataSetConfig,
56001 pdsIdentifier: &dataSetItemsNodeId).addResult;
56002 if(retVal != UA_STATUSCODE_GOOD) {
56003 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
56004 msg: "addPublishedDataset failed");
56005 return retVal;
56006 }
56007
56008 UA_DataSetFieldConfig dataSetFieldConfig;
56009 for(size_t j = 0; j < variablesToAddSize; ++j) {
56010 /* Prepare the config */
56011 memset(s: &dataSetFieldConfig, c: 0, n: sizeof(UA_DataSetFieldConfig));
56012 dataSetFieldConfig.dataSetFieldType = UA_PUBSUB_DATASETFIELD_VARIABLE;
56013 dataSetFieldConfig.field.variable.fieldNameAlias = fieldNameAliases[j];
56014 dataSetFieldConfig.field.variable.publishParameters = eoAddVar[j];
56015 if(fieldFlags[j] == UA_DATASETFIELDFLAGS_PROMOTEDFIELD)
56016 dataSetFieldConfig.field.variable.promotedField = true;
56017 retVal |= UA_Server_addDataSetField(server, publishedDataSet: dataSetItemsNodeId,
56018 fieldConfig: &dataSetFieldConfig, NULL).result;
56019 if(retVal != UA_STATUSCODE_GOOD) {
56020 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
56021 msg: "addDataSetField failed");
56022 return retVal;
56023 }
56024 }
56025
56026 UA_Variant_setScalarCopy(v: output, p: &dataSetItemsNodeId, type: &UA_TYPES[UA_TYPES_NODEID]);
56027 return retVal;
56028}
56029
56030static UA_StatusCode
56031addVariablesAction(UA_Server *server,
56032 const UA_NodeId *sessionId, void *sessionHandle,
56033 const UA_NodeId *methodId, void *methodContext,
56034 const UA_NodeId *objectId, void *objectContext,
56035 size_t inputSize, const UA_Variant *input,
56036 size_t outputSize, UA_Variant *output){
56037 return UA_STATUSCODE_GOOD;
56038}
56039
56040static UA_StatusCode
56041removeVariablesAction(UA_Server *server,
56042 const UA_NodeId *sessionId, void *sessionHandle,
56043 const UA_NodeId *methodId, void *methodContext,
56044 const UA_NodeId *objectId, void *objectContext,
56045 size_t inputSize, const UA_Variant *input,
56046 size_t outputSize, UA_Variant *output){
56047 return UA_STATUSCODE_GOOD;
56048}
56049
56050static UA_StatusCode
56051removePublishedDataSetAction(UA_Server *server,
56052 const UA_NodeId *sessionId, void *sessionHandle,
56053 const UA_NodeId *methodId, void *methodContext,
56054 const UA_NodeId *objectId, void *objectContext,
56055 size_t inputSize, const UA_Variant *input,
56056 size_t outputSize, UA_Variant *output){
56057 UA_NodeId nodeToRemove = *((UA_NodeId *) input[0].data);
56058 return UA_Server_removePublishedDataSet(server, pds: nodeToRemove);
56059}
56060
56061/**********************************************/
56062/* StandaloneSubscribedDataSet */
56063/**********************************************/
56064
56065UA_StatusCode
56066addStandaloneSubscribedDataSetRepresentation(UA_Server *server,
56067 UA_StandaloneSubscribedDataSet *subscribedDataSet) {
56068 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56069
56070 UA_StatusCode ret = UA_STATUSCODE_GOOD;
56071 if(subscribedDataSet->config.name.length > 512)
56072 return UA_STATUSCODE_BADCONFIGURATIONERROR;
56073
56074 UA_STACKARRAY(char, sdsName, sizeof(char) * subscribedDataSet->config.name.length +1);
56075 memcpy(dest: sdsName, src: subscribedDataSet->config.name.data, n: subscribedDataSet->config.name.length);
56076 sdsName[subscribedDataSet->config.name.length] = '\0';
56077
56078 UA_ObjectAttributes object_attr = UA_ObjectAttributes_default;
56079 object_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: sdsName);
56080 addNode(server, nodeClass: UA_NODECLASS_OBJECT, requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 1, identifier: 0), /* Create a new id */
56081 parentNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE_SUBSCRIBEDDATASETS),
56082 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
56083 browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: sdsName),
56084 typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_STANDALONESUBSCRIBEDDATASETTYPE),
56085 attr: &object_attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
56086 NULL, outNewNodeId: &subscribedDataSet->identifier);
56087 UA_NodeId sdsObjectNode = findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "SubscribedDataSet"),
56088 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
56089 startingNode: subscribedDataSet->identifier);
56090 UA_NodeId metaDataId = findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "DataSetMetaData"),
56091 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
56092 startingNode: subscribedDataSet->identifier);
56093 UA_NodeId connectedId = findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "IsConnected"),
56094 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
56095 startingNode: subscribedDataSet->identifier);
56096
56097 if(UA_NodeId_equal(p1: &sdsObjectNode, p2: &UA_NODEID_NULL) ||
56098 UA_NodeId_equal(p1: &metaDataId, p2: &UA_NODEID_NULL) ||
56099 UA_NodeId_equal(p1: &connectedId, p2: &UA_NODEID_NULL)) {
56100 return UA_STATUSCODE_BADNOTFOUND;
56101 }
56102 if(subscribedDataSet->config.subscribedDataSetType == UA_PUBSUB_SDS_TARGET){
56103 UA_VariableAttributes attr = UA_VariableAttributes_default;
56104 UA_NodeId targetVarsId;
56105 attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TargetVariables");
56106 attr.dataType = UA_TYPES[UA_TYPES_FIELDTARGETDATATYPE].typeId;
56107 attr.valueRank = UA_VALUERANK_ONE_DIMENSION;
56108 attr.arrayDimensionsSize = 1;
56109 UA_UInt32 arrayDimensions[1];
56110 arrayDimensions[0] = (UA_UInt32)
56111 subscribedDataSet->config.subscribedDataSet.target.targetVariablesSize;
56112 attr.arrayDimensions = arrayDimensions;
56113 attr.accessLevel = UA_ACCESSLEVELMASK_READ;
56114 UA_Variant_setArray(v: &attr.value,
56115 array: subscribedDataSet->config.subscribedDataSet.target.targetVariables,
56116 arraySize: subscribedDataSet->config.subscribedDataSet.target.targetVariablesSize,
56117 type: &UA_TYPES[UA_TYPES_FIELDTARGETDATATYPE]);
56118 ret |= addNode(server, nodeClass: UA_NODECLASS_VARIABLE, requestedNewNodeId: UA_NODEID_NULL, parentNodeId: sdsObjectNode,
56119 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
56120 browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "TargetVariables"),
56121 typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PROPERTYTYPE),
56122 attr: &attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],
56123 NULL, outNewNodeId: &targetVarsId);
56124 }
56125
56126 UA_NodePropertyContext *isConnectedNodeContext = (UA_NodePropertyContext *)
56127 UA_malloc(size: sizeof(UA_NodePropertyContext));
56128 isConnectedNodeContext->parentNodeId = subscribedDataSet->identifier;
56129 isConnectedNodeContext->parentClassifier = UA_NS0ID_STANDALONESUBSCRIBEDDATASETREFDATATYPE;
56130 isConnectedNodeContext->elementClassiefier = UA_NS0ID_STANDALONESUBSCRIBEDDATASETTYPE_ISCONNECTED;
56131
56132 UA_ValueCallback valueCallback;
56133 valueCallback.onRead = onRead;
56134 valueCallback.onWrite = NULL;
56135 ret |= addVariableValueSource(server, valueCallback, node: connectedId, context: isConnectedNodeContext);
56136
56137 UA_NodePropertyContext *metaDataContext = (UA_NodePropertyContext *)
56138 UA_malloc(size: sizeof(UA_NodePropertyContext));
56139 metaDataContext->parentNodeId = subscribedDataSet->identifier;
56140 metaDataContext->parentClassifier = UA_NS0ID_STANDALONESUBSCRIBEDDATASETREFDATATYPE;
56141 metaDataContext->elementClassiefier = UA_NS0ID_STANDALONESUBSCRIBEDDATASETTYPE_DATASETMETADATA;
56142 ret |= addVariableValueSource(server, valueCallback, node: metaDataId, context: metaDataContext);
56143
56144 return ret;
56145}
56146
56147/**********************************************/
56148/* WriterGroup */
56149/**********************************************/
56150
56151static UA_StatusCode
56152readContentMask(UA_Server *server, const UA_NodeId *sessionId,
56153 void *sessionContext, const UA_NodeId *nodeId,
56154 void *nodeContext, UA_Boolean includeSourceTimeStamp,
56155 const UA_NumericRange *range, UA_DataValue *value) {
56156 UA_WriterGroup *writerGroup = (UA_WriterGroup*)nodeContext;
56157 if((writerGroup->config.messageSettings.encoding != UA_EXTENSIONOBJECT_DECODED &&
56158 writerGroup->config.messageSettings.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) ||
56159 writerGroup->config.messageSettings.content.decoded.type !=
56160 &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE])
56161 return UA_STATUSCODE_BADINTERNALERROR;
56162 UA_UadpWriterGroupMessageDataType *wgm = (UA_UadpWriterGroupMessageDataType*)
56163 writerGroup->config.messageSettings.content.decoded.data;
56164
56165 UA_Variant_setScalarCopy(v: &value->value, p: &wgm->networkMessageContentMask,
56166 type: &UA_TYPES[UA_TYPES_UADPNETWORKMESSAGECONTENTMASK]);
56167 value->hasValue = true;
56168 return UA_STATUSCODE_GOOD;
56169}
56170
56171static UA_StatusCode
56172writeContentMask(UA_Server *server, const UA_NodeId *sessionId,
56173 void *sessionContext, const UA_NodeId *nodeId,
56174 void *nodeContext, const UA_NumericRange *range,
56175 const UA_DataValue *value) {
56176 UA_WriterGroup *writerGroup = (UA_WriterGroup*)nodeContext;
56177 if((writerGroup->config.messageSettings.encoding != UA_EXTENSIONOBJECT_DECODED &&
56178 writerGroup->config.messageSettings.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) ||
56179 writerGroup->config.messageSettings.content.decoded.type !=
56180 &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE])
56181 return UA_STATUSCODE_BADINTERNALERROR;
56182 UA_UadpWriterGroupMessageDataType *wgm = (UA_UadpWriterGroupMessageDataType*)
56183 writerGroup->config.messageSettings.content.decoded.data;
56184
56185 if(!value->value.type)
56186 return UA_STATUSCODE_BADTYPEMISMATCH;
56187 if(value->value.type->typeKind != UA_DATATYPEKIND_ENUM &&
56188 value->value.type->typeKind != UA_DATATYPEKIND_INT32)
56189 return UA_STATUSCODE_BADTYPEMISMATCH;
56190
56191 wgm->networkMessageContentMask = *(UA_UadpNetworkMessageContentMask*)value->value.data;
56192 return UA_STATUSCODE_GOOD;
56193}
56194
56195static UA_StatusCode
56196readGroupVersion(UA_Server *server, const UA_NodeId *sessionId,
56197 void *sessionContext, const UA_NodeId *nodeId,
56198 void *nodeContext, UA_Boolean includeSourceTimeStamp,
56199 const UA_NumericRange *range, UA_DataValue *value) {
56200 UA_WriterGroup *writerGroup = (UA_WriterGroup*)nodeContext;
56201 if((writerGroup->config.messageSettings.encoding != UA_EXTENSIONOBJECT_DECODED &&
56202 writerGroup->config.messageSettings.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) ||
56203 writerGroup->config.messageSettings.content.decoded.type !=
56204 &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE])
56205 return UA_STATUSCODE_BADINTERNALERROR;
56206 UA_UadpWriterGroupMessageDataType *wgm = (UA_UadpWriterGroupMessageDataType*)
56207 writerGroup->config.messageSettings.content.decoded.data;
56208
56209 UA_Variant_setScalarCopy(v: &value->value, p: &wgm->groupVersion,
56210 type: &UA_TYPES[UA_DATATYPEKIND_UINT32]);
56211 value->hasValue = true;
56212 return UA_STATUSCODE_GOOD;
56213}
56214
56215UA_StatusCode
56216addWriterGroupRepresentation(UA_Server *server, UA_WriterGroup *writerGroup) {
56217 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56218
56219 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
56220 if(writerGroup->config.name.length > 512)
56221 return UA_STATUSCODE_BADOUTOFMEMORY;
56222 char wgName[513];
56223 memcpy(dest: wgName, src: writerGroup->config.name.data, n: writerGroup->config.name.length);
56224 wgName[writerGroup->config.name.length] = '\0';
56225
56226 UA_ObjectAttributes object_attr = UA_ObjectAttributes_default;
56227 object_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: wgName);
56228 retVal = addNode(server, nodeClass: UA_NODECLASS_OBJECT,
56229 requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 1, identifier: 0), /* create a new id */
56230 parentNodeId: writerGroup->linkedConnection->identifier,
56231 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
56232 browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: wgName),
56233 typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_WRITERGROUPTYPE),
56234 attr: &object_attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
56235 NULL, outNewNodeId: &writerGroup->identifier);
56236
56237 UA_NodeId keepAliveNode =
56238 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "KeepAliveTime"),
56239 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
56240 startingNode: writerGroup->identifier);
56241 UA_NodeId publishingIntervalNode =
56242 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "PublishingInterval"),
56243 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
56244 startingNode: writerGroup->identifier);
56245 if(UA_NodeId_isNull(p: &keepAliveNode) ||
56246 UA_NodeId_isNull(p: &publishingIntervalNode))
56247 return UA_STATUSCODE_BADNOTFOUND;
56248
56249 UA_NodePropertyContext * publishingIntervalContext = (UA_NodePropertyContext *)
56250 UA_malloc(size: sizeof(UA_NodePropertyContext));
56251 publishingIntervalContext->parentNodeId = writerGroup->identifier;
56252 publishingIntervalContext->parentClassifier = UA_NS0ID_WRITERGROUPTYPE;
56253 publishingIntervalContext->elementClassiefier = UA_NS0ID_WRITERGROUPTYPE_PUBLISHINGINTERVAL;
56254 UA_ValueCallback valueCallback;
56255 valueCallback.onRead = onRead;
56256 valueCallback.onWrite = onWrite;
56257 retVal |= addVariableValueSource(server, valueCallback,
56258 node: publishingIntervalNode, context: publishingIntervalContext);
56259 writeAccessLevelAttribute(server, nodeId: publishingIntervalNode,
56260 UA_ACCESSLEVELMASK_READ ^ UA_ACCESSLEVELMASK_WRITE);
56261
56262 UA_NodeId priorityNode =
56263 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "Priority"),
56264 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
56265 startingNode: writerGroup->identifier);
56266 UA_NodeId writerGroupIdNode =
56267 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "WriterGroupId"),
56268 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
56269 startingNode: writerGroup->identifier);
56270
56271 UA_Variant value;
56272 UA_Variant_init(p: &value);
56273 UA_Variant_setScalar(v: &value, p: &writerGroup->config.publishingInterval, type: &UA_TYPES[UA_TYPES_DURATION]);
56274 writeValueAttribute(server, nodeId: publishingIntervalNode, value: &value);
56275 UA_Variant_setScalar(v: &value, p: &writerGroup->config.keepAliveTime, type: &UA_TYPES[UA_TYPES_DURATION]);
56276 writeValueAttribute(server, nodeId: keepAliveNode, value: &value);
56277 UA_Variant_setScalar(v: &value, p: &writerGroup->config.priority, type: &UA_TYPES[UA_TYPES_BYTE]);
56278 writeValueAttribute(server, nodeId: priorityNode, value: &value);
56279 UA_Variant_setScalar(v: &value, p: &writerGroup->config.writerGroupId, type: &UA_TYPES[UA_TYPES_UINT16]);
56280 writeValueAttribute(server, nodeId: writerGroupIdNode, value: &value);
56281
56282 object_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MessageSettings");
56283 retVal |= addNode(server, nodeClass: UA_NODECLASS_OBJECT,
56284 requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 1, identifier: 0),
56285 parentNodeId: writerGroup->identifier,
56286 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
56287 browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "MessageSettings"),
56288 typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_UADPWRITERGROUPMESSAGETYPE),
56289 attr: &object_attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
56290 NULL, NULL);
56291
56292 /* Find the variable with the content mask */
56293
56294 UA_NodeId messageSettingsId =
56295 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "MessageSettings"),
56296 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
56297 startingNode: writerGroup->identifier);
56298 UA_NodeId contentMaskId =
56299 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "NetworkMessageContentMask"),
56300 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY), startingNode: messageSettingsId);
56301 if(!UA_NodeId_isNull(p: &contentMaskId)) {
56302 /* Set the callback */
56303 UA_DataSource ds;
56304 ds.read = readContentMask;
56305 ds.write = writeContentMask;
56306 setVariableNode_dataSource(server, nodeId: contentMaskId, dataSource: ds);
56307 setNodeContext(server, nodeId: contentMaskId, nodeContext: writerGroup);
56308
56309 /* Make writable */
56310 writeAccessLevelAttribute(server, nodeId: contentMaskId,
56311 UA_ACCESSLEVELMASK_WRITE | UA_ACCESSLEVELMASK_READ);
56312
56313 }
56314 UA_NodeId groupVersionId =
56315 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "GroupVersion"),
56316 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY), startingNode: messageSettingsId);
56317 if(!UA_NodeId_isNull(p: &groupVersionId)) {
56318 /* Set the callback */
56319 UA_DataSource ds;
56320 ds.read = readGroupVersion;
56321 ds.write = NULL;
56322 setVariableNode_dataSource(server, nodeId: groupVersionId, dataSource: ds);
56323 setNodeContext(server, nodeId: groupVersionId, nodeContext: writerGroup);
56324
56325 /* Read only */
56326 writeAccessLevelAttribute(server, nodeId: groupVersionId,
56327 UA_ACCESSLEVELMASK_READ);
56328
56329 }
56330
56331 /* Add reference to methods */
56332 if(server->config.pubSubConfig.enableInformationModelMethods) {
56333 retVal |= addRef(server, sourceId: writerGroup->identifier,
56334 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
56335 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_WRITERGROUPTYPE_ADDDATASETWRITER), true);
56336 retVal |= addRef(server, sourceId: writerGroup->identifier,
56337 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
56338 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_WRITERGROUPTYPE_REMOVEDATASETWRITER), true);
56339 }
56340 return retVal;
56341}
56342
56343static UA_StatusCode
56344addWriterGroupAction(UA_Server *server,
56345 const UA_NodeId *sessionId, void *sessionHandle,
56346 const UA_NodeId *methodId, void *methodContext,
56347 const UA_NodeId *objectId, void *objectContext,
56348 size_t inputSize, const UA_Variant *input,
56349 size_t outputSize, UA_Variant *output){
56350 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56351
56352 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
56353 UA_WriterGroupDataType *writerGroup = ((UA_WriterGroupDataType *) input[0].data);
56354 UA_NodeId writerGroupId;
56355 retVal |= addWriterGroupConfig(server, connectionId: *objectId, writerGroup, writerGroupId: &writerGroupId);
56356 if(retVal != UA_STATUSCODE_GOOD) {
56357 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER, msg: "addWriterGroup failed");
56358 return retVal;
56359 }
56360 // TODO: Need to handle the UA_Server_setWriterGroupOperational based on the
56361 // status variable in information model
56362
56363 UA_Variant_setScalarCopy(v: output, p: &writerGroupId, type: &UA_TYPES[UA_TYPES_NODEID]);
56364 return retVal;
56365}
56366
56367static UA_StatusCode
56368removeGroupAction(UA_Server *server,
56369 const UA_NodeId *sessionId, void *sessionHandle,
56370 const UA_NodeId *methodId, void *methodContext,
56371 const UA_NodeId *objectId, void *objectContext,
56372 size_t inputSize, const UA_Variant *input,
56373 size_t outputSize, UA_Variant *output){
56374 UA_NodeId nodeToRemove = *((UA_NodeId *)input->data);
56375 if(UA_WriterGroup_findWGbyId(server, identifier: nodeToRemove)) {
56376 UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, identifier: nodeToRemove);
56377 if(wg->configurationFrozen)
56378 UA_Server_unfreezeWriterGroupConfiguration(server, writerGroup: nodeToRemove);
56379 return UA_Server_removeWriterGroup(server, writerGroup: nodeToRemove);
56380 } else {
56381 UA_ReaderGroup *rg = UA_ReaderGroup_findRGbyId(server, identifier: nodeToRemove);
56382 if(rg->configurationFrozen)
56383 UA_Server_unfreezeReaderGroupConfiguration(server, readerGroupId: nodeToRemove);
56384 return UA_Server_removeReaderGroup(server, groupIdentifier: nodeToRemove);
56385 }
56386}
56387
56388/**********************************************/
56389/* ReserveIds */
56390/**********************************************/
56391
56392static UA_StatusCode
56393addReserveIdsLocked(UA_Server *server,
56394 const UA_NodeId *sessionId, void *sessionHandle,
56395 const UA_NodeId *methodId, void *methodContext,
56396 const UA_NodeId *objectId, void *objectContext,
56397 size_t inputSize, const UA_Variant *input,
56398 size_t outputSize, UA_Variant *output){
56399 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56400 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
56401 UA_String transportProfileUri = *((UA_String *)input[0].data);
56402 UA_UInt16 numRegWriterGroupIds = *((UA_UInt16 *)input[1].data);
56403 UA_UInt16 numRegDataSetWriterIds = *((UA_UInt16 *)input[2].data);
56404
56405 UA_UInt16 *writerGroupIds;
56406 UA_UInt16 *dataSetWriterIds;
56407
56408 retVal |= UA_PubSubManager_reserveIds(server, sessionId: *sessionId, numRegWriterGroupIds,
56409 numRegDataSetWriterIds, transportProfileUri,
56410 writerGroupIds: &writerGroupIds, dataSetWriterIds: &dataSetWriterIds);
56411 if(retVal != UA_STATUSCODE_GOOD) {
56412 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER, msg: "addReserveIds failed");
56413 return retVal;
56414 }
56415
56416 /* Check the transportProfileUri */
56417 UA_String profile_1 = UA_STRING(chars: "http://opcfoundation.org/UA-Profile/Transport/pubsub-mqtt-uadp");
56418 UA_String profile_2 = UA_STRING(chars: "http://opcfoundation.org/UA-Profile/Transport/pubsub-mqtt-json");
56419
56420 if(UA_String_equal(p1: &transportProfileUri, p2: &profile_1) ||
56421 UA_String_equal(p1: &transportProfileUri, p2: &profile_2)) {
56422 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER, msg: "ApplicationUri: %.*s",
56423 (int)server->config.applicationDescription.applicationUri.length,
56424 server->config.applicationDescription.applicationUri.data);
56425 retVal |= UA_Variant_setScalarCopy(v: &output[0],
56426 p: &server->config.applicationDescription.applicationUri,
56427 type: &UA_TYPES[UA_TYPES_STRING]);
56428 } else {
56429 retVal |= UA_Variant_setScalarCopy(v: &output[0],
56430 p: &server->pubSubManager.defaultPublisherId,
56431 type: &UA_TYPES[UA_TYPES_UINT64]);
56432 }
56433
56434 UA_Variant_setArray(v: &output[1], array: writerGroupIds,
56435 arraySize: numRegWriterGroupIds, type: &UA_TYPES[UA_TYPES_UINT16]);
56436 UA_Variant_setArray(v: &output[2], array: dataSetWriterIds,
56437 arraySize: numRegDataSetWriterIds, type: &UA_TYPES[UA_TYPES_UINT16]);
56438
56439 return retVal;
56440}
56441
56442static UA_StatusCode
56443addReserveIdsAction(UA_Server *server,
56444 const UA_NodeId *sessionId, void *sessionHandle,
56445 const UA_NodeId *methodId, void *methodContext,
56446 const UA_NodeId *objectId, void *objectContext,
56447 size_t inputSize, const UA_Variant *input,
56448 size_t outputSize, UA_Variant *output) {
56449 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56450 return addReserveIdsLocked(server, sessionId, sessionHandle,
56451 methodId, methodContext, objectId, objectContext,
56452 inputSize, input, outputSize, output);
56453}
56454
56455/**********************************************/
56456/* ReaderGroup */
56457/**********************************************/
56458
56459UA_StatusCode
56460addReaderGroupRepresentation(UA_Server *server, UA_ReaderGroup *readerGroup) {
56461 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56462 if(readerGroup->config.name.length > 512)
56463 return UA_STATUSCODE_BADCONFIGURATIONERROR;
56464 char rgName[513];
56465 memcpy(dest: rgName, src: readerGroup->config.name.data, n: readerGroup->config.name.length);
56466 rgName[readerGroup->config.name.length] = '\0';
56467
56468 UA_ObjectAttributes object_attr = UA_ObjectAttributes_default;
56469 object_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: rgName);
56470 UA_StatusCode retVal =
56471 addNode(server, nodeClass: UA_NODECLASS_OBJECT, requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 1, identifier: 0), /* create an id */
56472 parentNodeId: readerGroup->linkedConnection->identifier,
56473 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
56474 browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: rgName), typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_READERGROUPTYPE),
56475 attr: &object_attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
56476 NULL, outNewNodeId: &readerGroup->identifier);
56477 if(server->config.pubSubConfig.enableInformationModelMethods) {
56478 retVal |= addRef(server, sourceId: readerGroup->identifier,
56479 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
56480 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_READERGROUPTYPE_ADDDATASETREADER), true);
56481 retVal |= addRef(server, sourceId: readerGroup->identifier,
56482 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
56483 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_READERGROUPTYPE_REMOVEDATASETREADER), true);
56484 }
56485 return retVal;
56486}
56487
56488static UA_StatusCode
56489addReaderGroupAction(UA_Server *server,
56490 const UA_NodeId *sessionId, void *sessionHandle,
56491 const UA_NodeId *methodId, void *methodContext,
56492 const UA_NodeId *objectId, void *objectContext,
56493 size_t inputSize, const UA_Variant *input,
56494 size_t outputSize, UA_Variant *output) {
56495 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56496
56497 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
56498 UA_ReaderGroupDataType *readerGroup = ((UA_ReaderGroupDataType *) input->data);
56499 UA_NodeId readerGroupId;
56500 retVal |= addReaderGroupConfig(server, connectionId: *objectId, readerGroup, readerGroupId: &readerGroupId);
56501 if(retVal != UA_STATUSCODE_GOOD) {
56502 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER, msg: "addReaderGroup failed");
56503 return retVal;
56504 }
56505 // TODO: Need to handle the UA_Server_setReaderGroupOperational based on the
56506 // status variable in information model
56507
56508 UA_Variant_setScalarCopy(v: output, p: &readerGroupId, type: &UA_TYPES[UA_TYPES_NODEID]);
56509 return retVal;
56510}
56511
56512#ifdef UA_ENABLE_PUBSUB_SKS
56513#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
56514static UA_Boolean
56515isValidParentNode(UA_Server *server, UA_NodeId parentId) {
56516 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56517 UA_Boolean retval = true;
56518 const UA_Node *parentNodeType;
56519 const UA_NodeId parentNodeTypeId =
56520 UA_NODEID_NUMERIC(0, UA_NS0ID_SECURITYGROUPFOLDERTYPE);
56521 const UA_Node *parentNode = UA_NODESTORE_GET(server, &parentId);
56522
56523 if(parentNode) {
56524 parentNodeType = getNodeType(server, &parentNode->head);
56525 if(parentNodeType) {
56526 retval = UA_NodeId_equal(&parentNodeType->head.nodeId, &parentNodeTypeId);
56527 UA_NODESTORE_RELEASE(server, parentNodeType);
56528 }
56529 UA_NODESTORE_RELEASE(server, parentNode);
56530 }
56531 return retval;
56532}
56533
56534static UA_StatusCode
56535updateSecurityGroupProperties(UA_Server *server, UA_NodeId *securityGroupNodeId,
56536 UA_SecurityGroupConfig *config) {
56537 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56538
56539 UA_StatusCode retval = UA_STATUSCODE_BAD;
56540 UA_Variant value;
56541 UA_Variant_init(&value);
56542 UA_Variant_setScalar(&value, &config->securityGroupName, &UA_TYPES[UA_TYPES_STRING]);
56543 retval = writeObjectProperty(server, *securityGroupNodeId,
56544 UA_QUALIFIEDNAME(0, "SecurityGroupId"), value);
56545 if(retval != UA_STATUSCODE_GOOD)
56546 return retval;
56547
56548 /*AddValueCallback*/
56549 UA_Variant_setScalar(&value, &config->securityPolicyUri, &UA_TYPES[UA_TYPES_STRING]);
56550 retval = writeObjectProperty(server, *securityGroupNodeId,
56551 UA_QUALIFIEDNAME(0, "SecurityPolicyUri"), value);
56552 if(retval != UA_STATUSCODE_GOOD)
56553 return retval;
56554
56555 UA_Variant_setScalar(&value, &config->keyLifeTime, &UA_TYPES[UA_TYPES_DURATION]);
56556 retval = writeObjectProperty(server, *securityGroupNodeId,
56557 UA_QUALIFIEDNAME(0, "KeyLifetime"), value);
56558 if(retval != UA_STATUSCODE_GOOD)
56559 return retval;
56560
56561 UA_Variant_setScalar(&value, &config->maxFutureKeyCount, &UA_TYPES[UA_TYPES_UINT32]);
56562 retval = writeObjectProperty(server, *securityGroupNodeId,
56563 UA_QUALIFIEDNAME(0, "MaxFutureKeyCount"), value);
56564 if(retval != UA_STATUSCODE_GOOD)
56565 return retval;
56566
56567 UA_Variant_setScalar(&value, &config->maxPastKeyCount, &UA_TYPES[UA_TYPES_UINT32]);
56568 retval = writeObjectProperty(server, *securityGroupNodeId,
56569 UA_QUALIFIEDNAME(0, "MaxPastKeyCount"), value);
56570 if(retval != UA_STATUSCODE_GOOD)
56571 return retval;
56572
56573 return retval;
56574}
56575
56576UA_StatusCode
56577addSecurityGroupRepresentation(UA_Server *server, UA_SecurityGroup *securityGroup) {
56578 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56579 UA_StatusCode retval = UA_STATUSCODE_BAD;
56580
56581 UA_SecurityGroupConfig *securityGroupConfig = &securityGroup->config;
56582 if(!isValidParentNode(server, securityGroup->securityGroupFolderId))
56583 return UA_STATUSCODE_BADPARENTNODEIDINVALID;
56584
56585 if(securityGroupConfig->securityGroupName.length <= 0)
56586 return UA_STATUSCODE_BADINVALIDARGUMENT;
56587
56588 UA_QualifiedName browseName;
56589 UA_QualifiedName_init(&browseName);
56590 browseName.name = securityGroupConfig->securityGroupName;
56591
56592 UA_ObjectAttributes object_attr = UA_ObjectAttributes_default;
56593 object_attr.displayName.text = securityGroupConfig->securityGroupName;
56594 UA_NodeId refType = UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT);
56595 UA_NodeId nodeType = UA_NODEID_NUMERIC(0, UA_NS0ID_SECURITYGROUPTYPE);
56596 retval = addNode(server, UA_NODECLASS_OBJECT, UA_NODEID_NULL,
56597 securityGroup->securityGroupFolderId, refType,
56598 browseName, nodeType, &object_attr,
56599 &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], NULL,
56600 &securityGroup->securityGroupNodeId);
56601 if(retval != UA_STATUSCODE_GOOD) {
56602 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
56603 "Add SecurityGroup failed with error: %s.",
56604 UA_StatusCode_name(retval));
56605 return retval;
56606 }
56607
56608 retval = updateSecurityGroupProperties(server,
56609 &securityGroup->securityGroupNodeId,
56610 securityGroupConfig);
56611 if(retval != UA_STATUSCODE_GOOD) {
56612 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
56613 "Add SecurityGroup failed with error: %s.",
56614 UA_StatusCode_name(retval));
56615 deleteNode(server, securityGroup->securityGroupNodeId, true);
56616 }
56617 return retval;
56618}
56619
56620#endif /* UA_ENABLE_PUBSUB_INFORMATIONMODEL*/
56621#endif /* UA_ENABLE_PUBSUB_SKS */
56622
56623/**********************************************/
56624/* DataSetWriter */
56625/**********************************************/
56626
56627UA_StatusCode
56628addDataSetWriterRepresentation(UA_Server *server, UA_DataSetWriter *dataSetWriter) {
56629 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56630
56631 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
56632 if(dataSetWriter->config.name.length > 512)
56633 return UA_STATUSCODE_BADOUTOFMEMORY;
56634
56635 char dswName[513];
56636 memcpy(dest: dswName, src: dataSetWriter->config.name.data, n: dataSetWriter->config.name.length);
56637 dswName[dataSetWriter->config.name.length] = '\0';
56638
56639 UA_ObjectAttributes object_attr = UA_ObjectAttributes_default;
56640 object_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: dswName);
56641 retVal = addNode(server, nodeClass: UA_NODECLASS_OBJECT, requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 1, identifier: 0), /* create an id */
56642 parentNodeId: dataSetWriter->linkedWriterGroup,
56643 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASDATASETWRITER),
56644 browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: dswName),
56645 typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETWRITERTYPE),
56646 attr: &object_attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
56647 NULL, outNewNodeId: &dataSetWriter->identifier);
56648 //if connected dataset is null this means it's configured for heartbeats
56649 if(!UA_NodeId_isNull(p: &dataSetWriter->connectedDataSet)) {
56650 retVal |= addRef(server, sourceId: dataSetWriter->connectedDataSet,
56651 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETTOWRITER),
56652 targetId: dataSetWriter->identifier, true);
56653 }
56654
56655 UA_NodeId dataSetWriterIdNode =
56656 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "DataSetWriterId"),
56657 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
56658 startingNode: dataSetWriter->identifier);
56659 UA_NodeId keyFrameNode =
56660 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "KeyFrameCount"),
56661 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
56662 startingNode: dataSetWriter->identifier);
56663 UA_NodeId dataSetFieldContentMaskNode =
56664 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "DataSetFieldContentMask"),
56665 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
56666 startingNode: dataSetWriter->identifier);
56667
56668 UA_NodePropertyContext *dataSetWriterIdContext = (UA_NodePropertyContext *)
56669 UA_malloc(size: sizeof(UA_NodePropertyContext));
56670 dataSetWriterIdContext->parentNodeId = dataSetWriter->identifier;
56671 dataSetWriterIdContext->parentClassifier = UA_NS0ID_DATASETWRITERTYPE;
56672 dataSetWriterIdContext->elementClassiefier = UA_NS0ID_DATASETWRITERTYPE_DATASETWRITERID;
56673 UA_ValueCallback valueCallback;
56674 valueCallback.onRead = onRead;
56675 valueCallback.onWrite = NULL;
56676 retVal |= addVariableValueSource(server, valueCallback,
56677 node: dataSetWriterIdNode, context: dataSetWriterIdContext);
56678
56679 UA_Variant value;
56680 UA_Variant_init(p: &value);
56681 UA_Variant_setScalar(v: &value, p: &dataSetWriter->config.dataSetWriterId,
56682 type: &UA_TYPES[UA_TYPES_UINT16]);
56683 writeValueAttribute(server, nodeId: dataSetWriterIdNode, value: &value);
56684
56685 UA_Variant_setScalar(v: &value, p: &dataSetWriter->config.keyFrameCount,
56686 type: &UA_TYPES[UA_TYPES_UINT32]);
56687 writeValueAttribute(server, nodeId: keyFrameNode, value: &value);
56688
56689 UA_Variant_setScalar(v: &value, p: &dataSetWriter->config.dataSetFieldContentMask,
56690 type: &UA_TYPES[UA_TYPES_DATASETFIELDCONTENTMASK]);
56691 writeValueAttribute(server, nodeId: dataSetFieldContentMaskNode, value: &value);
56692
56693 object_attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MessageSettings");
56694 retVal |= addNode(server, nodeClass: UA_NODECLASS_OBJECT, requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: 1, identifier: 0),
56695 parentNodeId: dataSetWriter->identifier,
56696 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
56697 browseName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "MessageSettings"),
56698 typeDefinition: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_UADPDATASETWRITERMESSAGETYPE),
56699 attr: &object_attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
56700 NULL, NULL);
56701
56702 return retVal;
56703}
56704
56705static UA_StatusCode
56706addDataSetWriterLocked(UA_Server *server,
56707 const UA_NodeId *sessionId, void *sessionHandle,
56708 const UA_NodeId *methodId, void *methodContext,
56709 const UA_NodeId *objectId, void *objectContext,
56710 size_t inputSize, const UA_Variant *input,
56711 size_t outputSize, UA_Variant *output) {
56712 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56713
56714 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
56715 UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, identifier: *objectId);
56716 if(!wg) {
56717 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
56718 msg: "Not a WriterGroup");
56719 return UA_STATUSCODE_BAD;
56720 }
56721 if(wg->configurationFrozen) {
56722 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
56723 msg: "addDataSetWriter cannot be done because writergroup config frozen");
56724 return UA_STATUSCODE_BAD;
56725 }
56726
56727 UA_NodeId dataSetWriterId;
56728 UA_DataSetWriterDataType *dataSetWriterData = (UA_DataSetWriterDataType *)input->data;
56729 retVal |= addDataSetWriterConfig(server, writerGroupId: objectId, dataSetWriter: dataSetWriterData, dataSetWriterId: &dataSetWriterId);
56730 if(retVal != UA_STATUSCODE_GOOD) {
56731 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
56732 msg: "addDataSetWriter failed");
56733 return retVal;
56734 }
56735
56736 UA_Variant_setScalarCopy(v: output, p: &dataSetWriterId, type: &UA_TYPES[UA_TYPES_NODEID]);
56737 return UA_STATUSCODE_GOOD;
56738}
56739
56740static UA_StatusCode
56741addDataSetWriterAction(UA_Server *server,
56742 const UA_NodeId *sessionId, void *sessionHandle,
56743 const UA_NodeId *methodId, void *methodContext,
56744 const UA_NodeId *objectId, void *objectContext,
56745 size_t inputSize, const UA_Variant *input,
56746 size_t outputSize, UA_Variant *output) {
56747 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56748 return addDataSetWriterLocked(server, sessionId, sessionHandle,
56749 methodId, methodContext, objectId, objectContext,
56750 inputSize, input, outputSize, output);
56751}
56752
56753static UA_StatusCode
56754removeDataSetWriterAction(UA_Server *server,
56755 const UA_NodeId *sessionId, void *sessionHandle,
56756 const UA_NodeId *methodId, void *methodContext,
56757 const UA_NodeId *objectId, void *objectContext,
56758 size_t inputSize, const UA_Variant *input,
56759 size_t outputSize, UA_Variant *output){
56760 UA_NodeId nodeToRemove = *((UA_NodeId *) input[0].data);
56761 return UA_Server_removeDataSetWriter(server, dsw: nodeToRemove);
56762}
56763
56764#ifdef UA_ENABLE_PUBSUB_SKS
56765/**
56766 * @note The user credentials and permissions are checked in the AccessControl plugin
56767 * before this callback is executed.
56768 */
56769static UA_StatusCode
56770setSecurityKeysLocked(UA_Server *server, const UA_NodeId *sessionId, void *sessionHandle,
56771 const UA_NodeId *methodId, void *methodContext,
56772 const UA_NodeId *objectId, void *objectContext, size_t inputSize,
56773 const UA_Variant *input, size_t outputSize, UA_Variant *output) {
56774 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56775
56776 /*Check whether the channel is encrypted according to specification*/
56777 session_list_entry *session_entry;
56778 LIST_FOREACH(session_entry, &server->sessions, pointers) {
56779 if(UA_NodeId_equal(&session_entry->session.sessionId, sessionId)) {
56780 if(session_entry->session.header.channel->securityMode !=
56781 UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
56782 return UA_STATUSCODE_BADSECURITYMODEINSUFFICIENT;
56783 }
56784 }
56785
56786 if(!server || !input)
56787 return UA_STATUSCODE_BADINVALIDARGUMENT;
56788
56789 if(inputSize < 7)
56790 return UA_STATUSCODE_BADARGUMENTSMISSING;
56791 if(inputSize > 7 || outputSize > 0)
56792 return UA_STATUSCODE_BADTOOMANYARGUMENTS;
56793
56794 /*check for types*/
56795 if(!UA_Variant_hasScalarType(&input[0], &UA_TYPES[UA_TYPES_STRING]) || /*SecurityGroupId*/
56796 !UA_Variant_hasScalarType(&input[1], &UA_TYPES[UA_TYPES_STRING]) || /*SecurityPolicyUri*/
56797 !UA_Variant_hasScalarType(&input[2], &UA_TYPES[UA_TYPES_INTEGERID]) || /*CurrentTokenId*/
56798 !UA_Variant_hasScalarType(&input[3], &UA_TYPES[UA_TYPES_BYTESTRING]) || /*CurrentKey*/
56799 !UA_Variant_hasArrayType(&input[4], &UA_TYPES[UA_TYPES_BYTESTRING]) || /*FutureKeys*/
56800 (!UA_Variant_hasScalarType(&input[5], &UA_TYPES[UA_TYPES_DURATION]) &&
56801 !UA_Variant_hasScalarType(&input[5], &UA_TYPES[UA_TYPES_DOUBLE])) || /*TimeToNextKey*/
56802 (!UA_Variant_hasScalarType(&input[6], &UA_TYPES[UA_TYPES_DURATION]) &&
56803 !UA_Variant_hasScalarType(&input[6], &UA_TYPES[UA_TYPES_DOUBLE]))) /*TimeToNextKey*/
56804 return UA_STATUSCODE_BADTYPEMISMATCH;
56805
56806 UA_StatusCode retval = UA_STATUSCODE_BAD;
56807 UA_Duration callbackTime;
56808 UA_String *securityGroupId = (UA_String *)input[0].data;
56809 UA_String *securityPolicyUri = (UA_String *)input[1].data;
56810 UA_UInt32 currentKeyId = *(UA_UInt32 *)input[2].data;
56811 UA_ByteString *currentKey = (UA_ByteString *)input[3].data;
56812 UA_ByteString *futureKeys = (UA_ByteString *)input[4].data;
56813 size_t futureKeySize = input[4].arrayLength;
56814 UA_Duration msTimeToNextKey = *(UA_Duration *)input[5].data;
56815 UA_Duration msKeyLifeTime = *(UA_Duration *)input[6].data;
56816
56817 UA_PubSubKeyStorage *ks =
56818 UA_PubSubKeyStorage_findKeyStorage(server, *securityGroupId);
56819 if(!ks)
56820 return UA_STATUSCODE_BADNOTFOUND;
56821
56822 if(!UA_String_equal(securityPolicyUri, &ks->policy->policyUri))
56823 return UA_STATUSCODE_BADSECURITYPOLICYREJECTED;
56824
56825 if(ks->keyListSize == 0) {
56826 retval = UA_PubSubKeyStorage_storeSecurityKeys(server, ks, currentKeyId,
56827 currentKey, futureKeys, futureKeySize,
56828 msKeyLifeTime);
56829 if(retval != UA_STATUSCODE_GOOD)
56830 return retval;
56831 } else {
56832 retval = UA_PubSubKeyStorage_update(server, ks, currentKey, currentKeyId,
56833 futureKeySize, futureKeys, msKeyLifeTime);
56834 if(retval != UA_STATUSCODE_GOOD)
56835 return retval;
56836 }
56837
56838 retval = UA_PubSubKeyStorage_activateKeyToChannelContext(server, UA_NODEID_NULL,
56839 ks->securityGroupID);
56840 if(retval != UA_STATUSCODE_GOOD) {
56841 UA_LOG_INFO(
56842 server->config.logging, UA_LOGCATEGORY_SERVER,
56843 "Failed to import Symmetric Keys into PubSub Channel Context with %s \n",
56844 UA_StatusCode_name(retval));
56845 return retval;
56846 }
56847
56848 callbackTime = msKeyLifeTime;
56849 if(msTimeToNextKey > 0)
56850 callbackTime = msTimeToNextKey;
56851
56852 /*move to setSecurityKeysAction*/
56853 retval = UA_PubSubKeyStorage_addKeyRolloverCallback(
56854 server, ks, (UA_ServerCallback)UA_PubSubKeyStorage_keyRolloverCallback, callbackTime,
56855 &ks->callBackId);
56856 return retval;
56857}
56858
56859static UA_StatusCode
56860setSecurityKeysAction(UA_Server *server, const UA_NodeId *sessionId, void *sessionHandle,
56861 const UA_NodeId *methodId, void *methodContext,
56862 const UA_NodeId *objectId, void *objectContext, size_t inputSize,
56863 const UA_Variant *input, size_t outputSize, UA_Variant *output) {
56864 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56865 return setSecurityKeysLocked(server, sessionId, sessionHandle,
56866 methodId, methodContext,
56867 objectId, objectContext, inputSize,
56868 input, outputSize, output);
56869}
56870
56871static UA_StatusCode
56872getSecurityKeysLocked(UA_Server *server, const UA_NodeId *sessionId, void *sessionHandle,
56873 const UA_NodeId *methodId, void *methodContext,
56874 const UA_NodeId *objectId, void *objectContext, size_t inputSize,
56875 const UA_Variant *input, size_t outputSize, UA_Variant *output) {
56876 UA_LOCK_ASSERT(&server->serviceMutex, 1);
56877
56878 /*Check whether the channel is encrypted according to specification*/
56879 session_list_entry *session_entry;
56880 LIST_FOREACH(session_entry, &server->sessions, pointers) {
56881 if(UA_NodeId_equal(&session_entry->session.sessionId, sessionId)) {
56882 if(session_entry->session.header.channel->securityMode !=
56883 UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
56884 return UA_STATUSCODE_BADSECURITYMODEINSUFFICIENT;
56885 }
56886 }
56887
56888 if(!server || !input)
56889 return UA_STATUSCODE_BADINVALIDARGUMENT;
56890
56891 if(inputSize < 3 || outputSize < 5)
56892 return UA_STATUSCODE_BADARGUMENTSMISSING;
56893 if(inputSize > 3 || outputSize > 5)
56894 return UA_STATUSCODE_BADTOOMANYARGUMENTS;
56895
56896 /*check for types*/
56897 if(!UA_Variant_hasScalarType(&input[0],
56898 &UA_TYPES[UA_TYPES_STRING]) || /*SecurityGroupId*/
56899 !UA_Variant_hasScalarType(&input[1],
56900 &UA_TYPES[UA_TYPES_INTEGERID]) || /*StartingTokenId*/
56901 !UA_Variant_hasScalarType(&input[2],
56902 &UA_TYPES[UA_TYPES_UINT32])) /*RequestedKeyCount*/
56903 return UA_STATUSCODE_BADTYPEMISMATCH;
56904
56905 UA_StatusCode retval = UA_STATUSCODE_BAD;
56906 UA_UInt32 currentKeyCount = 1;
56907 /* input */
56908 UA_String *securityGroupId = (UA_String *)input[0].data;
56909 UA_UInt32 startingTokenId = *(UA_UInt32 *)input[1].data;
56910 UA_UInt32 requestedKeyCount = *(UA_UInt32 *)input[2].data;
56911
56912 UA_PubSubKeyStorage *ks =
56913 UA_PubSubKeyStorage_findKeyStorage(server, *securityGroupId);
56914 if(!ks)
56915 return UA_STATUSCODE_BADNOTFOUND;
56916
56917 UA_Boolean executable = false;
56918 UA_SecurityGroup *sg = UA_SecurityGroup_findSGbyName(server, *securityGroupId);
56919 void *sgNodeCtx;
56920 getNodeContext(server, sg->securityGroupNodeId, (void **)&sgNodeCtx);
56921 executable = server->config.accessControl.getUserExecutableOnObject(
56922 server, &server->config.accessControl, sessionId, sessionHandle, methodId,
56923 methodContext, &sg->securityGroupNodeId, sgNodeCtx);
56924
56925 if(!executable)
56926 return UA_STATUSCODE_BADUSERACCESSDENIED;
56927
56928 /* If the caller requests a number larger than the Security Key Service permits, then
56929 * the SKS shall return the maximum it allows.*/
56930 if(requestedKeyCount > sg->config.maxFutureKeyCount)
56931 requestedKeyCount =(UA_UInt32) sg->keyStorage->keyListSize;
56932 else
56933 requestedKeyCount = requestedKeyCount + currentKeyCount; /* Add Current keyCount */
56934
56935 /*The current token is requested by passing 0.*/
56936 UA_PubSubKeyListItem *startingItem = NULL;
56937 if(startingTokenId == 0) {
56938 /* currentItem is always set by the server when a security group is added */
56939 UA_assert(sg->keyStorage->currentItem != NULL);
56940 startingItem = sg->keyStorage->currentItem;
56941 } else {
56942 retval = UA_PubSubKeyStorage_getKeyByKeyID(
56943 startingTokenId, sg->keyStorage, &startingItem);
56944 /*If the StartingTokenId is unknown, the oldest (firstItem) available tokens are
56945 * returned. */
56946 if(retval == UA_STATUSCODE_BADNOTFOUND)
56947 startingItem = TAILQ_FIRST(&sg->keyStorage->keyList);
56948 }
56949
56950 /*SecurityPolicyUri*/
56951 retval = UA_Variant_setScalarCopy(&output[0], &(sg->keyStorage->policy->policyUri),
56952 &UA_TYPES[UA_TYPES_STRING]);
56953 if(retval != UA_STATUSCODE_GOOD)
56954 return retval;
56955
56956 /*FirstTokenId*/
56957 retval = UA_Variant_setScalarCopy(&output[1], &startingItem->keyID,
56958 &UA_TYPES[UA_TYPES_INTEGERID]);
56959 if(retval != UA_STATUSCODE_GOOD)
56960 return retval;
56961
56962 /*TimeToNextKey*/
56963 UA_DateTime baseTime = sg->baseTime;
56964 UA_DateTime currentTime = UA_DateTime_nowMonotonic();
56965 UA_Duration interval = sg->config.keyLifeTime;
56966 UA_Duration timeToNextKey =
56967 (UA_Duration)((currentTime - baseTime) / UA_DATETIME_MSEC);
56968 timeToNextKey = interval - timeToNextKey;
56969 retval = UA_Variant_setScalarCopy(&output[3], &timeToNextKey,
56970 &UA_TYPES[UA_TYPES_DURATION]);
56971 if(retval != UA_STATUSCODE_GOOD)
56972 return retval;
56973
56974 /*KeyLifeTime*/
56975 retval = UA_Variant_setScalarCopy(&output[4], &sg->config.keyLifeTime,
56976 &UA_TYPES[UA_TYPES_DURATION]);
56977 if(retval != UA_STATUSCODE_GOOD)
56978 return retval;
56979
56980 /*Keys*/
56981 UA_PubSubKeyListItem *iterator = startingItem;
56982 output[2].data = (UA_ByteString *)UA_calloc(requestedKeyCount, startingItem->key.length);
56983 if(!output[2].data)
56984 return UA_STATUSCODE_BADOUTOFMEMORY;
56985
56986 UA_ByteString *requestedKeys = (UA_ByteString *)output[2].data;
56987 UA_UInt32 retkeyCount = 0;
56988 for(size_t i = 0; i < requestedKeyCount; i++) {
56989 UA_ByteString_copy(&iterator->key, &requestedKeys[i]);
56990 ++retkeyCount;
56991 iterator = TAILQ_NEXT(iterator, keyListEntry);
56992 if(!iterator) {
56993 requestedKeyCount = retkeyCount;
56994 break;
56995 }
56996 }
56997
56998 UA_Variant_setArray(&output[2], requestedKeys, requestedKeyCount, &UA_TYPES[UA_TYPES_BYTESTRING]);
56999 return retval;
57000}
57001
57002static UA_StatusCode
57003getSecurityKeysAction(UA_Server *server, const UA_NodeId *sessionId, void *sessionHandle,
57004 const UA_NodeId *methodId, void *methodContext,
57005 const UA_NodeId *objectId, void *objectContext, size_t inputSize,
57006 const UA_Variant *input, size_t outputSize, UA_Variant *output) {
57007 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57008 return getSecurityKeysLocked(server, sessionId, sessionHandle,
57009 methodId, methodContext,
57010 objectId, objectContext, inputSize,
57011 input, outputSize, output);
57012}
57013#endif
57014
57015/**********************************************/
57016/* Destructors */
57017/**********************************************/
57018
57019static void
57020connectionTypeDestructor(UA_Server *server,
57021 const UA_NodeId *sessionId, void *sessionContext,
57022 const UA_NodeId *typeId, void *typeContext,
57023 const UA_NodeId *nodeId, void **nodeContext) {
57024 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57025 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_USERLAND,
57026 msg: "Connection destructor called!");
57027 UA_NodeId publisherIdNode =
57028 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "PublisherId"),
57029 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY), startingNode: *nodeId);
57030 UA_NodePropertyContext *ctx;
57031 getNodeContext(server, nodeId: publisherIdNode, nodeContext: (void **)&ctx);
57032 if(!UA_NodeId_isNull(p: &publisherIdNode))
57033 UA_free(ptr: ctx);
57034}
57035
57036static void
57037writerGroupTypeDestructor(UA_Server *server,
57038 const UA_NodeId *sessionId, void *sessionContext,
57039 const UA_NodeId *typeId, void *typeContext,
57040 const UA_NodeId *nodeId, void **nodeContext) {
57041 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57042 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_USERLAND,
57043 msg: "WriterGroup destructor called!");
57044 UA_NodeId intervalNode =
57045 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "PublishingInterval"),
57046 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY), startingNode: *nodeId);
57047 UA_NodePropertyContext *ctx;
57048 getNodeContext(server, nodeId: intervalNode, nodeContext: (void **)&ctx);
57049 if(!UA_NodeId_isNull(p: &intervalNode))
57050 UA_free(ptr: ctx);
57051}
57052
57053static void
57054readerGroupTypeDestructor(UA_Server *server,
57055 const UA_NodeId *sessionId, void *sessionContext,
57056 const UA_NodeId *typeId, void *typeContext,
57057 const UA_NodeId *nodeId, void **nodeContext) {
57058 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_USERLAND,
57059 msg: "ReaderGroup destructor called!");
57060}
57061
57062static void
57063dataSetWriterTypeDestructor(UA_Server *server,
57064 const UA_NodeId *sessionId, void *sessionContext,
57065 const UA_NodeId *typeId, void *typeContext,
57066 const UA_NodeId *nodeId, void **nodeContext) {
57067 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57068 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_USERLAND,
57069 msg: "DataSetWriter destructor called!");
57070 UA_NodeId dataSetWriterIdNode =
57071 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "DataSetWriterId"),
57072 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY), startingNode: *nodeId);
57073 UA_NodePropertyContext *ctx;
57074 getNodeContext(server, nodeId: dataSetWriterIdNode, nodeContext: (void **)&ctx);
57075 if(!UA_NodeId_isNull(p: &dataSetWriterIdNode))
57076 UA_free(ptr: ctx);
57077}
57078
57079static void
57080dataSetReaderTypeDestructor(UA_Server *server,
57081 const UA_NodeId *sessionId, void *sessionContext,
57082 const UA_NodeId *typeId, void *typeContext,
57083 const UA_NodeId *nodeId, void **nodeContext) {
57084 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57085 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_USERLAND,
57086 msg: "DataSetReader destructor called!");
57087 UA_NodeId publisherIdNode =
57088 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "PublisherId"),
57089 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY), startingNode: *nodeId);
57090 UA_NodePropertyContext *ctx;
57091 getNodeContext(server, nodeId: publisherIdNode, nodeContext: (void **)&ctx);
57092 if(!UA_NodeId_isNull(p: &publisherIdNode))
57093 UA_free(ptr: ctx);
57094}
57095
57096static void
57097publishedDataItemsTypeDestructor(UA_Server *server,
57098 const UA_NodeId *sessionId, void *sessionContext,
57099 const UA_NodeId *typeId, void *typeContext,
57100 const UA_NodeId *nodeId, void **nodeContext) {
57101 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57102 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_USERLAND,
57103 msg: "PublishedDataItems destructor called!");
57104 void *childContext;
57105 UA_NodeId node = findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "PublishedData"),
57106 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY), startingNode: *nodeId);
57107 getNodeContext(server, nodeId: node, nodeContext: (void**)&childContext);
57108 if(!UA_NodeId_isNull(p: &node))
57109 UA_free(ptr: childContext);
57110
57111 node = findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "ConfigurationVersion"),
57112 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
57113 startingNode: *nodeId);
57114 getNodeContext(server, nodeId: node, nodeContext: (void**)&childContext);
57115 if(!UA_NodeId_isNull(p: &node))
57116 UA_free(ptr: childContext);
57117
57118 node = findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "DataSetMetaData"),
57119 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY), startingNode: *nodeId);
57120 getNodeContext(server, nodeId: node, nodeContext: (void**)&childContext);
57121 if(!UA_NodeId_isNull(p: &node))
57122 UA_free(ptr: childContext);
57123}
57124
57125static void
57126standaloneSubscribedDataSetTypeDestructor(UA_Server *server,
57127 const UA_NodeId *sessionId, void *sessionContext,
57128 const UA_NodeId *typeId, void *typeContext,
57129 const UA_NodeId *nodeId, void **nodeContext) {
57130 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57131 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_USERLAND,
57132 msg: "Standalone SubscribedDataSet destructor called!");
57133 void *childContext;
57134 UA_NodeId node =
57135 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "DataSetMetaData"),
57136 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY), startingNode: *nodeId);
57137 getNodeContext(server, nodeId: node, nodeContext: (void**)&childContext);
57138 if(!UA_NodeId_equal(p1: &UA_NODEID_NULL , p2: &node))
57139 UA_free(ptr: childContext);
57140 node = findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "IsConnected"),
57141 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
57142 startingNode: *nodeId);
57143 getNodeContext(server, nodeId: node, nodeContext: (void**)&childContext);
57144 if(!UA_NodeId_equal(p1: &UA_NODEID_NULL , p2: &node))
57145 UA_free(ptr: childContext);
57146}
57147
57148/*************************************/
57149/* PubSub configurator */
57150/*************************************/
57151
57152#ifdef UA_ENABLE_PUBSUB_FILE_CONFIG
57153
57154/* Callback function that will be executed when the method "PubSub configurator
57155 * (replace config)" is called. */
57156static UA_StatusCode
57157UA_loadPubSubConfigMethodCallback(UA_Server *server,
57158 const UA_NodeId *sessionId, void *sessionHandle,
57159 const UA_NodeId *methodId, void *methodContext,
57160 const UA_NodeId *objectId, void *objectContext,
57161 size_t inputSize, const UA_Variant *input,
57162 size_t outputSize, UA_Variant *output) {
57163 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57164 if(inputSize == 1) {
57165 UA_ByteString *inputStr = (UA_ByteString*)input->data;
57166 UA_StatusCode res = UA_PubSubManager_loadPubSubConfigFromByteString(server, *inputStr);
57167 return res;
57168 } else if(inputSize > 1) {
57169 return UA_STATUSCODE_BADTOOMANYARGUMENTS;
57170 } else {
57171 return UA_STATUSCODE_BADARGUMENTSMISSING;
57172 }
57173}
57174
57175/* Callback function that will be executed when the method "PubSub configurator
57176 * (delete config)" is called. */
57177static UA_StatusCode
57178UA_deletePubSubConfigMethodCallback(UA_Server *server,
57179 const UA_NodeId *sessionId, void *sessionHandle,
57180 const UA_NodeId *methodId, void *methodContext,
57181 const UA_NodeId *objectId, void *objectContext,
57182 size_t inputSize, const UA_Variant *input,
57183 size_t outputSize, UA_Variant *output) {
57184 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57185 UA_PubSubManager_delete(server, &server->pubSubManager);
57186 return UA_STATUSCODE_GOOD;
57187}
57188
57189#endif
57190
57191UA_StatusCode
57192initPubSubNS0(UA_Server *server) {
57193 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57194
57195 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
57196 UA_String profileArray[1];
57197 profileArray[0] = UA_STRING(chars: "http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp");
57198
57199 retVal |= writePubSubNs0VariableArray(server,
57200 id: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE_SUPPORTEDTRANSPORTPROFILES),
57201 v: profileArray, length: 1, type: &UA_TYPES[UA_TYPES_STRING]);
57202
57203 if(server->config.pubSubConfig.enableInformationModelMethods) {
57204 /* Add missing references */
57205 retVal |= addRef(server, sourceId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS),
57206 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
57207 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETFOLDERTYPE_ADDDATASETFOLDER), true);
57208 retVal |= addRef(server, sourceId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS),
57209 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
57210 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMS), true);
57211 retVal |= addRef(server, sourceId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS),
57212 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
57213 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEPUBLISHEDDATASET), true);
57214 retVal |= addRef(server, sourceId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS),
57215 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT),
57216 targetId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEDATASETFOLDER), true);
57217
57218 /* Set method callbacks */
57219 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE_ADDCONNECTION), methodCallback: addPubSubConnectionAction);
57220 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE_REMOVECONNECTION), methodCallback: removeConnectionAction);
57221 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETFOLDERTYPE_ADDDATASETFOLDER), methodCallback: addDataSetFolderAction);
57222 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEDATASETFOLDER), methodCallback: removeDataSetFolderAction);
57223 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMS), methodCallback: addPublishedDataItemsAction);
57224 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEPUBLISHEDDATASET), methodCallback: removePublishedDataSetAction);
57225 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHEDDATAITEMSTYPE_ADDVARIABLES), methodCallback: addVariablesAction);
57226 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHEDDATAITEMSTYPE_REMOVEVARIABLES), methodCallback: removeVariablesAction);
57227 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDWRITERGROUP), methodCallback: addWriterGroupAction);
57228 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDREADERGROUP), methodCallback: addReaderGroupAction);
57229 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBSUBCONNECTIONTYPE_REMOVEGROUP), methodCallback: removeGroupAction);
57230 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_WRITERGROUPTYPE_ADDDATASETWRITER), methodCallback: addDataSetWriterAction);
57231 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_WRITERGROUPTYPE_REMOVEDATASETWRITER), methodCallback: removeDataSetWriterAction);
57232 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_READERGROUPTYPE_ADDDATASETREADER), methodCallback: addDataSetReaderAction);
57233 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_READERGROUPTYPE_REMOVEDATASETREADER), methodCallback: removeDataSetReaderAction);
57234 retVal |= setMethodNode_callback(server, methodNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_RESERVEIDS), methodCallback: addReserveIdsAction);
57235#ifdef UA_ENABLE_PUBSUB_SKS
57236 retVal |= setMethodNode_callback(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_SETSECURITYKEYS), setSecurityKeysAction);
57237 retVal |= setMethodNode_callback(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_GETSECURITYKEYS), getSecurityKeysAction);
57238#endif
57239
57240#ifdef UA_ENABLE_PUBSUB_FILE_CONFIG
57241 /* Adds method node to server. This method is used to load binary files for
57242 * PubSub configuration and delete / replace old PubSub configurations. */
57243 UA_Argument inputArgument;
57244 UA_Argument_init(&inputArgument);
57245 inputArgument.description = UA_LOCALIZEDTEXT("", "PubSub config binfile");
57246 inputArgument.name = UA_STRING("BinFile");
57247 inputArgument.dataType = UA_TYPES[UA_TYPES_BYTESTRING].typeId;
57248 inputArgument.valueRank = UA_VALUERANK_SCALAR;
57249
57250 UA_MethodAttributes configAttr = UA_MethodAttributes_default;
57251 configAttr.description = UA_LOCALIZEDTEXT("","Load binary configuration file");
57252 configAttr.displayName = UA_LOCALIZEDTEXT("","LoadPubSubConfigurationFile");
57253 configAttr.executable = true;
57254 configAttr.userExecutable = true;
57255 retVal |= addMethodNode(server, UA_NODEID_NULL,
57256 UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE),
57257 UA_NODEID_NUMERIC(0, UA_NS0ID_HASORDEREDCOMPONENT),
57258 UA_QUALIFIEDNAME(1, "PubSub configuration"),
57259 &configAttr, UA_loadPubSubConfigMethodCallback,
57260 1, &inputArgument, UA_NODEID_NULL, NULL,
57261 0, NULL, UA_NODEID_NULL, NULL,
57262 NULL, NULL);
57263
57264 /* Adds method node to server. This method is used to delete the current
57265 * PubSub configuration. */
57266 configAttr.description = UA_LOCALIZEDTEXT("","Delete current PubSub configuration");
57267 configAttr.displayName = UA_LOCALIZEDTEXT("","DeletePubSubConfiguration");
57268 configAttr.executable = true;
57269 configAttr.userExecutable = true;
57270 retVal |= addMethodNode(server, UA_NODEID_NULL,
57271 UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE),
57272 UA_NODEID_NUMERIC(0, UA_NS0ID_HASORDEREDCOMPONENT),
57273 UA_QUALIFIEDNAME(1, "Delete PubSub config"),
57274 &configAttr, UA_deletePubSubConfigMethodCallback,
57275 0, NULL, UA_NODEID_NULL, NULL,
57276 0, NULL, UA_NODEID_NULL, NULL,
57277 NULL, NULL);
57278#endif
57279 } else {
57280 /* Remove methods */
57281 retVal |= deleteReference(server, sourceNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE),
57282 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT), true,
57283 targetNodeId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE_ADDCONNECTION),
57284 false);
57285 retVal |= deleteReference(server, sourceNodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE),
57286 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT), true,
57287 targetNodeId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHSUBSCRIBE_REMOVECONNECTION),
57288 false);
57289 }
57290
57291 /* Set the object-type destructors */
57292 UA_NodeTypeLifecycle lifeCycle;
57293 lifeCycle.constructor = NULL;
57294
57295 lifeCycle.destructor = connectionTypeDestructor;
57296 retVal |= setNodeTypeLifecycle(server,
57297 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBSUBCONNECTIONTYPE),
57298 lifecycle: lifeCycle);
57299
57300 lifeCycle.destructor = writerGroupTypeDestructor;
57301 retVal |= setNodeTypeLifecycle(server,
57302 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_WRITERGROUPTYPE),
57303 lifecycle: lifeCycle);
57304
57305 lifeCycle.destructor = readerGroupTypeDestructor;
57306 retVal |= setNodeTypeLifecycle(server,
57307 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_READERGROUPTYPE),
57308 lifecycle: lifeCycle);
57309
57310 lifeCycle.destructor = dataSetWriterTypeDestructor;
57311 retVal |= setNodeTypeLifecycle(server,
57312 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETWRITERTYPE),
57313 lifecycle: lifeCycle);
57314
57315 lifeCycle.destructor = publishedDataItemsTypeDestructor;
57316 retVal |= setNodeTypeLifecycle(server,
57317 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_PUBLISHEDDATAITEMSTYPE),
57318 lifecycle: lifeCycle);
57319
57320 lifeCycle.destructor = dataSetReaderTypeDestructor;
57321 retVal |= setNodeTypeLifecycle(server,
57322 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_DATASETREADERTYPE),
57323 lifecycle: lifeCycle);
57324
57325 lifeCycle.destructor = standaloneSubscribedDataSetTypeDestructor;
57326 retVal |= setNodeTypeLifecycle(server,
57327 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_STANDALONESUBSCRIBEDDATASETTYPE),
57328 lifecycle: lifeCycle);
57329
57330 return retVal;
57331}
57332
57333UA_StatusCode
57334connectDataSetReaderToDataSet(UA_Server *server, UA_NodeId dsrId, UA_NodeId standaloneSdsId) {
57335 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57336
57337 UA_StatusCode retVal = UA_STATUSCODE_GOOD;
57338
57339 UA_NodeId dataSetMetaDataOnDsrId =
57340 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "DataSetMetaData"),
57341 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY), startingNode: dsrId);
57342 UA_NodeId subscribedDataSetOnDsrId =
57343 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "SubscribedDataSet"),
57344 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT), startingNode: dsrId);
57345 UA_NodeId dataSetMetaDataOnSdsId =
57346 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "DataSetMetaData"),
57347 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY), startingNode: standaloneSdsId);
57348 UA_NodeId subscribedDataSetOnSdsId =
57349 findSingleChildNode(server, targetName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "SubscribedDataSet"),
57350 referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASCOMPONENT), startingNode: standaloneSdsId);
57351
57352 if(UA_NodeId_isNull(p: &dataSetMetaDataOnDsrId) ||
57353 UA_NodeId_isNull(p: &subscribedDataSetOnDsrId) ||
57354 UA_NodeId_isNull(p: &dataSetMetaDataOnSdsId) ||
57355 UA_NodeId_isNull(p: &subscribedDataSetOnSdsId))
57356 return UA_STATUSCODE_BADNOTFOUND;
57357
57358 UA_NODESTORE_REMOVE(server, &dataSetMetaDataOnDsrId);
57359 UA_NODESTORE_REMOVE(server, &subscribedDataSetOnDsrId);
57360
57361 retVal |= addRef(server, sourceId: dsrId, referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
57362 targetId: UA_NODEID_NUMERIC(nsIndex: dataSetMetaDataOnSdsId.namespaceIndex,
57363 identifier: dataSetMetaDataOnSdsId.identifier.numeric), true);
57364 retVal |= addRef(server, sourceId: dsrId, referenceTypeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HASPROPERTY),
57365 targetId: UA_NODEID_NUMERIC(nsIndex: subscribedDataSetOnSdsId.namespaceIndex,
57366 identifier: subscribedDataSetOnSdsId.identifier.numeric), true);
57367
57368 return retVal;
57369}
57370
57371#endif /* UA_ENABLE_PUBSUB_INFORMATIONMODEL */
57372
57373/**** amalgamated original file "/src/pubsub/ua_pubsub_keystorage.c" ****/
57374
57375/* This Source Code Form is subject to the terms of the Mozilla Public
57376 * License, v. 2.0. If a copy of the MPL was not distributed with this
57377 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
57378 *
57379 * Copyright (c) 2019 ifak e.V. Magdeburg (Holger Zipper)
57380 * Copyright (c) 2022 Linutronix GmbH (Author: Muddasir Shakil)
57381 */
57382
57383
57384#ifdef UA_ENABLE_PUBSUB_SKS /* conditional compilation */
57385
57386#define UA_REQ_CURRENT_TOKEN 0
57387
57388
57389UA_PubSubKeyStorage *
57390UA_PubSubKeyStorage_findKeyStorage(UA_Server *server, UA_String securityGroupId) {
57391 if(!server || UA_String_isEmpty(&securityGroupId))
57392 return NULL;
57393
57394 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57395
57396 UA_PubSubKeyStorage *outKeyStorage;
57397 LIST_FOREACH(outKeyStorage, &server->pubSubManager.pubSubKeyList, keyStorageList) {
57398 if(UA_String_equal(&outKeyStorage->securityGroupID, &securityGroupId))
57399 return outKeyStorage;
57400 }
57401 return NULL;
57402}
57403
57404UA_PubSubSecurityPolicy *
57405findPubSubSecurityPolicy(UA_Server *server, const UA_String *securityPolicyUri) {
57406 if(!server || !securityPolicyUri)
57407 return NULL;
57408
57409 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57410
57411 UA_ServerConfig *config = &server->config;
57412 for(size_t i = 0; i < config->pubSubConfig.securityPoliciesSize; i++) {
57413 if(UA_String_equal(securityPolicyUri,
57414 &config->pubSubConfig.securityPolicies[i].policyUri))
57415 return &config->pubSubConfig.securityPolicies[i];
57416 }
57417 return NULL;
57418}
57419
57420static void
57421UA_PubSubKeyStorage_clearKeyList(UA_PubSubKeyStorage *keyStorage) {
57422 if(TAILQ_EMPTY(&keyStorage->keyList))
57423 return;
57424
57425 UA_PubSubKeyListItem *item, *item_tmp;
57426 TAILQ_FOREACH_SAFE(item, &keyStorage->keyList, keyListEntry, item_tmp) {
57427 TAILQ_REMOVE(&keyStorage->keyList, item, keyListEntry);
57428 UA_ByteString_clear(&item->key);
57429 UA_free(item);
57430 }
57431 keyStorage->keyListSize = 0;
57432}
57433
57434void
57435UA_PubSubKeyStorage_delete(UA_Server *server, UA_PubSubKeyStorage *keyStorage) {
57436 UA_assert(keyStorage != NULL);
57437 UA_assert(server != NULL);
57438
57439 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57440
57441 /* Remove callback */
57442 if(!keyStorage->callBackId != 0) {
57443 removeCallback(server, keyStorage->callBackId);
57444 keyStorage->callBackId = 0;
57445 }
57446
57447 UA_PubSubKeyStorage_clearKeyList(keyStorage);
57448 UA_String_clear(&keyStorage->securityGroupID);
57449 UA_ClientConfig_clear(&keyStorage->sksConfig.clientConfig);
57450 UA_free(keyStorage);
57451}
57452
57453UA_StatusCode
57454UA_PubSubKeyStorage_init(UA_Server *server, UA_PubSubKeyStorage *keyStorage,
57455 const UA_String *securityGroupId,
57456 UA_PubSubSecurityPolicy *policy,
57457 UA_UInt32 maxPastKeyCount, UA_UInt32 maxFutureKeyCount) {
57458 UA_StatusCode res = UA_String_copy(securityGroupId, &keyStorage->securityGroupID);
57459 if(res != UA_STATUSCODE_GOOD)
57460 return res;
57461
57462 UA_UInt32 currentkeyCount = 1;
57463 keyStorage->maxPastKeyCount = maxPastKeyCount;
57464 keyStorage->maxFutureKeyCount = maxFutureKeyCount;
57465 keyStorage->maxKeyListSize = maxPastKeyCount + currentkeyCount + maxFutureKeyCount;
57466 keyStorage->policy = policy;
57467
57468 /* Add this keystorage to the server keystoragelist */
57469 LIST_INSERT_HEAD(&server->pubSubManager.pubSubKeyList, keyStorage, keyStorageList);
57470
57471 return UA_STATUSCODE_GOOD;
57472}
57473
57474UA_StatusCode
57475UA_PubSubKeyStorage_storeSecurityKeys(UA_Server *server, UA_PubSubKeyStorage *keyStorage,
57476 UA_UInt32 currentTokenId, const UA_ByteString *currentKey,
57477 UA_ByteString *futureKeys, size_t futureKeyCount,
57478 UA_Duration msKeyLifeTime) {
57479 UA_assert(server);
57480 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57481
57482 UA_StatusCode retval = UA_STATUSCODE_BAD;
57483
57484 if(futureKeyCount > 0 && !futureKeys) {
57485 retval = UA_STATUSCODE_BADARGUMENTSMISSING;
57486 goto error;
57487 }
57488
57489 size_t keyNumber = futureKeyCount;
57490
57491 if(currentKey && keyStorage->keyListSize == 0) {
57492
57493 keyStorage->keyListSize++;
57494 UA_PubSubKeyListItem *keyItem =
57495 (UA_PubSubKeyListItem *)UA_calloc(1, sizeof(UA_PubSubKeyListItem));
57496 if(!keyItem)
57497 goto error;
57498 retval = UA_ByteString_copy(currentKey, &keyItem->key);
57499 if(UA_StatusCode_isBad(retval))
57500 goto error;
57501
57502 keyItem->keyID = currentTokenId;
57503
57504 TAILQ_INIT(&keyStorage->keyList);
57505 TAILQ_INSERT_HEAD(&keyStorage->keyList, keyItem, keyListEntry);
57506 }
57507
57508 UA_PubSubKeyListItem *keyListIterator = TAILQ_FIRST(&keyStorage->keyList);
57509 UA_UInt32 startingTokenID = currentTokenId + 1;
57510 for(size_t i = 0; i < keyNumber; ++i) {
57511 retval = UA_PubSubKeyStorage_getKeyByKeyID(
57512 startingTokenID, keyStorage, &keyListIterator);
57513 /*Skipping key with matching KeyID in existing list*/
57514 if(retval == UA_STATUSCODE_BADNOTFOUND) {
57515 keyListIterator = UA_PubSubKeyStorage_push(keyStorage, &futureKeys[i], startingTokenID);
57516 if(!keyListIterator)
57517 goto error;
57518
57519 keyStorage->keyListSize++;
57520 }
57521 if(startingTokenID == UA_UINT32_MAX)
57522 startingTokenID = 1;
57523 else
57524 ++startingTokenID;
57525 }
57526
57527 /*update keystorage references*/
57528 retval = UA_PubSubKeyStorage_getKeyByKeyID(currentTokenId, keyStorage, &keyStorage->currentItem);
57529 if (retval != UA_STATUSCODE_GOOD && !keyStorage->currentItem)
57530 goto error;
57531
57532 keyStorage->keyLifeTime = msKeyLifeTime;
57533
57534 return retval;
57535error:
57536 if(keyStorage) {
57537 UA_PubSubKeyStorage_clearKeyList(keyStorage);
57538 }
57539 return retval;
57540}
57541
57542UA_StatusCode
57543UA_PubSubKeyStorage_getKeyByKeyID(const UA_UInt32 keyId, UA_PubSubKeyStorage *keyStorage,
57544 UA_PubSubKeyListItem **keyItem) {
57545
57546 if(!keyStorage)
57547 return UA_STATUSCODE_BADINVALIDARGUMENT;
57548
57549 UA_PubSubKeyListItem *item;
57550 TAILQ_FOREACH(item, &keyStorage->keyList, keyListEntry){
57551 if(item->keyID == keyId) {
57552 *keyItem = item;
57553 return UA_STATUSCODE_GOOD;
57554 }
57555 }
57556 return UA_STATUSCODE_BADNOTFOUND;
57557}
57558
57559UA_PubSubKeyListItem *
57560UA_PubSubKeyStorage_push(UA_PubSubKeyStorage *keyStorage, const UA_ByteString *key,
57561 UA_UInt32 keyID) {
57562 UA_PubSubKeyListItem *newItem = (UA_PubSubKeyListItem *)malloc(sizeof(UA_PubSubKeyListItem));
57563 if (!newItem)
57564 return NULL;
57565
57566 newItem->keyID = keyID;
57567 UA_ByteString_copy(key, &newItem->key);
57568 TAILQ_INSERT_TAIL(&keyStorage->keyList, newItem, keyListEntry);
57569
57570 return TAILQ_LAST(&keyStorage->keyList, keyListItems);
57571}
57572
57573UA_StatusCode
57574UA_PubSubKeyStorage_addKeyRolloverCallback(UA_Server *server,
57575 UA_PubSubKeyStorage *keyStorage,
57576 UA_ServerCallback callback,
57577 UA_Duration timeToNextMs,
57578 UA_UInt64 *callbackID) {
57579 if(!server || !keyStorage || !callback || timeToNextMs <= 0)
57580 return UA_STATUSCODE_BADINVALIDARGUMENT;
57581
57582 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57583
57584 UA_EventLoop *el = server->config.eventLoop;
57585 if(*callbackID != 0)
57586 el->removeCyclicCallback(el, *callbackID);
57587
57588 UA_DateTime dateTimeToNextKey = UA_DateTime_nowMonotonic() +
57589 (UA_DateTime)(UA_DATETIME_MSEC * timeToNextMs);
57590 return el->addTimedCallback(el, (UA_Callback)callback, server, keyStorage,
57591 dateTimeToNextKey, callbackID);
57592}
57593
57594static UA_StatusCode
57595splitCurrentKeyMaterial(UA_PubSubKeyStorage *keyStorage, UA_ByteString *signingKey,
57596 UA_ByteString *encryptingKey, UA_ByteString *keyNonce) {
57597 if(!keyStorage)
57598 return UA_STATUSCODE_BADNOTFOUND;
57599
57600 if(!keyStorage->policy)
57601 return UA_STATUSCODE_BADINTERNALERROR;
57602
57603 UA_PubSubSecurityPolicy *policy = keyStorage->policy;
57604
57605 UA_ByteString key = keyStorage->currentItem->key;
57606
57607 /*Check the main key length is the same according to policy*/
57608 if(key.length != policy->symmetricModule.secureChannelNonceLength)
57609 return UA_STATUSCODE_BADINTERNALERROR;
57610
57611 /*Get Key Length according to policy*/
57612 size_t signingkeyLength =
57613 policy->symmetricModule.cryptoModule.signatureAlgorithm.getLocalKeyLength(NULL);
57614 size_t encryptkeyLength =
57615 policy->symmetricModule.cryptoModule.encryptionAlgorithm.getLocalKeyLength(NULL);
57616 /*Rest of the part is the keyNonce*/
57617 size_t keyNonceLength = key.length - signingkeyLength - encryptkeyLength;
57618
57619 /*DivideKeys in origin ByteString*/
57620 signingKey->data = key.data;
57621 signingKey->length = signingkeyLength;
57622
57623 encryptingKey->data = key.data + signingkeyLength;
57624 encryptingKey->length = encryptkeyLength;
57625
57626 keyNonce->data = key.data + signingkeyLength + encryptkeyLength;
57627 keyNonce->length = keyNonceLength;
57628
57629 return UA_STATUSCODE_GOOD;
57630}
57631
57632static UA_StatusCode
57633setPubSubGroupEncryptingKey(UA_Server *server, UA_NodeId PubSubGroupId, UA_UInt32 securityTokenId,
57634 UA_ByteString signingKey, UA_ByteString encryptingKey,
57635 UA_ByteString keyNonce) {
57636 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57637 UA_StatusCode retval =
57638 setWriterGroupEncryptionKeys(server, PubSubGroupId, securityTokenId,
57639 signingKey, encryptingKey, keyNonce);
57640 if(retval == UA_STATUSCODE_BADNOTFOUND)
57641 retval = setReaderGroupEncryptionKeys(server, PubSubGroupId, securityTokenId,
57642 signingKey, encryptingKey, keyNonce);
57643 return retval;
57644}
57645
57646static UA_StatusCode
57647setPubSubGroupEncryptingKeyForMatchingSecurityGroupId(UA_Server *server,
57648 UA_String securityGroupId,
57649 UA_UInt32 securityTokenId,
57650 UA_ByteString signingKey,
57651 UA_ByteString encryptingKey,
57652 UA_ByteString keyNonce) {
57653 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57654 UA_StatusCode retval = UA_STATUSCODE_BAD;
57655 UA_PubSubConnection *tmpPubSubConnections;
57656
57657 /* Key storage is the same for all reader / writer groups, channel context isn't
57658 * => Update channelcontext in all Writergroups / ReaderGroups which have the same
57659 * securityGroupId*/
57660 TAILQ_FOREACH(tmpPubSubConnections, &server->pubSubManager.connections, listEntry) {
57661 /* For each writerGroup in server with matching SecurityGroupId */
57662 UA_WriterGroup *tmpWriterGroup;
57663 LIST_FOREACH(tmpWriterGroup, &tmpPubSubConnections->writerGroups, listEntry) {
57664 if(UA_String_equal(&tmpWriterGroup->config.securityGroupId, &securityGroupId)) {
57665 retval = setWriterGroupEncryptionKeys(server, tmpWriterGroup->identifier,
57666 securityTokenId, signingKey,
57667 encryptingKey, keyNonce);
57668 if(retval != UA_STATUSCODE_GOOD)
57669 return retval;
57670 }
57671 }
57672
57673 /* For each readerGroup in server with matching SecurityGroupId */
57674 UA_ReaderGroup *tmpReaderGroup;
57675 LIST_FOREACH(tmpReaderGroup, &tmpPubSubConnections->readerGroups, listEntry) {
57676 if(UA_String_equal(&tmpReaderGroup->config.securityGroupId, &securityGroupId)) {
57677 retval = setReaderGroupEncryptionKeys(server, tmpReaderGroup->identifier,
57678 securityTokenId, signingKey,
57679 encryptingKey, keyNonce);
57680 if(retval != UA_STATUSCODE_GOOD)
57681 return retval;
57682 }
57683 }
57684 }
57685 return retval;
57686}
57687
57688UA_StatusCode
57689UA_PubSubKeyStorage_activateKeyToChannelContext(UA_Server *server, UA_NodeId pubSubGroupId,
57690 UA_String securityGroupId) {
57691 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57692 if(securityGroupId.data == NULL)
57693 return UA_STATUSCODE_BADINVALIDARGUMENT;
57694
57695 UA_PubSubKeyStorage *keyStorage =
57696 UA_PubSubKeyStorage_findKeyStorage(server, securityGroupId);
57697 if(!keyStorage)
57698 return UA_STATUSCODE_BADNOTFOUND;
57699
57700 if(!keyStorage->policy && !(keyStorage->keyListSize > 0))
57701 return UA_STATUSCODE_BADINTERNALERROR;
57702
57703 UA_UInt32 securityTokenId = keyStorage->currentItem->keyID;
57704
57705 /*DivideKeys in origin ByteString*/
57706 UA_ByteString signingKey;
57707 UA_ByteString encryptKey;
57708 UA_ByteString keyNonce;
57709 UA_StatusCode retval = splitCurrentKeyMaterial(keyStorage, &signingKey,
57710 &encryptKey, &keyNonce);
57711 if(retval != UA_STATUSCODE_GOOD)
57712 return retval;
57713
57714 if(!UA_NodeId_isNull(&pubSubGroupId))
57715 retval = setPubSubGroupEncryptingKey(server, pubSubGroupId, securityTokenId,
57716 signingKey, encryptKey, keyNonce);
57717 else
57718 retval = setPubSubGroupEncryptingKeyForMatchingSecurityGroupId(
57719 server, securityGroupId, securityTokenId, signingKey, encryptKey, keyNonce);
57720
57721 if(retval != UA_STATUSCODE_GOOD)
57722 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
57723 "Failed to set Encrypting keys with Error: %s",
57724 UA_StatusCode_name(retval));
57725
57726 return retval;
57727}
57728
57729static void
57730nextGetSecuritykeysCallback(UA_Server *server, UA_PubSubKeyStorage *keyStorage) {
57731 UA_StatusCode retval = UA_STATUSCODE_BAD;
57732 if(!keyStorage) {
57733 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
57734 "GetSecurityKeysCall Failed with error: KeyStorage does not exist "
57735 "in the server");
57736 return;
57737 }
57738 retval = getSecurityKeysAndStoreFetchedKeys(server, keyStorage);
57739 if(retval != UA_STATUSCODE_GOOD)
57740 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
57741 "GetSecurityKeysCall Failed with error: %s ",
57742 UA_StatusCode_name(retval));
57743}
57744
57745void
57746UA_PubSubKeyStorage_keyRolloverCallback(UA_Server *server, UA_PubSubKeyStorage *keyStorage) {
57747 /* Callbacks from the EventLoop are initially unlocked */
57748 lockServer(server);
57749 UA_StatusCode retval =
57750 UA_PubSubKeyStorage_addKeyRolloverCallback(server, keyStorage,
57751 (UA_ServerCallback)UA_PubSubKeyStorage_keyRolloverCallback,
57752 keyStorage->keyLifeTime, &keyStorage->callBackId);
57753 if(retval != UA_STATUSCODE_GOOD) {
57754 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
57755 "Failed to update keys for security group id '%.*s'. Reason: '%s'.",
57756 (int)keyStorage->securityGroupID.length,
57757 keyStorage->securityGroupID.data, UA_StatusCode_name(retval));
57758 }
57759
57760 if(keyStorage->currentItem != TAILQ_LAST(&keyStorage->keyList, keyListItems)) {
57761 keyStorage->currentItem = TAILQ_NEXT(keyStorage->currentItem, keyListEntry);
57762 keyStorage->currentTokenId = keyStorage->currentItem->keyID;
57763 retval = UA_PubSubKeyStorage_activateKeyToChannelContext(server, UA_NODEID_NULL,
57764 keyStorage->securityGroupID);
57765 if(retval != UA_STATUSCODE_GOOD) {
57766 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
57767 "Failed to update keys for security group id '%.*s'. Reason: '%s'.",
57768 (int)keyStorage->securityGroupID.length, keyStorage->securityGroupID.data,
57769 UA_StatusCode_name(retval));
57770 }
57771 } else if(keyStorage->sksConfig.endpointUrl && keyStorage->sksConfig.reqId == 0) {
57772 UA_DateTime now = UA_DateTime_nowMonotonic();
57773 /*Publishers using a central SKS shall call GetSecurityKeys at a period of half the KeyLifetime */
57774 UA_Duration msTimeToNextGetSecurityKeys = keyStorage->keyLifeTime / 2;
57775 UA_DateTime dateTimeToNextGetSecurityKeys =
57776 now + (UA_DateTime)(UA_DATETIME_MSEC * msTimeToNextGetSecurityKeys);
57777 retval = server->config.eventLoop->addTimedCallback(
57778 server->config.eventLoop, (UA_Callback)nextGetSecuritykeysCallback, server,
57779 keyStorage, dateTimeToNextGetSecurityKeys, NULL);
57780 }
57781 unlockServer(server);
57782}
57783
57784UA_StatusCode
57785UA_PubSubKeyStorage_update(UA_Server *server, UA_PubSubKeyStorage *keyStorage,
57786 const UA_ByteString *currentKey, UA_UInt32 currentKeyID,
57787 const size_t futureKeySize, UA_ByteString *futureKeys,
57788 UA_Duration msKeyLifeTime) {
57789 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57790 if(!keyStorage)
57791 return UA_STATUSCODE_BADINVALIDARGUMENT;
57792
57793 UA_StatusCode retval = UA_STATUSCODE_GOOD;
57794 UA_PubSubKeyListItem *keyListIterator = NULL;
57795
57796 if(currentKeyID != 0){
57797 /* If currentKeyId is known then update keystorage currentItem */
57798 retval = UA_PubSubKeyStorage_getKeyByKeyID(currentKeyID, keyStorage,
57799 &keyListIterator);
57800 if(retval == UA_STATUSCODE_GOOD && keyListIterator) {
57801 keyStorage->currentItem = keyListIterator;
57802 /* Add new keys at the end of KeyList */
57803 retval = UA_PubSubKeyStorage_storeSecurityKeys(server, keyStorage, currentKeyID,
57804 NULL, futureKeys, futureKeySize,
57805 msKeyLifeTime);
57806 if(retval != UA_STATUSCODE_GOOD)
57807 return retval;
57808 } else if(retval == UA_STATUSCODE_BADNOTFOUND) {
57809 /* If the CurrentTokenId is unknown, the existing list shall be
57810 * discarded and replaced by the fetched list */
57811 UA_PubSubKeyStorage_clearKeyList(keyStorage);
57812 retval = UA_PubSubKeyStorage_storeSecurityKeys(server, keyStorage,
57813 currentKeyID, currentKey, futureKeys,
57814 futureKeySize, msKeyLifeTime);
57815 if(retval != UA_STATUSCODE_GOOD)
57816 return retval;
57817 }
57818 }
57819 return retval;
57820}
57821
57822void
57823UA_PubSubKeyStorage_detachKeyStorage(UA_Server *server, UA_PubSubKeyStorage *keyStorage) {
57824 UA_LOCK_ASSERT(&server->serviceMutex, 1);
57825
57826 keyStorage->referenceCount--;
57827 if(keyStorage->referenceCount == 0) {
57828 LIST_REMOVE(keyStorage, keyStorageList);
57829 UA_PubSubKeyStorage_delete(server, keyStorage);
57830 }
57831}
57832
57833/**
57834 * @brief It holds the information required in the async callback to
57835 * GetSecurityKeys method Call.
57836 */
57837typedef struct {
57838 UA_Server *server;
57839 UA_PubSubKeyStorage *ks;
57840 UA_UInt32 startingTokenId;
57841 UA_UInt32 requestedKeyCount;
57842 UA_DelayedCallback dc;
57843} sksClientContext;
57844
57845static void sksClientCleanupCb(void *client, void *context);
57846
57847static void
57848addDelayedSksClientCleanupCb(UA_Client *client, sksClientContext *context) {
57849 /* Register at most once */
57850 if(context->dc.application != NULL)
57851 return;
57852 context->dc.application = client;
57853 context->dc.callback = sksClientCleanupCb;
57854 context->dc.context = context;
57855 client->config.eventLoop->addDelayedCallback(client->config.eventLoop, &context->dc);
57856}
57857
57858static void
57859sksClientCleanupCb(void *client, void *context) {
57860 UA_Client *sksClient = (UA_Client *)client;
57861 sksClientContext *ctx = (sksClientContext*)context;
57862
57863 /* we do not want to call state change Callback when cleaning up */
57864 sksClient->config.stateCallback = NULL;
57865
57866 if(sksClient->sessionState > UA_SESSIONSTATE_CLOSED &&
57867 sksClient->channel.state < UA_SECURECHANNELSTATE_CLOSED) {
57868 sksClient->config.eventLoop->
57869 addDelayedCallback(sksClient->config.eventLoop, &ctx->dc);
57870 UA_Client_disconnectAsync(sksClient);
57871 return;
57872 }
57873
57874 if(sksClient->channel.state == UA_SECURECHANNELSTATE_CLOSED) {
57875 /* We cannot make deep copy of the following pointers because these have
57876 * internal structures, therefore we do not free them here. These will
57877 * be freed in UA_PubSubKeyStorage_delete. */
57878 sksClient->config.securityPolicies = NULL;
57879 sksClient->config.securityPoliciesSize = 0;
57880 sksClient->config.authSecurityPolicies = NULL;
57881 sksClient->config.authSecurityPoliciesSize = 0;
57882 sksClient->config.certificateVerification.context = NULL;
57883 sksClient->config.logging = NULL;
57884 sksClient->config.clientContext = NULL;
57885 UA_Client_delete(sksClient);
57886 UA_free(context);
57887 } else {
57888 sksClient->config.eventLoop->
57889 addDelayedCallback(sksClient->config.eventLoop, &ctx->dc);
57890 }
57891}
57892
57893static void
57894storeFetchedKeys(UA_Client *client, void *userdata, UA_UInt32 requestId,
57895 UA_CallResponse *response) {
57896
57897 sksClientContext *ctx = (sksClientContext *)userdata;
57898 UA_PubSubKeyStorage *ks = ctx->ks;
57899 UA_Server *server = ctx->server;
57900 UA_StatusCode retval = response->responseHeader.serviceResult;
57901
57902 lockServer(server);
57903 /* check if the call to getSecurityKeys was a success */
57904 if(response->resultsSize != 0)
57905 retval = response->results->statusCode;
57906 if(retval != UA_STATUSCODE_GOOD) {
57907 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
57908 "SKS Client: Failed to call GetSecurityKeys on SKS server with error: %s ",
57909 UA_StatusCode_name(retval));
57910 goto cleanup;
57911 }
57912
57913 UA_String *securityPolicyUri = (UA_String *)response->results->outputArguments[0].data;
57914 UA_UInt32 firstTokenId = *(UA_UInt32 *)response->results->outputArguments[1].data;
57915 UA_ByteString *keys = (UA_ByteString *)response->results->outputArguments[2].data;
57916 UA_ByteString *currentKey = &keys[0];
57917 UA_UInt32 currentKeyCount = 1;
57918 UA_ByteString *futureKeys = &keys[currentKeyCount];
57919 size_t futureKeySize = response->results->outputArguments[2].arrayLength - currentKeyCount;
57920 UA_Duration msKeyLifeTime = *(UA_Duration *)response->results->outputArguments[4].data;
57921
57922 if(!UA_String_equal(securityPolicyUri, &ks->policy->policyUri)) {
57923 retval = UA_STATUSCODE_BADSECURITYPOLICYREJECTED;
57924 goto cleanup;
57925 }
57926
57927 if(ks->keyListSize == 0) {
57928 retval = UA_PubSubKeyStorage_storeSecurityKeys(server, ks, firstTokenId,
57929 currentKey, futureKeys,
57930 futureKeySize, msKeyLifeTime);
57931 if(retval != UA_STATUSCODE_GOOD)
57932 goto cleanup;
57933 } else {
57934 retval = UA_PubSubKeyStorage_update(server, ks, currentKey, firstTokenId,
57935 futureKeySize, futureKeys, msKeyLifeTime);
57936 if(retval != UA_STATUSCODE_GOOD)
57937 goto cleanup;
57938 }
57939
57940 /**
57941 * After a new batch of keys is fetched from SKS server, the key storage is updated
57942 * with new keys and new keylifetime. Also the remaining time for current
57943 * keyRollover is also returned. When setting a new keyRollover callback, the
57944 * previous callback must be removed so that the keyRollover does not happen twice
57945 */
57946 if(ks->callBackId != 0) {
57947 server->config.eventLoop->removeCyclicCallback(server->config.eventLoop,
57948 ks->callBackId);
57949 ks->callBackId = 0;
57950 }
57951
57952 UA_Duration msTimeToNextKey =
57953 *(UA_Duration *)response->results->outputArguments[3].data;
57954 if(!(msTimeToNextKey > 0))
57955 msTimeToNextKey = ks->keyLifeTime;
57956 retval = UA_PubSubKeyStorage_addKeyRolloverCallback(
57957 server, ks, (UA_ServerCallback)UA_PubSubKeyStorage_keyRolloverCallback,
57958 msTimeToNextKey, &ks->callBackId);
57959
57960cleanup:
57961 if(retval != UA_STATUSCODE_GOOD) {
57962 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
57963 "Failed to store the fetched keys from SKS server with error: %s",
57964 UA_StatusCode_name(retval));
57965 }
57966 /* call user callback to notify about the status */
57967 if(ks->sksConfig.userNotifyCallback)
57968 ks->sksConfig.userNotifyCallback(server, retval, ks->sksConfig.context);
57969 ks->sksConfig.reqId = 0;
57970 UA_Client_disconnectAsync(client);
57971 addDelayedSksClientCleanupCb(client, ctx);
57972
57973 unlockServer(server);
57974}
57975
57976static UA_StatusCode
57977callGetSecurityKeysMethod(UA_Client *client) {
57978
57979 sksClientContext *ctx = (sksClientContext *)client->config.clientContext;
57980
57981 UA_Variant inputArguments[3];
57982 UA_Variant_setScalar(&inputArguments[0], &ctx->ks->securityGroupID,
57983 &UA_TYPES[UA_TYPES_STRING]);
57984 UA_Variant_setScalar(&inputArguments[1], &ctx->startingTokenId,
57985 &UA_TYPES[UA_TYPES_UINT32]);
57986 UA_Variant_setScalar(&inputArguments[2], &ctx->requestedKeyCount,
57987 &UA_TYPES[UA_TYPES_UINT32]);
57988
57989 UA_NodeId objectId = UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE);
57990 UA_NodeId methodId = UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_GETSECURITYKEYS);
57991 size_t inputArgumentsSize = 3;
57992
57993 UA_StatusCode retval = UA_Client_call_async(client, objectId, methodId, inputArgumentsSize,
57994 inputArguments, storeFetchedKeys, (void *)ctx, &ctx->ks->sksConfig.reqId);
57995 return retval;
57996}
57997
57998static void
57999onConnect(UA_Client *client, UA_SecureChannelState channelState,
58000 UA_SessionState sessionState, UA_StatusCode connectStatus) {
58001 UA_Boolean triggerSKSCleanup = false;
58002 if(connectStatus != UA_STATUSCODE_GOOD &&
58003 connectStatus != UA_STATUSCODE_BADNOTCONNECTED &&
58004 sessionState != UA_SESSIONSTATE_ACTIVATED) {
58005 UA_LOG_ERROR(client->config.logging, UA_LOGCATEGORY_CLIENT,
58006 "SKS Client: Failed to connect SKS server with error: %s ",
58007 UA_StatusCode_name(connectStatus));
58008 triggerSKSCleanup = true;
58009 }
58010 if(connectStatus == UA_STATUSCODE_GOOD && sessionState == UA_SESSIONSTATE_ACTIVATED) {
58011 connectStatus = callGetSecurityKeysMethod(client);
58012 if(connectStatus != UA_STATUSCODE_GOOD) {
58013 UA_LOG_ERROR(client->config.logging, UA_LOGCATEGORY_SERVER,
58014 "SKS Client: Failed to call GetSecurityKeys on SKS server with "
58015 "error: %s ",
58016 UA_StatusCode_name(connectStatus));
58017 triggerSKSCleanup = true;
58018 }
58019 }
58020 if(triggerSKSCleanup) {
58021 /* call user callback to notify about the status */
58022 sksClientContext *ctx = (sksClientContext *)client->config.clientContext;
58023 UA_PubSubKeyStorage *ks = ctx->ks;
58024 if(ks->sksConfig.userNotifyCallback)
58025 ks->sksConfig.userNotifyCallback(ctx->server, connectStatus,
58026 ks->sksConfig.context);
58027 UA_Client_disconnectAsync(client);
58028 addDelayedSksClientCleanupCb(client, ctx);
58029 }
58030}
58031
58032static void
58033setServerEventloopOnSksClient(UA_ClientConfig *cc, UA_EventLoop *externalEventloop) {
58034 UA_assert(externalEventloop != NULL);
58035 cc->eventLoop = externalEventloop;
58036 cc->externalEventLoop = true;
58037}
58038
58039UA_StatusCode
58040getSecurityKeysAndStoreFetchedKeys(UA_Server *server, UA_PubSubKeyStorage *keyStorage) {
58041 UA_StatusCode retval = UA_STATUSCODE_BAD;
58042 UA_UInt32 startingTokenId = UA_REQ_CURRENT_TOKEN;
58043 UA_UInt32 requestKeyCount = UA_UINT32_MAX;
58044
58045 if(keyStorage->sksConfig.reqId != 0) {
58046 UA_LOG_INFO(server->config.logging, UA_LOGCATEGORY_SERVER,
58047 "SKS Client: SKS Pull request in process ");
58048 return UA_STATUSCODE_GOOD;
58049 }
58050
58051 UA_ClientConfig cc;
58052 memset(&cc, 0, sizeof(UA_ClientConfig));
58053
58054 /* over write the client config with user specified SKS config */
58055 retval = UA_ClientConfig_copy(&keyStorage->sksConfig.clientConfig, &cc);
58056 if(retval != UA_STATUSCODE_GOOD)
58057 return retval;
58058
58059 setServerEventloopOnSksClient(&cc, server->config.eventLoop);
58060
58061 /* this is cleanedup in sksClientCleanupCb */
58062 sksClientContext *ctx = (sksClientContext *)UA_calloc(1, sizeof(sksClientContext));
58063 if(!ctx)
58064 return UA_STATUSCODE_BADOUTOFMEMORY;
58065 ctx->ks = keyStorage;
58066 ctx->server = server;
58067 ctx->startingTokenId = startingTokenId;
58068 ctx->requestedKeyCount = requestKeyCount;
58069 cc.clientContext = ctx;
58070
58071 UA_Client *client = UA_Client_newWithConfig(&cc);
58072 if(!client)
58073 return retval;
58074 /* connect to sks server */
58075 retval = UA_Client_connectAsync(client, keyStorage->sksConfig.endpointUrl);
58076 if(retval != UA_STATUSCODE_GOOD) {
58077 UA_LOG_ERROR(client->config.logging, UA_LOGCATEGORY_CLIENT,
58078 "Failed to connect SKS server with error: %s ",
58079 UA_StatusCode_name(retval));
58080 /* Make sure the client channel state is closed and not fresh, otherwise, eventloop will
58081 keep waiting for the client status to go from Fresh to closed in UA_Client_delete*/
58082 client->channel.state = UA_SECURECHANNELSTATE_CLOSED;
58083 /* this client instance will be cleared in the next event loop iteration */
58084 addDelayedSksClientCleanupCb(client, ctx);
58085 return retval;
58086 }
58087
58088 /* add user specified callback, if the client is properly configured. */
58089 client->config.stateCallback = onConnect;
58090
58091 return retval;
58092}
58093
58094UA_StatusCode
58095UA_Server_setSksClient(UA_Server *server, UA_String securityGroupId,
58096 UA_ClientConfig *clientConfig, const char *endpointUrl,
58097 UA_Server_sksPullRequestCallback callback, void *context) {
58098 if(!server || !clientConfig || !endpointUrl)
58099 return UA_STATUSCODE_BADINVALIDARGUMENT;
58100
58101 UA_StatusCode retval = UA_STATUSCODE_BADNOTFOUND;
58102 lockServer(server);
58103 UA_PubSubKeyStorage *ks = UA_PubSubKeyStorage_findKeyStorage(server, securityGroupId);
58104 if(!ks) {
58105 unlockServer(server);
58106 return retval;
58107 }
58108
58109 UA_ClientConfig_copy(clientConfig, &ks->sksConfig.clientConfig);
58110 /*Clear the content of original config, so that no body can access the original config */
58111 clientConfig->authSecurityPolicies = NULL;
58112 clientConfig->certificateVerification.context = NULL;
58113 clientConfig->eventLoop = NULL;
58114 clientConfig->logging = NULL;
58115 clientConfig->securityPolicies = NULL;
58116 UA_ClientConfig_clear(clientConfig);
58117
58118 ks->sksConfig.endpointUrl = endpointUrl;
58119 ks->sksConfig.userNotifyCallback = callback;
58120 ks->sksConfig.context = context;
58121 /* if keys are not previously fetched, then first call GetSecurityKeys*/
58122 if(ks->keyListSize == 0) {
58123 retval = getSecurityKeysAndStoreFetchedKeys(server, ks);
58124 }
58125 unlockServer(server);
58126 return retval;
58127}
58128
58129#endif
58130
58131/**** amalgamated original file "/src/pubsub/ua_pubsub_securitygroup.c" ****/
58132
58133/* This Source Code Form is subject to the terms of the Mozilla Public
58134 * License, v. 2.0. If a copy of the MPL was not distributed with this
58135 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
58136 *
58137 * Copyright (c) 2019 ifak e.V. Magdeburg (Holger Zipper)
58138 * Copyright (c) 2022 Linutronix GmbH (Author: Muddasir Shakil)
58139 */
58140
58141
58142
58143#ifdef UA_ENABLE_PUBSUB_SKS /* conditional compilation */
58144
58145
58146#define UA_PUBSUB_KEYMATERIAL_NONCELENGTH 32
58147
58148UA_SecurityGroup *
58149UA_SecurityGroup_findSGbyName(UA_Server *server, UA_String securityGroupName) {
58150 UA_SecurityGroup *tmpSG;
58151 TAILQ_FOREACH(tmpSG, &server->pubSubManager.securityGroups, listEntry) {
58152 if(UA_String_equal(&securityGroupName, &tmpSG->config.securityGroupName))
58153 return tmpSG;
58154 }
58155 return NULL;
58156}
58157
58158UA_StatusCode
58159UA_SecurityGroupConfig_copy(const UA_SecurityGroupConfig *src,
58160 UA_SecurityGroupConfig *dst) {
58161 UA_StatusCode retval = UA_STATUSCODE_GOOD;
58162
58163 memcpy(dst, src, sizeof(UA_SecurityGroupConfig));
58164 if(UA_String_copy(&src->securityGroupName, &dst->securityGroupName) !=
58165 UA_STATUSCODE_GOOD)
58166 return UA_STATUSCODE_BAD;
58167
58168 if(UA_String_copy(&src->securityPolicyUri, &dst->securityPolicyUri) !=
58169 UA_STATUSCODE_GOOD)
58170 return UA_STATUSCODE_BAD;
58171 return retval;
58172}
58173
58174static UA_StatusCode
58175generateKeyData(const UA_PubSubSecurityPolicy *policy, UA_ByteString *key) {
58176 if(!key || !policy)
58177 return UA_STATUSCODE_BADINVALIDARGUMENT;
58178
58179 UA_StatusCode retVal;
58180
58181 /* Can't not found in specification for pubsub key generation, so use the idea of
58182 * securechannel, see specification 1.0.3 6.7.5 Deriving keys for more details
58183 In pubsub we do get have OpenSecureChannel request, so we cannot have Client or Server Nonce*/
58184 UA_Byte secretBytes[UA_PUBSUB_KEYMATERIAL_NONCELENGTH];
58185 UA_ByteString secret;
58186 secret.length = UA_PUBSUB_KEYMATERIAL_NONCELENGTH;
58187 secret.data = secretBytes;
58188
58189 UA_Byte seedBytes[UA_PUBSUB_KEYMATERIAL_NONCELENGTH];
58190 UA_ByteString seed;
58191 seed.data = seedBytes;
58192 seed.length = UA_PUBSUB_KEYMATERIAL_NONCELENGTH;
58193 memset(seed.data, 0, seed.length);
58194 retVal = policy->symmetricModule.generateNonce(policy->policyContext, &secret);
58195 retVal |= policy->symmetricModule.generateNonce(policy->policyContext, &seed);
58196 if(retVal != UA_STATUSCODE_GOOD)
58197 return retVal;
58198
58199 retVal = policy->symmetricModule.generateKey(policy->policyContext, &secret, &seed, key);
58200 return retVal;
58201}
58202
58203static void
58204updateSKSKeyStorage(UA_Server *server, UA_SecurityGroup *securityGroup){
58205
58206 if(!securityGroup) {
58207 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_PUBSUB,
58208 "UpdateSKSKeyStorage callback failed with Error: %s ",
58209 UA_StatusCode_name(UA_STATUSCODE_BADINVALIDARGUMENT));
58210 return;
58211 }
58212
58213 UA_PubSubKeyStorage *keyStorage = securityGroup->keyStorage;
58214
58215 UA_StatusCode retval = UA_STATUSCODE_BAD;
58216 UA_ByteString newKey;
58217 size_t keyLength = keyStorage->policy->symmetricModule.secureChannelNonceLength;
58218
58219 retval = UA_ByteString_allocBuffer(&newKey, keyLength);
58220 if(retval != UA_STATUSCODE_GOOD) {
58221 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_PUBSUB,
58222 "UpdateSKSKeyStorage callback failed to allocate memory for new key with Error: %s ",
58223 UA_StatusCode_name(retval));
58224 return;
58225 }
58226
58227 generateKeyData(keyStorage->policy, &newKey);
58228 UA_UInt32 newKeyID = TAILQ_LAST(&keyStorage->keyList, keyListItems)->keyID;
58229
58230 if(newKeyID >= UA_UINT32_MAX)
58231 newKeyID = 1;
58232 else
58233 ++newKeyID;
58234
58235 if(keyStorage->keyListSize >= keyStorage->maxKeyListSize) {
58236 /* reusing the preallocated memory of the oldest key for the new key material */
58237 UA_PubSubKeyListItem *oldestKey = TAILQ_FIRST(&keyStorage->keyList);
58238 TAILQ_REMOVE(&keyStorage->keyList, oldestKey, keyListEntry);
58239 TAILQ_INSERT_TAIL(&keyStorage->keyList, oldestKey, keyListEntry);
58240 UA_ByteString_clear(&oldestKey->key);
58241 oldestKey->keyID = newKeyID;
58242 UA_ByteString_copy(&newKey, &oldestKey->key);
58243 } else {
58244 UA_PubSubKeyListItem *newItem =
58245 UA_PubSubKeyStorage_push(keyStorage, &newKey, newKeyID);
58246 if(!newItem) {
58247 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_PUBSUB,
58248 "UpdateSKSKeyStorage callback failed to add new key to the "
58249 "sks keystorage for the SecurityGroup %.*s",
58250 (int)securityGroup->securityGroupId.length,
58251 securityGroup->securityGroupId.data);
58252 UA_Byte_delete(newKey.data);
58253 return;
58254 }
58255 keyStorage->keyListSize++;
58256 }
58257
58258 UA_PubSubKeyListItem *nextCurrentItem = TAILQ_NEXT(keyStorage->currentItem, keyListEntry);
58259 if(nextCurrentItem)
58260 keyStorage->currentItem = nextCurrentItem;
58261
58262 securityGroup->baseTime = UA_DateTime_nowMonotonic();
58263
58264 /* We allocated memory for data with allocBuffer so now we free it */
58265 UA_ByteString_clear(&newKey);
58266}
58267
58268static UA_StatusCode
58269initializeKeyStorageWithKeys(UA_Server *server, UA_SecurityGroup *securityGroup) {
58270 UA_LOCK_ASSERT(&server->serviceMutex, 1);
58271
58272 UA_PubSubSecurityPolicy *policy =
58273 findPubSubSecurityPolicy(server, &securityGroup->config.securityPolicyUri);
58274 if(!policy)
58275 return UA_STATUSCODE_BADSECURITYPOLICYREJECTED;
58276
58277 UA_PubSubKeyStorage *ks = (UA_PubSubKeyStorage *)
58278 UA_calloc(1, sizeof(UA_PubSubKeyStorage));
58279 if(!ks)
58280 return UA_STATUSCODE_BADOUTOFMEMORY;
58281
58282 UA_StatusCode retval =
58283 UA_PubSubKeyStorage_init(server, ks, &securityGroup->securityGroupId,
58284 policy, securityGroup->config.maxPastKeyCount,
58285 securityGroup->config.maxFutureKeyCount);
58286 if(retval != UA_STATUSCODE_GOOD) {
58287 UA_free(ks);
58288 return retval;
58289 }
58290
58291 ks->referenceCount++;
58292 securityGroup->keyStorage = ks;
58293
58294 UA_ByteString currentKey;
58295 size_t keyLength = ks->policy->symmetricModule.secureChannelNonceLength;
58296 retval = UA_ByteString_allocBuffer(&currentKey, keyLength);
58297 retval = generateKeyData(ks->policy, &currentKey);
58298
58299 UA_ByteString *futurekeys = (UA_ByteString *)UA_calloc(securityGroup->config.maxFutureKeyCount, sizeof(UA_ByteString));
58300 for(size_t i = 0; i < securityGroup->config.maxFutureKeyCount; i++) {
58301 retval = UA_ByteString_allocBuffer(&futurekeys[i], keyLength);
58302 retval = generateKeyData(ks->policy, &futurekeys[i]);
58303 }
58304
58305 UA_UInt32 startingKeyId = 1;
58306 retval = UA_PubSubKeyStorage_storeSecurityKeys(server, securityGroup->keyStorage,
58307 startingKeyId, &currentKey, futurekeys,
58308 securityGroup->config.maxFutureKeyCount,
58309 securityGroup->config.keyLifeTime);
58310 if(retval != UA_STATUSCODE_GOOD)
58311 goto cleanup;
58312
58313 securityGroup->baseTime = UA_DateTime_nowMonotonic();
58314 retval = addRepeatedCallback(server, (UA_ServerCallback)updateSKSKeyStorage,
58315 securityGroup, securityGroup->config.keyLifeTime,
58316 &securityGroup->callbackId);
58317
58318cleanup:
58319 UA_Array_delete(futurekeys, securityGroup->config.maxFutureKeyCount,
58320 &UA_TYPES[UA_TYPES_BYTESTRING]);
58321 UA_ByteString_clear(&currentKey);
58322 if(retval != UA_STATUSCODE_GOOD)
58323 UA_PubSubKeyStorage_delete(server, ks);
58324 return retval;
58325}
58326
58327static UA_StatusCode
58328addSecurityGroup(UA_Server *server, UA_NodeId securityGroupFolderNodeId,
58329 const UA_SecurityGroupConfig *securityGroupConfig,
58330 UA_NodeId *securityGroupNodeId) {
58331 if(!securityGroupConfig)
58332 return UA_STATUSCODE_BADINVALIDARGUMENT;
58333
58334 /*check minimal config parameters*/
58335 if(!securityGroupConfig->keyLifeTime ||
58336 UA_String_isEmpty(&securityGroupConfig->securityGroupName) ||
58337 UA_String_isEmpty(&securityGroupConfig->securityPolicyUri))
58338 return UA_STATUSCODE_BADINVALIDARGUMENT;
58339
58340 if(UA_SecurityGroup_findSGbyName(server, securityGroupConfig->securityGroupName))
58341 return UA_STATUSCODE_BADNODEIDEXISTS;
58342
58343 UA_PubSubSecurityPolicy *policy =
58344 findPubSubSecurityPolicy(server, &securityGroupConfig->securityPolicyUri);
58345 if(!policy)
58346 return UA_STATUSCODE_BADSECURITYPOLICYREJECTED;
58347
58348 if(securityGroupConfig->securityGroupName.length > 512)
58349 return UA_STATUSCODE_BADOUTOFMEMORY;
58350
58351 UA_StatusCode retval = UA_STATUSCODE_BAD;
58352
58353 UA_SecurityGroup *newSecurityGroup =
58354 (UA_SecurityGroup *)UA_calloc(1, sizeof(UA_SecurityGroup));
58355 if(!newSecurityGroup)
58356 return UA_STATUSCODE_BADOUTOFMEMORY;
58357
58358 memset(newSecurityGroup, 0, sizeof(UA_SecurityGroup));
58359 UA_SecurityGroupConfig_copy(securityGroupConfig, &newSecurityGroup->config);
58360
58361#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
58362 retval = UA_NodeId_copy(&securityGroupFolderNodeId,
58363 &newSecurityGroup->securityGroupFolderId);
58364 if(retval != UA_STATUSCODE_GOOD) {
58365 UA_SecurityGroup_delete(newSecurityGroup);
58366 return retval;
58367 }
58368#endif
58369
58370 retval = UA_String_copy(&securityGroupConfig->securityGroupName,
58371 &newSecurityGroup->securityGroupId);
58372 if(retval != UA_STATUSCODE_GOOD) {
58373 UA_SecurityGroup_delete(newSecurityGroup);
58374 return retval;
58375 }
58376
58377 retval = initializeKeyStorageWithKeys(server, newSecurityGroup);
58378 if(retval != UA_STATUSCODE_GOOD) {
58379 UA_SecurityGroup_delete(newSecurityGroup);
58380 return retval;
58381 }
58382
58383#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
58384 retval = addSecurityGroupRepresentation(server, newSecurityGroup);
58385 if(retval != UA_STATUSCODE_GOOD) {
58386 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58387 "Add SecurityGroup failed with error: %s.",
58388 UA_StatusCode_name(retval));
58389 UA_SecurityGroup_delete(newSecurityGroup);
58390 return retval;
58391 }
58392#else
58393 UA_PubSubManager_generateUniqueNodeId(&server->pubSubManager,
58394 &newSecurityGroup->securityGroupNodeId);
58395#endif
58396 if(securityGroupNodeId)
58397 UA_NodeId_copy(&newSecurityGroup->securityGroupNodeId, securityGroupNodeId);
58398
58399 TAILQ_INSERT_TAIL(&server->pubSubManager.securityGroups, newSecurityGroup, listEntry);
58400
58401 server->pubSubManager.securityGroupsSize++;
58402 return retval;
58403}
58404
58405UA_StatusCode
58406UA_Server_addSecurityGroup(UA_Server *server, UA_NodeId securityGroupFolderNodeId,
58407 const UA_SecurityGroupConfig *securityGroupConfig,
58408 UA_NodeId *securityGroupNodeId) {
58409 lockServer(server);
58410 UA_StatusCode retval = addSecurityGroup(server, securityGroupFolderNodeId,
58411 securityGroupConfig, securityGroupNodeId);
58412 unlockServer(server);
58413 return retval;
58414}
58415
58416UA_SecurityGroup *
58417UA_SecurityGroup_findSGbyId(UA_Server *server, UA_NodeId identifier) {
58418 UA_SecurityGroup *tmpSG;
58419 TAILQ_FOREACH(tmpSG, &server->pubSubManager.securityGroups, listEntry) {
58420 if(UA_NodeId_equal(&identifier, &tmpSG->securityGroupNodeId))
58421 return tmpSG;
58422 }
58423 return NULL;
58424}
58425
58426static void
58427UA_SecurityGroupConfig_clear(UA_SecurityGroupConfig *config) {
58428 config->keyLifeTime = 0;
58429 config->maxFutureKeyCount = 0;
58430 UA_String_clear(&config->securityGroupName);
58431 UA_String_clear(&config->securityPolicyUri);
58432}
58433
58434static void
58435UA_SecurityGroup_clear(UA_SecurityGroup *securityGroup) {
58436 UA_SecurityGroupConfig_clear(&securityGroup->config);
58437 UA_String_clear(&securityGroup->securityGroupId);
58438#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
58439 UA_NodeId_clear(&securityGroup->securityGroupFolderId);
58440#endif
58441 UA_NodeId_clear(&securityGroup->securityGroupNodeId);
58442}
58443
58444void
58445UA_SecurityGroup_delete(UA_SecurityGroup *securityGroup) {
58446 UA_SecurityGroup_clear(securityGroup);
58447 UA_free(securityGroup);
58448}
58449
58450void
58451removeSecurityGroup(UA_Server *server, UA_SecurityGroup *securityGroup) {
58452#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
58453 deleteNode(server, securityGroup->securityGroupNodeId, true);
58454#endif
58455
58456 /* Unlink from the server */
58457 TAILQ_REMOVE(&server->pubSubManager.securityGroups, securityGroup, listEntry);
58458 server->pubSubManager.securityGroupsSize--;
58459 if(securityGroup->callbackId > 0)
58460 removeCallback(server, securityGroup->callbackId);
58461
58462 if(securityGroup->keyStorage) {
58463 UA_PubSubKeyStorage_detachKeyStorage(server, securityGroup->keyStorage);
58464 securityGroup->keyStorage = NULL;
58465 }
58466
58467 UA_SecurityGroup_delete(securityGroup);
58468}
58469
58470UA_StatusCode
58471UA_Server_removeSecurityGroup(UA_Server *server, const UA_NodeId securityGroup) {
58472 lockServer(server);
58473 UA_SecurityGroup *sg = UA_SecurityGroup_findSGbyId(server, securityGroup);
58474 UA_StatusCode res = UA_STATUSCODE_GOOD;
58475 if(sg) {
58476 removeSecurityGroup(server, sg);
58477 } else {
58478 res = UA_STATUSCODE_BADBOUNDNOTFOUND;
58479 }
58480 unlockServer(server);
58481 return res;
58482}
58483
58484#endif
58485
58486/**** amalgamated original file "/src/pubsub/ua_pubsub_config.c" ****/
58487
58488/* This Source Code Form is subject to the terms of the Mozilla Public
58489 * License, v. 2.0. If a copy of the MPL was not distributed with this
58490 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
58491 *
58492 * Copyright (c) 2020 Yannick Wallerer, Siemens AG
58493 * Copyright (c) 2020 Thomas Fischer, Siemens AG
58494 */
58495
58496
58497#if defined(UA_ENABLE_PUBSUB) && defined(UA_ENABLE_PUBSUB_FILE_CONFIG)
58498
58499static UA_StatusCode
58500createPubSubConnection(UA_Server *server,
58501 const UA_PubSubConnectionDataType *connection,
58502 UA_UInt32 pdsCount, UA_NodeId *pdsIdent);
58503
58504static UA_StatusCode
58505createWriterGroup(UA_Server *server,
58506 const UA_WriterGroupDataType *writerGroupParameters,
58507 UA_NodeId connectionIdent, UA_UInt32 pdsCount,
58508 const UA_NodeId *pdsIdent);
58509
58510static UA_StatusCode
58511createDataSetWriter(UA_Server *server,
58512 const UA_DataSetWriterDataType *dataSetWriterParameters,
58513 UA_NodeId writerGroupIdent, UA_UInt32 pdsCount,
58514 const UA_NodeId *pdsIdent);
58515
58516static UA_StatusCode
58517createReaderGroup(UA_Server *server,
58518 const UA_ReaderGroupDataType *readerGroupParameters,
58519 UA_NodeId connectionIdent);
58520
58521static UA_StatusCode
58522createDataSetReader(UA_Server *server,
58523 const UA_DataSetReaderDataType *dataSetReaderParameters,
58524 UA_NodeId readerGroupIdent);
58525
58526static UA_StatusCode
58527createPublishedDataSet(UA_Server *server,
58528 const UA_PublishedDataSetDataType *publishedDataSetParameters,
58529 UA_NodeId *publishedDataSetIdent);
58530
58531static UA_StatusCode
58532createDataSetFields(UA_Server *server,
58533 const UA_NodeId *publishedDataSetIdent,
58534 const UA_PublishedDataSetDataType *publishedDataSetParameters);
58535
58536static UA_StatusCode
58537generatePubSubConfigurationDataType(UA_Server *server,
58538 UA_PubSubConfigurationDataType *pubSubConfiguration);
58539
58540/* Gets PubSub Configuration from an ExtensionObject */
58541static UA_StatusCode
58542extractPubSubConfigFromExtensionObject(UA_Server *server,
58543 const UA_ExtensionObject *src,
58544 UA_PubSubConfigurationDataType **dst) {
58545 if(src->encoding != UA_EXTENSIONOBJECT_DECODED ||
58546 src->content.decoded.type != &UA_TYPES[UA_TYPES_UABINARYFILEDATATYPE]) {
58547 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58548 "[UA_PubSubManager_extractPubSubConfigFromDecodedObject] "
58549 "Reading extensionObject failed");
58550 return UA_STATUSCODE_BADINVALIDARGUMENT;
58551 }
58552
58553 UA_UABinaryFileDataType *binFile = (UA_UABinaryFileDataType*)src->content.decoded.data;
58554
58555 if(binFile->body.arrayLength != 0 || binFile->body.arrayDimensionsSize != 0) {
58556 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58557 "[UA_PubSubManager_extractPubSubConfigFromDecodedObject] "
58558 "Loading multiple configurations is not supported");
58559 return UA_STATUSCODE_BADNOTIMPLEMENTED;
58560 }
58561
58562 if(binFile->body.type != &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONDATATYPE]) {
58563 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58564 "[UA_PubSubManager_extractPubSubConfigFromDecodedObject] "
58565 "Invalid datatype encoded in the binary file");
58566 return UA_STATUSCODE_BADTYPEMISMATCH;
58567 }
58568
58569 *dst = (UA_PubSubConfigurationDataType*)binFile->body.data;
58570 return UA_STATUSCODE_GOOD;
58571}
58572
58573/* Configures a PubSub Server with given PubSubConfigurationDataType object */
58574static UA_StatusCode
58575updatePubSubConfig(UA_Server *server,
58576 const UA_PubSubConfigurationDataType *configurationParameters) {
58577 UA_LOCK_ASSERT(&server->serviceMutex, 1);
58578
58579 if(configurationParameters == NULL) {
58580 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58581 "[UA_PubSubManager_updatePubSubConfig] Invalid argument");
58582 return UA_STATUSCODE_BADINVALIDARGUMENT;
58583 }
58584
58585 UA_PubSubManager_delete(server, &server->pubSubManager);
58586
58587 /* Configuration of Published DataSets: */
58588 UA_UInt32 pdsCount = (UA_UInt32)configurationParameters->publishedDataSetsSize;
58589 UA_NodeId *publishedDataSetIdent = (UA_NodeId*)UA_calloc(pdsCount, sizeof(UA_NodeId));
58590 if(!publishedDataSetIdent)
58591 return UA_STATUSCODE_BADOUTOFMEMORY;
58592
58593 UA_StatusCode res = UA_STATUSCODE_GOOD;
58594
58595 for(UA_UInt32 i = 0; i < pdsCount; i++) {
58596 res = createPublishedDataSet(server,
58597 &configurationParameters->publishedDataSets[i],
58598 &publishedDataSetIdent[i]);
58599 if(res != UA_STATUSCODE_GOOD) {
58600 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58601 "[UA_PubSubManager_updatePubSubConfig] PDS creation failed");
58602 UA_free(publishedDataSetIdent);
58603 return res;
58604 }
58605 }
58606
58607 /* Configuration of PubSub Connections: */
58608 if(configurationParameters->connectionsSize < 1) {
58609 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_SERVER,
58610 "[UA_PubSubManager_updatePubSubConfig] no connection in "
58611 "UA_PubSubConfigurationDataType");
58612 UA_free(publishedDataSetIdent);
58613 return UA_STATUSCODE_GOOD;
58614 }
58615
58616 for(size_t i = 0; i < configurationParameters->connectionsSize; i++) {
58617 res = createPubSubConnection(server,
58618 &configurationParameters->connections[i],
58619 pdsCount, publishedDataSetIdent);
58620 if(res != UA_STATUSCODE_GOOD)
58621 break;
58622 }
58623
58624 UA_free(publishedDataSetIdent);
58625
58626 return res;
58627}
58628
58629/* Function called by UA_PubSubManager_createPubSubConnection to set the
58630 * PublisherId of a certain connection. */
58631static UA_StatusCode
58632setConnectionPublisherId(UA_Server *server,
58633 const UA_PubSubConnectionDataType *src,
58634 UA_PubSubConnectionConfig *dst) {
58635 if(src->publisherId.type == &UA_TYPES[UA_TYPES_STRING]) {
58636 dst->publisherIdType = UA_PUBLISHERIDTYPE_STRING;
58637 dst->publisherId.string = *(UA_String*)src->publisherId.data;
58638 } else if(src->publisherId.type == &UA_TYPES[UA_TYPES_BYTE]) {
58639 dst->publisherIdType = UA_PUBLISHERIDTYPE_BYTE;
58640 dst->publisherId.byte = *((UA_Byte*)src->publisherId.data);
58641 } else if(src->publisherId.type == &UA_TYPES[UA_TYPES_UINT16]) {
58642 dst->publisherIdType = UA_PUBLISHERIDTYPE_UINT16;
58643 dst->publisherId.uint16 = *((UA_UInt16*)src->publisherId.data);
58644 } else if(src->publisherId.type == &UA_TYPES[UA_TYPES_UINT32]) {
58645 dst->publisherIdType = UA_PUBLISHERIDTYPE_UINT32;
58646 dst->publisherId.uint32 = *(UA_UInt32*)src->publisherId.data;
58647 } else if(src->publisherId.type == &UA_TYPES[UA_TYPES_UINT64]) {
58648 dst->publisherIdType = UA_PUBLISHERIDTYPE_UINT64;
58649 dst->publisherId.uint64 = *(UA_UInt64*)src->publisherId.data;
58650 } else {
58651 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58652 "[UA_PubSubManager_setConnectionPublisherId] PublisherId is not valid.");
58653 return UA_STATUSCODE_BADINTERNALERROR;
58654 }
58655 return UA_STATUSCODE_GOOD;
58656}
58657
58658/* Function called by UA_PubSubManager_createPubSubConnection to create all WriterGroups
58659 * and ReaderGroups that belong to a certain connection. */
58660static UA_StatusCode
58661createComponentsForConnection(UA_Server *server,
58662 const UA_PubSubConnectionDataType *connParams,
58663 UA_NodeId connectionIdent, UA_UInt32 pdsCount,
58664 const UA_NodeId *pdsIdent) {
58665 UA_LOCK_ASSERT(&server->serviceMutex, 1);
58666
58667 /* WriterGroups configuration */
58668 UA_StatusCode res = UA_STATUSCODE_GOOD;
58669 for(size_t i = 0; i < connParams->writerGroupsSize; i++) {
58670 res = createWriterGroup(server, &connParams->writerGroups[i],
58671 connectionIdent, pdsCount, pdsIdent);
58672 if(res != UA_STATUSCODE_GOOD) {
58673 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58674 "[UA_PubSubManager_createComponentsForConnection] "
58675 "Error occured during %d. WriterGroup Creation", (UA_UInt32)i+1);
58676 return res;
58677 }
58678 }
58679
58680 /* ReaderGroups configuration */
58681 for(size_t j = 0; j < connParams->readerGroupsSize; j++) {
58682 res = createReaderGroup(server, &connParams->readerGroups[j], connectionIdent);
58683 if(res != UA_STATUSCODE_GOOD) {
58684 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58685 "[UA_PubSubManager_createComponentsForConnection] "
58686 "Error occured during %d. ReaderGroup Creation", (UA_UInt32)j+1);
58687 return res;
58688 }
58689 }
58690
58691 return res;
58692}
58693
58694/* Creates PubSubConnection configuration from PubSubConnectionDataType object
58695 *
58696 * @param server Server object that shall be configured
58697 * @param connParams PubSub connection configuration
58698 * @param pdsCount Number of published DataSets
58699 * @param pdsIdent Array of NodeIds of the published DataSets */
58700static UA_StatusCode
58701createPubSubConnection(UA_Server *server, const UA_PubSubConnectionDataType *connParams,
58702 UA_UInt32 pdsCount, UA_NodeId *pdsIdent) {
58703 UA_LOCK_ASSERT(&server->serviceMutex, 1);
58704
58705 UA_PubSubConnectionConfig config;
58706 memset(&config, 0, sizeof(UA_PubSubConnectionConfig));
58707
58708 config.name = connParams->name;
58709 config.enabled = connParams->enabled;
58710 config.transportProfileUri = connParams->transportProfileUri;
58711 config.connectionProperties.map = connParams->connectionProperties;
58712 config.connectionProperties.mapSize = connParams->connectionPropertiesSize;
58713
58714 UA_StatusCode res = setConnectionPublisherId(server, connParams, &config);
58715 if(res != UA_STATUSCODE_GOOD) {
58716 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58717 "[UA_PubSubManager_createPubSubConnection] "
58718 "Setting PublisherId failed");
58719 return res;
58720 }
58721
58722 if(connParams->address.encoding == UA_EXTENSIONOBJECT_DECODED) {
58723 UA_Variant_setScalar(&(config.address),
58724 connParams->address.content.decoded.data,
58725 connParams->address.content.decoded.type);
58726 } else {
58727 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58728 "[UA_PubSubManager_createPubSubConnection] "
58729 "Reading connection address failed");
58730 return UA_STATUSCODE_BADINTERNALERROR;
58731 }
58732
58733 if(connParams->transportSettings.encoding == UA_EXTENSIONOBJECT_DECODED) {
58734 UA_Variant_setScalar(&(config.connectionTransportSettings),
58735 connParams->transportSettings.content.decoded.data,
58736 connParams->transportSettings.content.decoded.type);
58737 } else {
58738 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_SERVER,
58739 "[UA_PubSubManager_createPubSubConnection] "
58740 "TransportSettings can not be read");
58741 }
58742
58743 /* Load connection config into server: */
58744 UA_NodeId connectionIdent;
58745 res = UA_PubSubConnection_create(server, &config, &connectionIdent);
58746 if(res == UA_STATUSCODE_GOOD) {
58747 /* Configuration of all Components that belong to this connection: */
58748 res = createComponentsForConnection(server, connParams, connectionIdent,
58749 pdsCount, pdsIdent);
58750 } else {
58751 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58752 "[UA_PubSubManager_createPubSubConnection] "
58753 "Connection creation failed");
58754 }
58755
58756 return res;
58757}
58758
58759/* Function called by UA_PubSubManager_createWriterGroup to configure the messageSettings
58760 * of a writerGroup */
58761static UA_StatusCode
58762setWriterGroupEncodingType(UA_Server *server,
58763 const UA_WriterGroupDataType *writerGroupParameters,
58764 UA_WriterGroupConfig *config) {
58765 if(writerGroupParameters->messageSettings.encoding != UA_EXTENSIONOBJECT_DECODED) {
58766 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58767 "[UA_PubSubManager_setWriterGroupEncodingType] "
58768 "getting message type information failed");
58769 return UA_STATUSCODE_BADINVALIDARGUMENT;
58770 }
58771
58772 if(writerGroupParameters->messageSettings.content.decoded.type ==
58773 &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE]) {
58774 config->encodingMimeType = UA_PUBSUB_ENCODING_UADP;
58775 } else if(writerGroupParameters->messageSettings.content.decoded.type ==
58776 &UA_TYPES[UA_TYPES_JSONWRITERGROUPMESSAGEDATATYPE]) {
58777#ifdef UA_ENABLE_JSON_ENCODING
58778 config->encodingMimeType = UA_PUBSUB_ENCODING_JSON;
58779#else
58780 UA_LOG_ERROR(psm->logging, UA_LOGCATEGORY_PUBSUB,
58781 "[UA_PubSubManager_setWriterGroupEncodingType] "
58782 "encoding type: JSON (not implemented!)");
58783 return UA_STATUSCODE_BADNOTIMPLEMENTED;
58784#endif
58785 } else {
58786 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58787 "[UA_PubSubManager_setWriterGroupEncodingType] "
58788 "invalid message encoding type");
58789 return UA_STATUSCODE_BADINVALIDARGUMENT;
58790 }
58791
58792 return UA_STATUSCODE_GOOD;
58793}
58794
58795/* WriterGroup configuration from WriterGroup object
58796 *
58797 * @param server Server object that shall be configured
58798 * @param writerGroupParameters WriterGroup configuration
58799 * @param connectionIdent NodeId of the PubSub connection, the WriterGroup belongs to
58800 * @param pdsCount Number of published DataSets
58801 * @param pdsIdent Array of NodeIds of the published DataSets */
58802static UA_StatusCode
58803createWriterGroup(UA_Server *server,
58804 const UA_WriterGroupDataType *writerGroupParameters,
58805 UA_NodeId connectionIdent, UA_UInt32 pdsCount,
58806 const UA_NodeId *pdsIdent) {
58807 UA_LOCK_ASSERT(&server->serviceMutex, 1);
58808
58809 UA_WriterGroupConfig config;
58810 memset(&config, 0, sizeof(UA_WriterGroupConfig));
58811 config.name = writerGroupParameters->name;
58812 config.enabled = writerGroupParameters->enabled;
58813 config.writerGroupId = writerGroupParameters->writerGroupId;
58814 config.publishingInterval = writerGroupParameters->publishingInterval;
58815 config.keepAliveTime = writerGroupParameters->keepAliveTime;
58816 config.priority = writerGroupParameters->priority;
58817 config.securityMode = writerGroupParameters->securityMode;
58818 config.transportSettings = writerGroupParameters->transportSettings;
58819 config.messageSettings = writerGroupParameters->messageSettings;
58820 config.groupProperties.mapSize = writerGroupParameters->groupPropertiesSize;
58821 config.groupProperties.map = writerGroupParameters->groupProperties;
58822 config.maxEncapsulatedDataSetMessageCount = 255; /* non std parameter */
58823
58824 UA_StatusCode res = setWriterGroupEncodingType(server, writerGroupParameters, &config);
58825 if(res != UA_STATUSCODE_GOOD) {
58826 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58827 "[UA_PubSubManager_createWriterGroup] "
58828 "Setting message settings failed");
58829 return res;
58830 }
58831
58832 /* Load config into server: */
58833 UA_NodeId writerGroupIdent;
58834 res = UA_WriterGroup_create(server, connectionIdent, &config, &writerGroupIdent);
58835 UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, writerGroupIdent);
58836 if(wg)
58837 UA_WriterGroup_setPubSubState(server, wg, UA_PUBSUBSTATE_OPERATIONAL, UA_STATUSCODE_GOOD);
58838 if(res != UA_STATUSCODE_GOOD) {
58839 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58840 "[UA_PubSubManager_createWriterGroup] "
58841 "Adding WriterGroup to server failed: 0x%x", res);
58842 return res;
58843 }
58844
58845 /* Configuration of all DataSetWriters that belong to this WriterGroup */
58846 for(size_t dsw = 0; dsw < writerGroupParameters->dataSetWritersSize; dsw++) {
58847 res = createDataSetWriter(server, &writerGroupParameters->dataSetWriters[dsw],
58848 writerGroupIdent, pdsCount, pdsIdent);
58849 if(res != UA_STATUSCODE_GOOD) {
58850 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58851 "[UA_PubSubManager_createWriterGroup] "
58852 "DataSetWriter Creation failed.");
58853 break;
58854 }
58855 }
58856 return res;
58857}
58858
58859/* Function called by UA_PubSubManager_createDataSetWriter. It searches for a
58860 * PublishedDataSet that is referenced by the DataSetWriter. If a related PDS is found,
58861 * the DSWriter will be added to the server, otherwise, no DSWriter will be added.
58862 *
58863 * @param server UA_Server object that shall be configured
58864 * @param writerGroupIdent NodeId of writerGroup, the DataSetWriter belongs to
58865 * @param dsWriterConfig WriterGroup configuration
58866 * @param pdsCount Number of published DataSets
58867 * @param pdsIdent Array of NodeIds of the published DataSets */
58868static UA_StatusCode
58869addDataSetWriterWithPdsReference(UA_Server *server, UA_NodeId writerGroupIdent,
58870 const UA_DataSetWriterConfig *dsWriterConfig,
58871 UA_UInt32 pdsCount, const UA_NodeId *pdsIdent) {
58872 UA_LOCK_ASSERT(&server->serviceMutex, 1);
58873
58874 UA_NodeId dataSetWriterIdent;
58875 UA_PublishedDataSetConfig pdsConfig;
58876 UA_Boolean pdsFound = false;
58877
58878 UA_StatusCode res = UA_STATUSCODE_GOOD;
58879 for(size_t pds = 0; pds < pdsCount && res == UA_STATUSCODE_GOOD; pds++) {
58880 res = getPublishedDataSetConfig(server, pdsIdent[pds], &pdsConfig);
58881 /* members of pdsConfig must be deleted manually */
58882 if(res != UA_STATUSCODE_GOOD) {
58883 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58884 "[UA_PubSubManager_addDataSetWriterWithPdsReference] "
58885 "Getting pdsConfig from NodeId failed.");
58886 return res;
58887 }
58888
58889 if(dsWriterConfig->dataSetName.length == pdsConfig.name.length &&
58890 0 == strncmp((const char *)dsWriterConfig->dataSetName.data,
58891 (const char *)pdsConfig.name.data,
58892 dsWriterConfig->dataSetName.length)) {
58893 /* DSWriter will only be created, if a matching PDS is found: */
58894 res = UA_DataSetWriter_create(server, writerGroupIdent, pdsIdent[pds],
58895 dsWriterConfig, &dataSetWriterIdent);
58896 if(res != UA_STATUSCODE_GOOD) {
58897 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58898 "[UA_PubSubManager_addDataSetWriterWithPdsReference] "
58899 "Adding DataSetWriter failed");
58900 } else {
58901 pdsFound = true;
58902 }
58903
58904 UA_PublishedDataSetConfig_clear(&pdsConfig);
58905 if(pdsFound)
58906 break; /* break loop if corresponding publishedDataSet was found */
58907 }
58908 }
58909
58910 if(!pdsFound) {
58911 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58912 "[UA_PubSubManager_addDataSetWriterWithPdsReference] "
58913 "No matching DataSet found; no DataSetWriter created");
58914 }
58915
58916 return res;
58917}
58918
58919/* Creates DataSetWriter configuration from DataSetWriter object
58920 *
58921 * @param server UA_Server object that shall be configured
58922 * @param dataSetWriterParameters DataSetWriter Configuration
58923 * @param writerGroupIdent NodeId of writerGroup, the DataSetWriter belongs to
58924 * @param pdsCount Number of published DataSets
58925 * @param pdsIdent Array of NodeIds of the published DataSets */
58926static UA_StatusCode
58927createDataSetWriter(UA_Server *server,
58928 const UA_DataSetWriterDataType *dataSetWriterParameters,
58929 UA_NodeId writerGroupIdent, UA_UInt32 pdsCount,
58930 const UA_NodeId *pdsIdent) {
58931 UA_LOCK_ASSERT(&server->serviceMutex, 1);
58932
58933 UA_DataSetWriterConfig config;
58934 memset(&config, 0, sizeof(UA_DataSetWriterConfig));
58935 config.name = dataSetWriterParameters->name;
58936 config.dataSetWriterId = dataSetWriterParameters->dataSetWriterId;
58937 config.keyFrameCount = dataSetWriterParameters->keyFrameCount;
58938 config.dataSetFieldContentMask = dataSetWriterParameters->dataSetFieldContentMask;
58939 config.messageSettings = dataSetWriterParameters->messageSettings;
58940 config.dataSetName = dataSetWriterParameters->dataSetName;
58941 config.dataSetWriterProperties.mapSize = dataSetWriterParameters->dataSetWriterPropertiesSize;
58942 config.dataSetWriterProperties.map = dataSetWriterParameters->dataSetWriterProperties;
58943
58944 UA_StatusCode res = addDataSetWriterWithPdsReference(server, writerGroupIdent,
58945 &config, pdsCount, pdsIdent);
58946 if(res != UA_STATUSCODE_GOOD) {
58947 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58948 "[UA_PubSubManager_createDataSetWriter] "
58949 "Referencing related PDS failed");
58950 }
58951
58952 return res;
58953}
58954
58955/* Creates ReaderGroup configuration from ReaderGroup object
58956 *
58957 * @param server UA_Server object that shall be configured
58958 * @param readerGroupParameters ReaderGroup configuration
58959 * @param connectionIdent NodeId of the PubSub connection, the ReaderGroup belongs to */
58960static UA_StatusCode
58961createReaderGroup(UA_Server *server,
58962 const UA_ReaderGroupDataType *readerGroupParameters,
58963 UA_NodeId connectionIdent) {
58964 UA_LOCK_ASSERT(&server->serviceMutex, 1);
58965
58966 UA_ReaderGroupConfig config;
58967 memset(&config, 0, sizeof(UA_ReaderGroupConfig));
58968
58969 config.name = readerGroupParameters->name;
58970 config.securityMode = readerGroupParameters->securityMode;
58971
58972 UA_NodeId readerGroupIdent;
58973 UA_StatusCode res =
58974 UA_ReaderGroup_create(server, connectionIdent, &config, &readerGroupIdent);
58975 if(res != UA_STATUSCODE_GOOD) {
58976 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58977 "[UA_PubSubManager_createReaderGroup] Adding ReaderGroup "
58978 "to server failed: 0x%x", res);
58979 return res;
58980 }
58981
58982 UA_LOG_INFO(server->config.logging, UA_LOGCATEGORY_SERVER,
58983 "[UA_PubSubManager_createReaderGroup] ReaderGroup successfully added.");
58984 for(UA_UInt32 i = 0; i < readerGroupParameters->dataSetReadersSize; i++) {
58985 res = createDataSetReader(server, &readerGroupParameters->dataSetReaders[i],
58986 readerGroupIdent);
58987 if(res != UA_STATUSCODE_GOOD) {
58988 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
58989 "[UA_PubSubManager_createReaderGroup] Creating DataSetReader failed");
58990 break;
58991 }
58992 }
58993
58994 UA_ReaderGroup *rg = UA_ReaderGroup_findRGbyId(server, readerGroupIdent);
58995 if(res == UA_STATUSCODE_GOOD && rg)
58996 UA_ReaderGroup_setPubSubState(server, rg, UA_PUBSUBSTATE_OPERATIONAL,
58997 UA_STATUSCODE_GOOD);
58998
58999 return res;
59000}
59001
59002/* Creates TargetVariables or SubscribedDataSetMirror for a given DataSetReader
59003 *
59004 * @param server UA_Server object that shall be configured
59005 * @param dsReaderIdent NodeId of the DataSetReader the SubscribedDataSet belongs to
59006 * @param dataSetReaderParameters Configuration Parameters of the DataSetReader */
59007static UA_StatusCode
59008addSubscribedDataSet(UA_Server *server, const UA_NodeId dsReaderIdent,
59009 const UA_ExtensionObject *subscribedDataSet) {
59010 UA_LOCK_ASSERT(&server->serviceMutex, 1);
59011
59012 if(subscribedDataSet->content.decoded.type ==
59013 &UA_TYPES[UA_TYPES_TARGETVARIABLESDATATYPE]) {
59014 UA_TargetVariablesDataType *tmpTargetVars = (UA_TargetVariablesDataType*)
59015 subscribedDataSet->content.decoded.data;
59016 UA_FieldTargetVariable *targetVars = (UA_FieldTargetVariable *)
59017 UA_calloc(tmpTargetVars->targetVariablesSize, sizeof(UA_FieldTargetVariable));
59018
59019 for(size_t index = 0; index < tmpTargetVars->targetVariablesSize; index++) {
59020 UA_FieldTargetDataType_copy(&tmpTargetVars->targetVariables[index],
59021 &targetVars[index].targetVariable);
59022 }
59023
59024 UA_StatusCode res = UA_STATUSCODE_BADINTERNALERROR;
59025 UA_DataSetReader *dsr = UA_ReaderGroup_findDSRbyId(server, dsReaderIdent);
59026 if(dsr)
59027 res = DataSetReader_createTargetVariables(server, dsr,
59028 tmpTargetVars->targetVariablesSize,
59029 targetVars);
59030 if(res != UA_STATUSCODE_GOOD) {
59031 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59032 "[UA_PubSubManager_addSubscribedDataSet] "
59033 "create TargetVariables failed");
59034 }
59035
59036 for(size_t index = 0; index < tmpTargetVars->targetVariablesSize; index++) {
59037 UA_FieldTargetDataType_clear(&targetVars[index].targetVariable);
59038 }
59039
59040 UA_free(targetVars);
59041 return res;
59042 }
59043
59044 if(subscribedDataSet->content.decoded.type ==
59045 &UA_TYPES[UA_TYPES_SUBSCRIBEDDATASETMIRRORDATATYPE]) {
59046 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59047 "[UA_PubSubManager_addSubscribedDataSet] "
59048 "DataSetMirror is currently not supported");
59049 return UA_STATUSCODE_BADINVALIDARGUMENT;
59050 }
59051
59052 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59053 "[UA_PubSubManager_addSubscribedDataSet] "
59054 "Invalid Type of SubscribedDataSet");
59055 return UA_STATUSCODE_BADINTERNALERROR;
59056}
59057
59058/* Creates DataSetReader configuration from DataSetReader object
59059 *
59060 * @param server UA_Server object that shall be configured
59061 * @param dataSetReaderParameters DataSetReader configuration
59062 * @param writerGroupIdent NodeId of readerGroupParameters, the DataSetReader belongs to */
59063static UA_StatusCode
59064createDataSetReader(UA_Server *server, const UA_DataSetReaderDataType *dsrParams,
59065 UA_NodeId readerGroupIdent) {
59066 UA_LOCK_ASSERT(&server->serviceMutex, 1);
59067
59068 UA_DataSetReaderConfig config;
59069 memset(&config, 0, sizeof(UA_DataSetReaderConfig));
59070
59071 config.name = dsrParams->name;
59072 config.publisherId = dsrParams->publisherId;
59073 config.writerGroupId = dsrParams->writerGroupId;
59074 config.dataSetWriterId = dsrParams->dataSetWriterId;
59075 config.dataSetMetaData = dsrParams->dataSetMetaData;
59076 config.dataSetFieldContentMask = dsrParams->dataSetFieldContentMask;
59077 config.messageReceiveTimeout = dsrParams->messageReceiveTimeout;
59078 config.messageSettings = dsrParams->messageSettings;
59079
59080 UA_NodeId dsReaderIdent;
59081 UA_StatusCode res = UA_DataSetReader_create(server, readerGroupIdent,
59082 &config, &dsReaderIdent);
59083 if(res == UA_STATUSCODE_GOOD)
59084 res = addSubscribedDataSet(server, dsReaderIdent,
59085 &dsrParams->subscribedDataSet);
59086 if(res != UA_STATUSCODE_GOOD) {
59087 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59088 "[UA_PubSubManager_createDataSetReader] "
59089 "create subscribedDataSet failed");
59090 }
59091
59092 return res;
59093}
59094
59095/* Determines whether PublishedDataSet is of type PublishedItems or PublishedEvents.
59096 * (PublishedEvents are currently not supported!)
59097 *
59098 * @param publishedDataSetParameters PublishedDataSet parameters
59099 * @param config PublishedDataSet configuration object */
59100static UA_StatusCode
59101setPublishedDataSetType(UA_Server *server,
59102 const UA_PublishedDataSetDataType *pdsParams,
59103 UA_PublishedDataSetConfig *config) {
59104 if(pdsParams->dataSetSource.encoding != UA_EXTENSIONOBJECT_DECODED)
59105 return UA_STATUSCODE_BADINTERNALERROR;
59106
59107 const UA_DataType *sourceType = pdsParams->dataSetSource.content.decoded.type;
59108 if(sourceType == &UA_TYPES[UA_TYPES_PUBLISHEDDATAITEMSDATATYPE]) {
59109 config->publishedDataSetType = UA_PUBSUB_DATASET_PUBLISHEDITEMS;
59110 return UA_STATUSCODE_GOOD;
59111 } else if(sourceType == &UA_TYPES[UA_TYPES_PUBLISHEDEVENTSDATATYPE]) {
59112 /* config.publishedDataSetType = UA_PUBSUB_DATASET_PUBLISHEDEVENTS; */
59113 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59114 "[UA_PubSubManager_setPublishedDataSetType] Published events not supported.");
59115 return UA_STATUSCODE_BADNOTIMPLEMENTED;
59116 }
59117
59118 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59119 "[UA_PubSubManager_setPublishedDataSetType] Invalid DataSetSourceDataType.");
59120 return UA_STATUSCODE_BADINTERNALERROR;
59121}
59122
59123/* Creates PublishedDataSetConfig object from PublishedDataSet object
59124 *
59125 * @param server UA_Server object that shall be configured
59126 * @param pdsParams publishedDataSet configuration
59127 * @param pdsIdent NodeId of the publishedDataSet */
59128static UA_StatusCode
59129createPublishedDataSet(UA_Server *server,
59130 const UA_PublishedDataSetDataType *pdsParams,
59131 UA_NodeId *pdsIdent) {
59132 UA_LOCK_ASSERT(&server->serviceMutex, 1);
59133
59134 UA_PublishedDataSetConfig config;
59135 memset(&config, 0, sizeof(UA_PublishedDataSetConfig));
59136
59137 config.name = pdsParams->name;
59138 UA_StatusCode res = setPublishedDataSetType(server, pdsParams, &config);
59139 if(res != UA_STATUSCODE_GOOD)
59140 return res;
59141
59142 res = UA_PublishedDataSet_create(server, &config, pdsIdent).addResult;
59143 if(res != UA_STATUSCODE_GOOD) {
59144 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59145 "[UA_PubSubManager_createPublishedDataSet] "
59146 "Adding PublishedDataSet failed.");
59147 return res;
59148 }
59149
59150 /* DataSetField configuration for this publishedDataSet: */
59151 res = createDataSetFields(server, pdsIdent, pdsParams);
59152 if(res != UA_STATUSCODE_GOOD) {
59153 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59154 "[UA_PubSubManager_createPublishedDataSet] "
59155 "Creating DataSetFieldConfig failed.");
59156 }
59157
59158 return res;
59159}
59160
59161/* Adds DataSetField Variables bound to a certain PublishedDataSet. This method does NOT
59162 * check, whether the PublishedDataSet actually contains Variables instead of Events!
59163 *
59164 * @param server UA_Server object that shall be configured
59165 * @param pdsIdent NodeId of the publishedDataSet, the DataSetField belongs to
59166 * @param publishedDataSetParameters publishedDataSet configuration */
59167static UA_StatusCode
59168addDataSetFieldVariables(UA_Server *server, const UA_NodeId *pdsIdent,
59169 const UA_PublishedDataSetDataType *pdsParams) {
59170 UA_LOCK_ASSERT(&server->serviceMutex, 1);
59171
59172 UA_PublishedDataItemsDataType *pdItems = (UA_PublishedDataItemsDataType *)
59173 pdsParams->dataSetSource.content.decoded.data;
59174 if(pdItems->publishedDataSize != pdsParams->dataSetMetaData.fieldsSize)
59175 return UA_STATUSCODE_BADINTERNALERROR;
59176
59177 for(size_t i = 0; i < pdItems->publishedDataSize; i++) {
59178 UA_DataSetFieldConfig fc;
59179 memset(&fc, 0, sizeof(UA_DataSetFieldConfig));
59180 fc.dataSetFieldType = UA_PUBSUB_DATASETFIELD_VARIABLE;
59181 fc.field.variable.configurationVersion =
59182 pdsParams->dataSetMetaData.configurationVersion;
59183 fc.field.variable.fieldNameAlias = pdsParams->dataSetMetaData.fields[i].name;
59184 fc.field.variable.promotedField = pdsParams->dataSetMetaData.
59185 fields[i].fieldFlags & 0x0001;
59186 fc.field.variable.publishParameters = pdItems->publishedData[i];
59187
59188 UA_NodeId fieldIdent;
59189 UA_StatusCode res = UA_DataSetField_create(server, *pdsIdent, &fc, &fieldIdent).result;
59190 if(res != UA_STATUSCODE_GOOD) {
59191 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59192 "[UA_PubSubManager_addDataSetFieldVariables] "
59193 "Adding DataSetField Variable failed.");
59194 return res;
59195 }
59196 }
59197
59198 return UA_STATUSCODE_GOOD;
59199}
59200
59201/* Checks if PublishedDataSet contains event or variable fields and calls the
59202 * corresponding method to add these fields to the server.
59203 *
59204 * @param server UA_Server object that shall be configured
59205 * @param pdsIdent NodeId of the publishedDataSet, the DataSetFields belongs to
59206 * @param pdsParams publishedDataSet configuration */
59207static UA_StatusCode
59208createDataSetFields(UA_Server *server, const UA_NodeId *pdsIdent,
59209 const UA_PublishedDataSetDataType *pdsParams) {
59210 UA_LOCK_ASSERT(&server->serviceMutex, 1);
59211
59212 if(pdsParams->dataSetSource.encoding != UA_EXTENSIONOBJECT_DECODED)
59213 return UA_STATUSCODE_BADINTERNALERROR;
59214
59215 if(pdsParams->dataSetSource.content.decoded.type ==
59216 &UA_TYPES[UA_TYPES_PUBLISHEDDATAITEMSDATATYPE])
59217 return addDataSetFieldVariables(server, pdsIdent, pdsParams);
59218
59219 /* TODO: Implement Routine for adding Event DataSetFields */
59220 if(pdsParams->dataSetSource.content.decoded.type ==
59221 &UA_TYPES[UA_TYPES_PUBLISHEDEVENTSDATATYPE]) {
59222 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59223 "[UA_PubSubManager_createDataSetFields] "
59224 "Published events not supported.");
59225 return UA_STATUSCODE_BADNOTIMPLEMENTED;
59226 }
59227
59228 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59229 "[UA_PubSubManager_createDataSetFields] "
59230 "Invalid DataSetSourceDataType.");
59231 return UA_STATUSCODE_BADINTERNALERROR;
59232}
59233
59234UA_StatusCode
59235UA_PubSubManager_loadPubSubConfigFromByteString(UA_Server *server,
59236 const UA_ByteString buffer) {
59237 size_t offset = 0;
59238 UA_ExtensionObject decodedFile;
59239 UA_StatusCode res;
59240
59241 if(server == NULL) {
59242 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59243 "[UA_PubSubManager_loadPubSubConfigFromByteString] Invalid argument");
59244 return UA_STATUSCODE_BADINVALIDARGUMENT;
59245 }
59246
59247 UA_LOCK_ASSERT(&server->serviceMutex, 1);
59248
59249 res = UA_ExtensionObject_decodeBinary(&buffer, &offset, &decodedFile);
59250 if(res != UA_STATUSCODE_GOOD) {
59251 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59252 "[UA_decodeBinFile] decoding UA_Binary failed");
59253 goto cleanup;
59254 }
59255
59256 UA_PubSubConfigurationDataType *pubSubConfig = NULL;
59257 res = extractPubSubConfigFromExtensionObject(server, &decodedFile, &pubSubConfig);
59258 if(res != UA_STATUSCODE_GOOD) {
59259 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59260 "[UA_PubSubManager_loadPubSubConfigFromByteString] "
59261 "Extracting PubSub Configuration failed");
59262 goto cleanup;
59263 }
59264
59265 res = updatePubSubConfig(server, pubSubConfig);
59266 if(res != UA_STATUSCODE_GOOD) {
59267 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59268 "[UA_PubSubManager_loadPubSubConfigFromByteString] "
59269 "Loading PubSub configuration into server failed");
59270 goto cleanup;
59271 }
59272
59273 cleanup:
59274 UA_ExtensionObject_clear(&decodedFile);
59275 return res;
59276}
59277
59278/* Encodes a PubSubConfigurationDataType object as ByteString using the UA Binary Data
59279 * Encoding */
59280static UA_StatusCode
59281encodePubSubConfiguration(UA_Server *server,
59282 UA_PubSubConfigurationDataType *configurationParameters,
59283 UA_ByteString *buffer) {
59284 UA_UABinaryFileDataType binFile;
59285 memset(&binFile, 0, sizeof(UA_UABinaryFileDataType));
59286 /*Perhaps, additional initializations of binFile are necessary here.*/
59287
59288 UA_Variant_setScalar(&binFile.body, configurationParameters,
59289 &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONDATATYPE]);
59290
59291 UA_ExtensionObject container;
59292 memset(&container, 0, sizeof(UA_ExtensionObject));
59293 container.encoding = UA_EXTENSIONOBJECT_DECODED;
59294 container.content.decoded.type = &UA_TYPES[UA_TYPES_UABINARYFILEDATATYPE];
59295 container.content.decoded.data = &binFile;
59296
59297 size_t fileSize = UA_ExtensionObject_calcSizeBinary(&container);
59298 buffer->data = (UA_Byte*)UA_calloc(fileSize, sizeof(UA_Byte));
59299 if(buffer->data == NULL) {
59300 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59301 "[UA_PubSubManager_encodePubSubConfiguration] Allocating buffer failed");
59302 return UA_STATUSCODE_BADOUTOFMEMORY;
59303 }
59304
59305 buffer->length = fileSize;
59306
59307 UA_Byte *bufferPos = buffer->data;
59308 UA_StatusCode res =
59309 UA_ExtensionObject_encodeBinary(&container, &bufferPos, bufferPos + fileSize);
59310 if(res != UA_STATUSCODE_GOOD) {
59311 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59312 "[UA_PubSubManager_encodePubSubConfiguration] Encoding failed");
59313 }
59314 return res;
59315}
59316
59317static UA_StatusCode
59318generatePublishedDataSetDataType(UA_Server* server,
59319 const UA_PublishedDataSet *src,
59320 UA_PublishedDataSetDataType *dst) {
59321 if(src->config.publishedDataSetType != UA_PUBSUB_DATASET_PUBLISHEDITEMS)
59322 return UA_STATUSCODE_BADNOTIMPLEMENTED;
59323
59324 memset(dst, 0, sizeof(UA_PublishedDataSetDataType));
59325
59326 UA_PublishedDataItemsDataType *tmp = UA_PublishedDataItemsDataType_new();
59327 UA_String_copy(&src->config.name, &dst->name);
59328 dst->dataSetMetaData.fieldsSize = src->fieldSize;
59329
59330 size_t index = 0;
59331 tmp->publishedDataSize = src->fieldSize;
59332 tmp->publishedData = (UA_PublishedVariableDataType*)
59333 UA_Array_new(tmp->publishedDataSize, &UA_TYPES[UA_TYPES_PUBLISHEDVARIABLEDATATYPE]);
59334 if(tmp->publishedData == NULL) {
59335 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER, "Allocation memory failed");
59336 return UA_STATUSCODE_BADOUTOFMEMORY;
59337 }
59338
59339 dst->dataSetMetaData.fields = (UA_FieldMetaData*)
59340 UA_Array_new(dst->dataSetMetaData.fieldsSize, &UA_TYPES[UA_TYPES_FIELDMETADATA]);
59341 if(dst->dataSetMetaData.fields == NULL) {
59342 UA_free(tmp->publishedData);
59343 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER, "Allocation memory failed");
59344 return UA_STATUSCODE_BADOUTOFMEMORY;
59345 }
59346
59347 UA_DataSetField *dsf, *dsf_tmp = NULL;
59348 TAILQ_FOREACH_SAFE(dsf ,&src->fields, listEntry, dsf_tmp) {
59349 UA_String_copy(&dsf->config.field.variable.fieldNameAlias,
59350 &dst->dataSetMetaData.fields[index].name);
59351 UA_PublishedVariableDataType_copy(&dsf->config.field.variable.publishParameters,
59352 &tmp->publishedData[index]);
59353 UA_ConfigurationVersionDataType_copy(&dsf->config.field.variable.configurationVersion,
59354 &dst->dataSetMetaData.configurationVersion);
59355 dst->dataSetMetaData.fields[index].fieldFlags =
59356 dsf->config.field.variable.promotedField;
59357 index++;
59358 }
59359 UA_ExtensionObject_setValue(&dst->dataSetSource, tmp,
59360 &UA_TYPES[UA_TYPES_PUBLISHEDDATAITEMSDATATYPE]);
59361
59362 return UA_STATUSCODE_GOOD;
59363}
59364
59365static UA_StatusCode
59366generateDataSetWriterDataType(const UA_DataSetWriter *src,
59367 UA_DataSetWriterDataType *dst) {
59368 UA_StatusCode res = UA_STATUSCODE_GOOD;
59369 memset(dst, 0, sizeof(UA_DataSetWriterDataType));
59370 res |= UA_String_copy(&src->config.name, &dst->name);
59371 dst->dataSetWriterId = src->config.dataSetWriterId;
59372 dst->keyFrameCount = src->config.keyFrameCount;
59373 dst->dataSetFieldContentMask = src->config.dataSetFieldContentMask;
59374 res |= UA_ExtensionObject_copy(&src->config.messageSettings, &dst->messageSettings);
59375 res |= UA_String_copy(&src->config.dataSetName, &dst->dataSetName);
59376 if(res != UA_STATUSCODE_GOOD) {
59377 UA_DataSetWriterDataType_clear(dst);
59378 return res;
59379 }
59380
59381 res = UA_Array_copy(src->config.dataSetWriterProperties.map,
59382 src->config.dataSetWriterProperties.mapSize,
59383 (void**)&dst->dataSetWriterProperties,
59384 &UA_TYPES[UA_TYPES_KEYVALUEPAIR]);
59385 if(res == UA_STATUSCODE_GOOD)
59386 dst->dataSetWriterPropertiesSize = src->config.dataSetWriterProperties.mapSize;
59387 else
59388 UA_DataSetWriterDataType_clear(dst);
59389
59390 return res;
59391}
59392
59393static UA_StatusCode
59394generateWriterGroupDataType(const UA_WriterGroup *src,
59395 UA_WriterGroupDataType *dst) {
59396 memset(dst, 0, sizeof(UA_WriterGroupDataType));
59397
59398 UA_String_copy(&src->config.name, &dst->name);
59399 dst->enabled = src->config.enabled;
59400 dst->writerGroupId = src->config.writerGroupId;
59401 dst->publishingInterval = src->config.publishingInterval;
59402 dst->keepAliveTime = src->config.keepAliveTime;
59403 dst->priority = src->config.priority;
59404 dst->securityMode = src->config.securityMode;
59405
59406 UA_ExtensionObject_copy(&src->config.transportSettings, &dst->transportSettings);
59407 UA_ExtensionObject_copy(&src->config.messageSettings, &dst->messageSettings);
59408
59409 UA_StatusCode res =
59410 UA_Array_copy(src->config.groupProperties.map,
59411 src->config.groupProperties.mapSize,
59412 (void**)&dst->groupProperties,
59413 &UA_TYPES[UA_TYPES_KEYVALUEPAIR]);
59414 if(res != UA_STATUSCODE_GOOD) {
59415 UA_WriterGroupDataType_clear(dst);
59416 return res;
59417 }
59418 dst->groupPropertiesSize = src->config.groupProperties.mapSize,
59419
59420 dst->dataSetWriters = (UA_DataSetWriterDataType*)
59421 UA_calloc(src->writersCount, sizeof(UA_DataSetWriterDataType));
59422 if(!dst->dataSetWriters) {
59423 UA_WriterGroupDataType_clear(dst);
59424 return UA_STATUSCODE_BADOUTOFMEMORY;
59425 }
59426
59427 dst->dataSetWritersSize = src->writersCount;
59428
59429 UA_DataSetWriter *dsw;
59430 size_t dsWriterIndex = 0;
59431 LIST_FOREACH(dsw, &src->writers, listEntry) {
59432 res |= generateDataSetWriterDataType(dsw, &dst->dataSetWriters[dsWriterIndex]);
59433 dsWriterIndex++;
59434 }
59435 if(res != UA_STATUSCODE_GOOD)
59436 UA_WriterGroupDataType_clear(dst);
59437 return res;
59438}
59439
59440static UA_StatusCode
59441generateDataSetReaderDataType(const UA_DataSetReader *src,
59442 UA_DataSetReaderDataType *dst) {
59443 UA_StatusCode res = UA_STATUSCODE_GOOD;
59444 memset(dst, 0, sizeof(UA_DataSetReaderDataType));
59445 dst->writerGroupId = src->config.writerGroupId;
59446 dst->dataSetWriterId = src->config.dataSetWriterId;
59447 dst->dataSetFieldContentMask = src->config.dataSetFieldContentMask;
59448 dst->messageReceiveTimeout = src->config.messageReceiveTimeout;
59449 res |= UA_String_copy(&src->config.name, &dst->name);
59450 res |= UA_Variant_copy(&src->config.publisherId, &dst->publisherId);
59451 res |= UA_DataSetMetaDataType_copy(&src->config.dataSetMetaData,
59452 &dst->dataSetMetaData);
59453 res |= UA_ExtensionObject_copy(&src->config.messageSettings, &dst->messageSettings);
59454
59455 UA_TargetVariablesDataType *tmpTarget = UA_TargetVariablesDataType_new();
59456 if(!tmpTarget)
59457 return UA_STATUSCODE_BADOUTOFMEMORY;
59458 UA_ExtensionObject_setValue(&dst->subscribedDataSet, tmpTarget,
59459 &UA_TYPES[UA_TYPES_TARGETVARIABLESDATATYPE]);
59460
59461 const UA_TargetVariables *targets =
59462 &src->config.subscribedDataSet.subscribedDataSetTarget;
59463 tmpTarget->targetVariables = (UA_FieldTargetDataType *)
59464 UA_calloc(targets->targetVariablesSize, sizeof(UA_FieldTargetDataType));
59465 if(!tmpTarget->targetVariables)
59466 return UA_STATUSCODE_BADOUTOFMEMORY;
59467 tmpTarget->targetVariablesSize = targets->targetVariablesSize;
59468
59469 for(size_t i = 0; i < tmpTarget->targetVariablesSize; i++) {
59470 res |= UA_FieldTargetDataType_copy(&targets->targetVariables[i].targetVariable,
59471 &tmpTarget->targetVariables[i]);
59472 }
59473
59474 return res;
59475}
59476
59477static UA_StatusCode
59478generateReaderGroupDataType(const UA_ReaderGroup *src,
59479 UA_ReaderGroupDataType *dst) {
59480 memset(dst, 0, sizeof(UA_ReaderGroupDataType));
59481
59482 UA_String_copy(&src->config.name, &dst->name);
59483 dst->dataSetReaders = (UA_DataSetReaderDataType*)
59484 UA_calloc(src->readersCount, sizeof(UA_DataSetReaderDataType));
59485 if(dst->dataSetReaders == NULL)
59486 return UA_STATUSCODE_BADOUTOFMEMORY;
59487 dst->dataSetReadersSize = src->readersCount;
59488
59489 size_t i = 0;
59490 UA_DataSetReader *dsr, *dsr_tmp = NULL;
59491 LIST_FOREACH_SAFE(dsr, &src->readers, listEntry, dsr_tmp) {
59492 UA_StatusCode res =
59493 generateDataSetReaderDataType(dsr, &dst->dataSetReaders[i]);
59494 if(res != UA_STATUSCODE_GOOD)
59495 return res;
59496 i++;
59497 }
59498
59499 return UA_STATUSCODE_GOOD;
59500}
59501
59502/* Generates a PubSubConnectionDataType object from a PubSubConnection. */
59503static UA_StatusCode
59504generatePubSubConnectionDataType(UA_Server* server,
59505 const UA_PubSubConnection *src,
59506 UA_PubSubConnectionDataType *dst) {
59507 const UA_DataType *publisherIdType;
59508 memset(dst, 0, sizeof(UA_PubSubConnectionDataType));
59509
59510 UA_String_copy(&src->config.name, &dst->name);
59511 UA_String_copy(&src->config.transportProfileUri, &dst->transportProfileUri);
59512 dst->enabled = src->config.enabled;
59513
59514 UA_StatusCode res =
59515 UA_Array_copy(src->config.connectionProperties.map,
59516 src->config.connectionProperties.mapSize,
59517 (void**)&dst->connectionProperties,
59518 &UA_TYPES[UA_TYPES_KEYVALUEPAIR]);
59519 if(res != UA_STATUSCODE_GOOD) {
59520 UA_PubSubConnectionDataType_clear(dst);
59521 return res;
59522 }
59523 dst->connectionPropertiesSize = src->config.connectionProperties.mapSize;
59524
59525 switch (src->config.publisherIdType) {
59526 case UA_PUBLISHERIDTYPE_BYTE:
59527 publisherIdType = &UA_TYPES[UA_TYPES_BYTE];
59528 break;
59529 case UA_PUBLISHERIDTYPE_UINT16:
59530 publisherIdType = &UA_TYPES[UA_TYPES_UINT16];
59531 break;
59532 case UA_PUBLISHERIDTYPE_UINT32:
59533 publisherIdType = &UA_TYPES[UA_TYPES_UINT32];
59534 break;
59535 case UA_PUBLISHERIDTYPE_UINT64:
59536 publisherIdType = &UA_TYPES[UA_TYPES_UINT64];
59537 break;
59538 case UA_PUBLISHERIDTYPE_STRING:
59539 publisherIdType = &UA_TYPES[UA_TYPES_STRING];
59540 break;
59541 default:
59542 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59543 "generatePubSubConnectionDataType(): publisher Id type is not supported");
59544 return UA_STATUSCODE_BADINTERNALERROR;
59545 break;
59546 }
59547 UA_Variant_setScalarCopy(&dst->publisherId,
59548 &src->config.publisherId,
59549 publisherIdType);
59550
59551 /* Possibly, array size and dimensions of src->config->address and
59552 * src->config->connectionTransportSettings should be checked beforehand. */
59553 dst->address.encoding = UA_EXTENSIONOBJECT_DECODED;
59554 dst->address.content.decoded.type = src->config.address.type;
59555 res = UA_Array_copy(src->config.address.data, 1,
59556 &dst->address.content.decoded.data,
59557 src->config.address.type);
59558 if(res != UA_STATUSCODE_GOOD) {
59559 UA_PubSubConnectionDataType_clear(dst);
59560 return res;
59561 }
59562
59563 if(src->config.connectionTransportSettings.data) {
59564 dst->transportSettings.encoding = UA_EXTENSIONOBJECT_DECODED;
59565 dst->transportSettings.content.decoded.type =
59566 src->config.connectionTransportSettings.type;
59567 res = UA_Array_copy(src->config.connectionTransportSettings.data, 1,
59568 &dst->transportSettings.content.decoded.data,
59569 src->config.connectionTransportSettings.type);
59570
59571 if(res != UA_STATUSCODE_GOOD) {
59572 UA_PubSubConnectionDataType_clear(dst);
59573 return res;
59574 }
59575 }
59576
59577 dst->writerGroups = (UA_WriterGroupDataType*)
59578 UA_calloc(src->writerGroupsSize, sizeof(UA_WriterGroupDataType));
59579 if(!dst->writerGroups) {
59580 UA_PubSubConnectionDataType_clear(dst);
59581 return UA_STATUSCODE_BADOUTOFMEMORY;
59582 }
59583
59584 dst->writerGroupsSize = src->writerGroupsSize;
59585 UA_WriterGroup *wg, *wg_tmp = NULL;
59586 size_t wgIndex = 0;
59587 LIST_FOREACH_SAFE(wg, &src->writerGroups, listEntry, wg_tmp) {
59588 res = generateWriterGroupDataType(wg, &dst->writerGroups[wgIndex]);
59589 if(res != UA_STATUSCODE_GOOD) {
59590 UA_PubSubConnectionDataType_clear(dst);
59591 return res;
59592 }
59593 wgIndex++;
59594 }
59595
59596 dst->readerGroups = (UA_ReaderGroupDataType*)
59597 UA_calloc(src->readerGroupsSize, sizeof(UA_ReaderGroupDataType));
59598 if(dst->readerGroups == NULL) {
59599 UA_PubSubConnectionDataType_clear(dst);
59600 return UA_STATUSCODE_BADOUTOFMEMORY;
59601 }
59602
59603 dst->readerGroupsSize = src->readerGroupsSize;
59604 UA_ReaderGroup *rg = NULL;
59605 size_t rgIndex = 0;
59606 LIST_FOREACH(rg, &src->readerGroups, listEntry) {
59607 res = generateReaderGroupDataType(rg, &dst->readerGroups[rgIndex]);
59608 if(res != UA_STATUSCODE_GOOD) {
59609 UA_PubSubConnectionDataType_clear(dst);
59610 return res;
59611 }
59612 rgIndex++;
59613 }
59614
59615 return UA_STATUSCODE_GOOD;
59616}
59617
59618static UA_StatusCode
59619generatePubSubConfigurationDataType(UA_Server* server,
59620 UA_PubSubConfigurationDataType *configDT) {
59621 UA_LOCK_ASSERT(&server->serviceMutex, 1);
59622
59623 UA_StatusCode res = UA_STATUSCODE_GOOD;
59624 const UA_PubSubManager *manager = &server->pubSubManager;
59625 memset(configDT, 0, sizeof(UA_PubSubConfigurationDataType));
59626
59627 configDT->publishedDataSets = (UA_PublishedDataSetDataType*)
59628 UA_calloc(manager->publishedDataSetsSize,
59629 sizeof(UA_PublishedDataSetDataType));
59630 if(configDT->publishedDataSets == NULL)
59631 return UA_STATUSCODE_BADOUTOFMEMORY;
59632 configDT->publishedDataSetsSize = manager->publishedDataSetsSize;
59633
59634 UA_PublishedDataSet *pds;
59635 UA_UInt32 pdsIndex = 0;
59636 TAILQ_FOREACH(pds, &manager->publishedDataSets, listEntry) {
59637 UA_PublishedDataSetDataType *dst = &configDT->publishedDataSets[pdsIndex];
59638 res = generatePublishedDataSetDataType(server, pds, dst);
59639 if(res != UA_STATUSCODE_GOOD) {
59640 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59641 "[UA_PubSubManager_generatePubSubConfigurationDataType] "
59642 "retrieving PublishedDataSet configuration failed");
59643 return res;
59644 }
59645 pdsIndex++;
59646 }
59647
59648 configDT->connections = (UA_PubSubConnectionDataType*)
59649 UA_calloc(manager->connectionsSize, sizeof(UA_PubSubConnectionDataType));
59650 if(configDT->connections == NULL)
59651 return UA_STATUSCODE_BADOUTOFMEMORY;
59652 configDT->connectionsSize = manager->connectionsSize;
59653
59654 UA_UInt32 connectionIndex = 0;
59655 UA_PubSubConnection *connection;
59656 TAILQ_FOREACH(connection, &manager->connections, listEntry) {
59657 UA_PubSubConnectionDataType *cdt = &configDT->connections[connectionIndex];
59658 res = generatePubSubConnectionDataType(server, connection, cdt);
59659 if(res != UA_STATUSCODE_GOOD) {
59660 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59661 "[UA_PubSubManager_generatePubSubConfigurationDataType] "
59662 "retrieving PubSubConnection configuration failed");
59663 return res;
59664 }
59665 connectionIndex++;
59666 }
59667
59668 return UA_STATUSCODE_GOOD;
59669}
59670
59671UA_StatusCode
59672UA_PubSubManager_getEncodedPubSubConfiguration(UA_Server *server,
59673 UA_ByteString *buffer) {
59674 UA_PubSubConfigurationDataType config;
59675 memset(&config, 0, sizeof(UA_PubSubConfigurationDataType));
59676
59677 if(server == NULL) {
59678 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59679 "[UA_PubSubManager_getEncodedPubSubConfiguration] Invalid argument");
59680 return UA_STATUSCODE_BADINVALIDARGUMENT;
59681 }
59682
59683 UA_LOCK_ASSERT(&server->serviceMutex, 1);
59684
59685 UA_StatusCode res = generatePubSubConfigurationDataType(server, &config);
59686 if(res != UA_STATUSCODE_GOOD) {
59687 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59688 "retrieving PubSub configuration from server failed");
59689 goto cleanup;
59690 }
59691
59692 res = encodePubSubConfiguration(server, &config, buffer);
59693 if(res != UA_STATUSCODE_GOOD) {
59694 UA_LOG_ERROR(server->config.logging, UA_LOGCATEGORY_SERVER,
59695 "encoding PubSub configuration failed");
59696 goto cleanup;
59697 }
59698
59699 UA_LOG_INFO(server->config.logging, UA_LOGCATEGORY_SERVER,
59700 "Saving PubSub config was successful");
59701
59702 cleanup:
59703 UA_PubSubConfigurationDataType_clear(&config);
59704 return res;
59705}
59706
59707#endif /* UA_ENABLE_PUBSUB && UA_ENABLE_PUBSUB_FILE_CONFIG */
59708
59709/**** amalgamated original file "/src/client/ua_client.c" ****/
59710
59711/* This Source Code Form is subject to the terms of the Mozilla Public
59712 * License, v. 2.0. If a copy of the MPL was not distributed with this
59713 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
59714 *
59715 * Copyright 2015-2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
59716 * Copyright 2015-2016 (c) Sten Grüner
59717 * Copyright 2015-2016 (c) Chris Iatrou
59718 * Copyright 2015 (c) hfaham
59719 * Copyright 2015-2017 (c) Florian Palm
59720 * Copyright 2017-2018 (c) Thomas Stalder, Blue Time Concept SA
59721 * Copyright 2015 (c) Holger Jeromin
59722 * Copyright 2015 (c) Oleksiy Vasylyev
59723 * Copyright 2016 (c) TorbenD
59724 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
59725 * Copyright 2016 (c) Lykurg
59726 * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB
59727 * Copyright 2018 (c) Kalycito Infotech Private Limited
59728 * Copyright 2020 (c) Christian von Arnim, ISW University of Stuttgart
59729 * Copyright 2021 (c) Fraunhofer IOSB (Author: Jan Hermes)
59730 * Copyright 2022 (c) Linutronix GmbH (Author: Muddasir Shakil)
59731 */
59732
59733
59734
59735static void
59736clientHouseKeeping(UA_Client *client, void *_);
59737
59738/********************/
59739/* Client Lifecycle */
59740/********************/
59741
59742UA_StatusCode
59743UA_ClientConfig_copy(UA_ClientConfig const *src, UA_ClientConfig *dst){
59744 UA_StatusCode retval = UA_STATUSCODE_GOOD;
59745
59746 retval = UA_ApplicationDescription_copy(src: &src->clientDescription, dst: &dst->clientDescription);
59747 if(retval != UA_STATUSCODE_GOOD)
59748 goto cleanup;
59749
59750 retval = UA_ExtensionObject_copy(src: &src->userIdentityToken, dst: &dst->userIdentityToken);
59751 if(retval != UA_STATUSCODE_GOOD)
59752 goto cleanup;
59753
59754 retval = UA_String_copy(src: &src->securityPolicyUri, dst: &dst->securityPolicyUri);
59755 if(retval != UA_STATUSCODE_GOOD)
59756 goto cleanup;
59757
59758 retval = UA_EndpointDescription_copy(src: &src->endpoint, dst: &dst->endpoint);
59759 if(retval != UA_STATUSCODE_GOOD)
59760 goto cleanup;
59761
59762 retval = UA_UserTokenPolicy_copy(src: &src->userTokenPolicy, dst: &dst->userTokenPolicy);
59763 if(retval != UA_STATUSCODE_GOOD)
59764 goto cleanup;
59765
59766 retval = UA_Array_copy(src: src->sessionLocaleIds, size: src->sessionLocaleIdsSize,
59767 dst: (void **)&dst->sessionLocaleIds, type: &UA_TYPES[UA_TYPES_LOCALEID]);
59768 if(retval != UA_STATUSCODE_GOOD)
59769 goto cleanup;
59770
59771 dst->sessionLocaleIdsSize = src->sessionLocaleIdsSize;
59772 dst->connectivityCheckInterval = src->connectivityCheckInterval;
59773 dst->certificateVerification = src->certificateVerification;
59774 dst->clientContext = src->clientContext;
59775 dst->customDataTypes = src->customDataTypes;
59776 dst->eventLoop = src->eventLoop;
59777 dst->externalEventLoop = src->externalEventLoop;
59778 dst->inactivityCallback = src->inactivityCallback;
59779 dst->localConnectionConfig = src->localConnectionConfig;
59780 dst->logging = src->logging;
59781 if(src->certificateVerification.logging == NULL)
59782 dst->certificateVerification.logging = dst->logging;
59783#ifdef UA_ENABLE_SUBSCRIPTIONS
59784 dst->outStandingPublishRequests = src->outStandingPublishRequests;
59785#endif
59786 dst->requestedSessionTimeout = src->requestedSessionTimeout;
59787 dst->secureChannelLifeTime = src->secureChannelLifeTime;
59788 dst->securityMode = src->securityMode;
59789 dst->stateCallback = src->stateCallback;
59790#ifdef UA_ENABLE_SUBSCRIPTIONS
59791 dst->subscriptionInactivityCallback = src->subscriptionInactivityCallback;
59792#endif
59793 dst->timeout = src->timeout;
59794 dst->userTokenPolicy = src->userTokenPolicy;
59795 dst->securityPolicies = src->securityPolicies;
59796 dst->securityPoliciesSize = src->securityPoliciesSize;
59797 dst->authSecurityPolicies = src->authSecurityPolicies;
59798 dst->authSecurityPoliciesSize = src->authSecurityPoliciesSize;
59799
59800cleanup:
59801 if(retval != UA_STATUSCODE_GOOD) {
59802 /* _clear will free the plugins in dst that are a shallow copy from src. */
59803 dst->authSecurityPolicies = NULL;
59804 dst->certificateVerification.context = NULL;
59805 dst->eventLoop = NULL;
59806 dst->logging = NULL;
59807 dst->securityPolicies = NULL;
59808 UA_ClientConfig_clear(config: dst);
59809 }
59810 return retval;
59811}
59812
59813UA_Client *
59814UA_Client_newWithConfig(const UA_ClientConfig *config) {
59815 if(!config)
59816 return NULL;
59817 UA_Client *client = (UA_Client*)UA_malloc(size: sizeof(UA_Client));
59818 if(!client)
59819 return NULL;
59820 memset(s: client, c: 0, n: sizeof(UA_Client));
59821 client->config = *config;
59822
59823 UA_SecureChannel_init(channel: &client->channel);
59824 client->channel.config = client->config.localConnectionConfig;
59825 client->connectStatus = UA_STATUSCODE_GOOD;
59826
59827#if UA_MULTITHREADING >= 100
59828 UA_LOCK_INIT(&client->clientMutex);
59829#endif
59830
59831 return client;
59832}
59833
59834void
59835UA_ClientConfig_clear(UA_ClientConfig *config) {
59836 UA_ApplicationDescription_clear(p: &config->clientDescription);
59837 UA_String_clear(p: &config->endpointUrl);
59838 UA_ExtensionObject_clear(p: &config->userIdentityToken);
59839
59840 /* Delete the SecurityPolicies for Authentication */
59841 if(config->authSecurityPolicies != 0) {
59842 for(size_t i = 0; i < config->authSecurityPoliciesSize; i++)
59843 config->authSecurityPolicies[i].clear(&config->authSecurityPolicies[i]);
59844 UA_free(ptr: config->authSecurityPolicies);
59845 config->authSecurityPolicies = 0;
59846 }
59847 UA_String_clear(p: &config->securityPolicyUri);
59848 UA_String_clear(p: &config->authSecurityPolicyUri);
59849
59850 UA_EndpointDescription_clear(p: &config->endpoint);
59851 UA_UserTokenPolicy_clear(p: &config->userTokenPolicy);
59852
59853 UA_String_clear(p: &config->applicationUri);
59854
59855 if(config->certificateVerification.clear)
59856 config->certificateVerification.clear(&config->certificateVerification);
59857
59858 /* Delete the SecurityPolicies */
59859 if(config->securityPolicies != 0) {
59860 for(size_t i = 0; i < config->securityPoliciesSize; i++)
59861 config->securityPolicies[i].clear(&config->securityPolicies[i]);
59862 UA_free(ptr: config->securityPolicies);
59863 config->securityPolicies = 0;
59864 }
59865
59866 /* Stop and delete the EventLoop */
59867 UA_EventLoop *el = config->eventLoop;
59868 if(el && !config->externalEventLoop) {
59869 if(el->state != UA_EVENTLOOPSTATE_FRESH &&
59870 el->state != UA_EVENTLOOPSTATE_STOPPED) {
59871 el->stop(el);
59872 while(el->state != UA_EVENTLOOPSTATE_STOPPED) {
59873 el->run(el, 100);
59874 }
59875 }
59876 el->free(el);
59877 config->eventLoop = NULL;
59878 }
59879
59880 /* Logging */
59881 if(config->logging != NULL && config->logging->clear != NULL)
59882 config->logging->clear(config->logging);
59883 config->logging = NULL;
59884
59885 UA_String_clear(p: &config->sessionName);
59886 if(config->sessionLocaleIdsSize > 0 && config->sessionLocaleIds) {
59887 UA_Array_delete(p: config->sessionLocaleIds,
59888 size: config->sessionLocaleIdsSize, type: &UA_TYPES[UA_TYPES_LOCALEID]);
59889 }
59890 config->sessionLocaleIds = NULL;
59891 config->sessionLocaleIdsSize = 0;
59892
59893 /* Custom Data Types */
59894 UA_cleanupDataTypeWithCustom(customTypes: config->customDataTypes);
59895
59896#ifdef UA_ENABLE_ENCRYPTION
59897 config->privateKeyPasswordCallback = NULL;
59898#endif
59899}
59900
59901void
59902UA_ClientConfig_delete(UA_ClientConfig *config){
59903 UA_assert(config != NULL);
59904 UA_ClientConfig_clear(config);
59905 UA_free(ptr: config);
59906}
59907
59908static void
59909UA_Client_clear(UA_Client *client) {
59910 /* Prevent new async service calls in UA_Client_AsyncService_removeAll */
59911 UA_SessionState oldState = client->sessionState;
59912 client->sessionState = UA_SESSIONSTATE_CLOSING;
59913
59914 /* Delete the async service calls with BADHSUTDOWN */
59915 __Client_AsyncService_removeAll(client, UA_STATUSCODE_BADSHUTDOWN);
59916
59917 /* Reset to the old state to properly close the session */
59918 client->sessionState = oldState;
59919
59920 UA_Client_disconnect(client);
59921 UA_String_clear(p: &client->discoveryUrl);
59922 UA_EndpointDescription_clear(p: &client->endpoint);
59923
59924 UA_String_clear(p: &client->serverSessionNonce);
59925 UA_String_clear(p: &client->clientSessionNonce);
59926
59927 /* Delete the subscriptions */
59928#ifdef UA_ENABLE_SUBSCRIPTIONS
59929 __Client_Subscriptions_clean(client);
59930#endif
59931
59932 /* Remove the internal regular callback */
59933 UA_Client_removeCallback(client, callbackId: client->houseKeepingCallbackId);
59934 client->houseKeepingCallbackId = 0;
59935
59936 UA_SecureChannel_clear(channel: &client->channel);
59937
59938#if UA_MULTITHREADING >= 100
59939 UA_LOCK_DESTROY(&client->clientMutex);
59940#endif
59941}
59942
59943void
59944UA_Client_delete(UA_Client* client) {
59945 UA_Client_disconnect(client);
59946 UA_Client_clear(client);
59947 UA_ClientConfig_clear(config: &client->config);
59948 UA_free(ptr: client);
59949}
59950
59951void
59952UA_Client_getState(UA_Client *client, UA_SecureChannelState *channelState,
59953 UA_SessionState *sessionState, UA_StatusCode *connectStatus) {
59954 lockClient(client);
59955 if(channelState)
59956 *channelState = client->channel.state;
59957 if(sessionState)
59958 *sessionState = client->sessionState;
59959 if(connectStatus)
59960 *connectStatus = client->connectStatus;
59961 unlockClient(client);
59962}
59963
59964UA_ClientConfig *
59965UA_Client_getConfig(UA_Client *client) {
59966 if(!client)
59967 return NULL;
59968 return &client->config;
59969}
59970
59971#if UA_LOGLEVEL <= 300
59972static const char *channelStateTexts[14] = {
59973 "Fresh", "ReverseListening", "Connecting", "Connected", "ReverseConnected", "RHESent", "HELSent", "HELReceived", "ACKSent",
59974 "AckReceived", "OPNSent", "Open", "Closing", "Closed"};
59975static const char *sessionStateTexts[6] =
59976 {"Closed", "CreateRequested", "Created",
59977 "ActivateRequested", "Activated", "Closing"};
59978#endif
59979
59980void
59981notifyClientState(UA_Client *client) {
59982 UA_LOCK_ASSERT(&client->clientMutex, 1);
59983
59984 if(client->connectStatus == client->oldConnectStatus &&
59985 client->channel.state == client->oldChannelState &&
59986 client->sessionState == client->oldSessionState)
59987 return;
59988
59989#if UA_LOGLEVEL <= 300
59990 UA_Boolean info = (client->connectStatus != UA_STATUSCODE_GOOD);
59991 if(client->oldChannelState != client->channel.state)
59992 info |= (client->channel.state == UA_SECURECHANNELSTATE_OPEN ||
59993 client->channel.state == UA_SECURECHANNELSTATE_CLOSED);
59994 if(client->oldSessionState != client->sessionState)
59995 info |= (client->sessionState == UA_SESSIONSTATE_CREATED ||
59996 client->sessionState == UA_SESSIONSTATE_ACTIVATED ||
59997 client->sessionState == UA_SESSIONSTATE_CLOSED);
59998
59999 const char *channelStateText = channelStateTexts[client->channel.state];
60000 const char *sessionStateText = sessionStateTexts[client->sessionState];
60001 const char *connectStatusText = UA_StatusCode_name(code: client->connectStatus);
60002
60003 if(info)
60004 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60005 msg: "Client Status: ChannelState: %s, SessionState: %s, ConnectStatus: %s",
60006 channelStateText, sessionStateText, connectStatusText);
60007 else
60008 UA_LOG_DEBUG(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60009 msg: "Client Status: ChannelState: %s, SessionState: %s, ConnectStatus: %s",
60010 channelStateText, sessionStateText, connectStatusText);
60011#endif
60012
60013 client->oldConnectStatus = client->connectStatus;
60014 client->oldChannelState = client->channel.state;
60015 client->oldSessionState = client->sessionState;
60016
60017 if(client->config.stateCallback)
60018 client->config.stateCallback(client, client->channel.state,
60019 client->sessionState, client->connectStatus);
60020}
60021
60022/****************/
60023/* Raw Services */
60024/****************/
60025
60026/* For both synchronous and asynchronous service calls */
60027static UA_StatusCode
60028sendRequest(UA_Client *client, const void *request,
60029 const UA_DataType *requestType, UA_UInt32 *requestId) {
60030 UA_LOCK_ASSERT(&client->clientMutex, 1);
60031
60032 /* Renew SecureChannel if necessary */
60033 __Client_renewSecureChannel(client);
60034 if(client->connectStatus != UA_STATUSCODE_GOOD)
60035 return client->connectStatus;
60036
60037 /* Adjusting the request header. The const attribute is violated, but we
60038 * reset to the original state before returning. Use the AuthenticationToken
60039 * only once the session is active (or to activate / close it). */
60040 UA_RequestHeader *rr = (UA_RequestHeader*)(uintptr_t)request;
60041 UA_NodeId oldToken = rr->authenticationToken; /* Put back in place later */
60042 if(client->sessionState == UA_SESSIONSTATE_ACTIVATED ||
60043 requestType == &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST] ||
60044 requestType == &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST])
60045 rr->authenticationToken = client->authenticationToken;
60046 rr->timestamp = UA_DateTime_now();
60047
60048 /* Create a unique handle >100,000 if not manually defined. The handle is
60049 * not necessarily unique when manually defined and used to cancel async
60050 * service requests. */
60051 if(rr->requestHandle == 0) {
60052 if(UA_UNLIKELY(client->requestHandle < 100000))
60053 client->requestHandle = 100000;
60054 rr->requestHandle = ++client->requestHandle;
60055 }
60056
60057 /* Set the timeout hint if not manually defined */
60058 if(rr->timeoutHint == 0)
60059 rr->timeoutHint = client->config.timeout;
60060
60061 /* Generate the request id */
60062 UA_UInt32 rqId = ++client->requestId;
60063
60064#ifdef UA_ENABLE_TYPEDESCRIPTION
60065 UA_LOG_DEBUG_CHANNEL(client->config.logging, &client->channel,
60066 "Sending request with RequestId %u of type %s",
60067 (unsigned)rqId, requestType->typeName);
60068#else
60069 UA_LOG_DEBUG_CHANNEL(client->config.logging, &client->channel,
60070 "Sending request with RequestId %u of type %" PRIu32,
60071 (unsigned)rqId, requestType->binaryEncodingId.identifier.numeric);
60072#endif
60073
60074 /* Send the message */
60075 UA_StatusCode retval =
60076 UA_SecureChannel_sendSymmetricMessage(channel: &client->channel, requestId: rqId,
60077 messageType: UA_MESSAGETYPE_MSG, payload: rr, payloadType: requestType);
60078
60079 rr->authenticationToken = oldToken; /* Set back to the original token */
60080
60081 /* Sending failed. The SecureChannel cannot recover from that. Call
60082 * closeSecureChannel to a) close from our end and b) set the session to
60083 * non-activated. */
60084 if(retval != UA_STATUSCODE_GOOD)
60085 closeSecureChannel(client);
60086
60087 /* Return the request id */
60088 *requestId = rqId;
60089 return retval;
60090}
60091
60092static const UA_NodeId
60093serviceFaultId = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_SERVICEFAULT_ENCODING_DEFAULTBINARY}};
60094
60095/* Look for the async callback in the linked list, execute and delete it */
60096static UA_StatusCode
60097processMSGResponse(UA_Client *client, UA_UInt32 requestId,
60098 const UA_ByteString *msg) {
60099 /* Find the callback */
60100 AsyncServiceCall *ac;
60101 LIST_FOREACH(ac, &client->asyncServiceCalls, pointers) {
60102 if(ac->requestId == requestId)
60103 break;
60104 }
60105
60106 /* Part 6, 6.7.6: After the security validation is complete the receiver
60107 * shall verify the RequestId and the SequenceNumber. If these checks fail a
60108 * Bad_SecurityChecksFailed error is reported. The RequestId only needs to
60109 * be verified by the Client since only the Client knows if it is valid or
60110 * not.*/
60111 if(!ac) {
60112 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60113 msg: "Request with unknown RequestId %u", requestId);
60114 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
60115 }
60116
60117 UA_Response asyncResponse;
60118 UA_Response *response = (ac->syncResponse) ? ac->syncResponse : &asyncResponse;
60119 const UA_DataType *responseType = ac->responseType;
60120
60121 /* Dequeue ac. We might disconnect the client (remove all ac) in the callback. */
60122 LIST_REMOVE(ac, pointers);
60123
60124 /* Decode the response type */
60125 size_t offset = 0;
60126 UA_NodeId responseTypeId;
60127 UA_StatusCode retval = UA_NodeId_decodeBinary(src: msg, offset: &offset, dst: &responseTypeId);
60128 if(retval != UA_STATUSCODE_GOOD)
60129 goto process;
60130
60131 /* Verify the type of the response */
60132 if(!UA_NodeId_equal(p1: &responseTypeId, p2: &ac->responseType->binaryEncodingId)) {
60133 /* Initialize before switching the responseType to ServiceFault.
60134 * Otherwise the decoding will leave fields from the original response
60135 * type uninitialized. */
60136 UA_init(p: response, type: ac->responseType);
60137 if(UA_NodeId_equal(p1: &responseTypeId, p2: &serviceFaultId)) {
60138 /* Decode as a ServiceFault, i.e. only the response header */
60139 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60140 msg: "Received a ServiceFault response");
60141 responseType = &UA_TYPES[UA_TYPES_SERVICEFAULT];
60142 } else {
60143 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60144 msg: "Service response type does not match");
60145 retval = UA_STATUSCODE_BADCOMMUNICATIONERROR;
60146 goto process; /* Do not decode */
60147 }
60148 }
60149
60150 /* Decode the response */
60151#ifdef UA_ENABLE_TYPEDESCRIPTION
60152 UA_LOG_DEBUG(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60153 msg: "Decode a message of type %s", responseType->typeName);
60154#else
60155 UA_LOG_DEBUG(client->config.logging, UA_LOGCATEGORY_CLIENT,
60156 "Decode a message of type %" PRIu32,
60157 responseTypeId.identifier.numeric);
60158#endif
60159 retval = UA_decodeBinaryInternal(src: msg, offset: &offset, dst: response, type: responseType,
60160 customTypes: client->config.customDataTypes);
60161
60162 process:
60163 /* Process the received MSG response */
60164 if(retval != UA_STATUSCODE_GOOD) {
60165 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60166 msg: "Could not decode the response with RequestId %u with status %s",
60167 (unsigned)requestId, UA_StatusCode_name(code: retval));
60168 response->responseHeader.serviceResult = retval;
60169 }
60170
60171 /* The Session closed. The current response is processed with the return code.
60172 * The next request first recreates a session. */
60173 if(responseType != &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE] &&
60174 (response->responseHeader.serviceResult == UA_STATUSCODE_BADSESSIONIDINVALID ||
60175 response->responseHeader.serviceResult == UA_STATUSCODE_BADSESSIONCLOSED)) {
60176 /* Clean up the session information and reset the state */
60177 cleanupSession(client);
60178
60179 if(client->config.noNewSession) {
60180 /* Configuration option to not create a new Session. Disconnect the
60181 * client. */
60182 client->connectStatus = response->responseHeader.serviceResult;
60183 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60184 msg: "Session cannot be activated with StatusCode %s. "
60185 "The client is configured not to create a new Session.",
60186 UA_StatusCode_name(code: client->connectStatus));
60187 closeSecureChannel(client);
60188 } else {
60189 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60190 msg: "Session no longer valid. A new Session is created for the next "
60191 "Service request but we do not re-send the current request.");
60192 }
60193 }
60194
60195 /* Call the async callback. This is the only thread with access to ac. So we
60196 * can just unlock for the callback into userland. */
60197 if(ac->callback)
60198 ac->callback(client, ac->userdata, requestId, response);
60199
60200 /* Clean up */
60201 UA_NodeId_clear(p: &responseTypeId);
60202 if(!ac->syncResponse) {
60203 UA_clear(p: response, type: ac->responseType);
60204 UA_free(ptr: ac);
60205 } else {
60206 /* Return a special status code after processing a synchronous message.
60207 * This makes the client return control immediately. */
60208 ac->syncResponse = NULL; /* Indicate that response was received */
60209 if(retval == UA_STATUSCODE_GOOD)
60210 retval = UA_STATUSCODE_GOODCOMPLETESASYNCHRONOUSLY;
60211 }
60212 return retval;
60213}
60214
60215UA_StatusCode
60216processServiceResponse(UA_Client *client, UA_SecureChannel *channel,
60217 UA_MessageType messageType, UA_UInt32 requestId,
60218 UA_ByteString *message) {
60219 if(!UA_SecureChannel_isConnected(channel)) {
60220 if(messageType == UA_MESSAGETYPE_MSG) {
60221 UA_LOG_DEBUG_CHANNEL(client->config.logging, channel, "Discard MSG message "
60222 "with RequestId %u as the SecureChannel is not connected",
60223 requestId);
60224 } else {
60225 UA_LOG_DEBUG_CHANNEL(client->config.logging, channel, "Discard message "
60226 "as the SecureChannel is not connected");
60227 }
60228 return UA_STATUSCODE_BADCONNECTIONCLOSED;
60229 }
60230
60231 switch(messageType) {
60232 case UA_MESSAGETYPE_RHE:
60233 UA_LOG_DEBUG_CHANNEL(client->config.logging, channel, "Process RHE message");
60234 processRHEMessage(client, chunk: message);
60235 return UA_STATUSCODE_GOOD;
60236 case UA_MESSAGETYPE_ACK:
60237 UA_LOG_DEBUG_CHANNEL(client->config.logging, channel, "Process ACK message");
60238 processACKResponse(client, chunk: message);
60239 return UA_STATUSCODE_GOOD;
60240 case UA_MESSAGETYPE_OPN:
60241 UA_LOG_DEBUG_CHANNEL(client->config.logging, channel, "Process OPN message");
60242 processOPNResponse(client, message);
60243 return UA_STATUSCODE_GOOD;
60244 case UA_MESSAGETYPE_ERR:
60245 UA_LOG_DEBUG_CHANNEL(client->config.logging, channel, "Process ERR message");
60246 processERRResponse(client, chunk: message);
60247 return UA_STATUSCODE_GOOD;
60248 case UA_MESSAGETYPE_MSG:
60249 UA_LOG_DEBUG_CHANNEL(client->config.logging, channel, "Process MSG message "
60250 "with RequestId %u", requestId);
60251 return processMSGResponse(client, requestId, msg: message);
60252 default:
60253 UA_LOG_TRACE_CHANNEL(client->config.logging, channel,
60254 "Invalid message type");
60255 channel->state = UA_SECURECHANNELSTATE_CLOSING;
60256 return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
60257 }
60258}
60259
60260void
60261__Client_Service(UA_Client *client, const void *request,
60262 const UA_DataType *requestType, void *response,
60263 const UA_DataType *responseType) {
60264 UA_ResponseHeader *respHeader = (UA_ResponseHeader*)response;
60265
60266 /* Initialize. Response is valied in case of aborting. */
60267 UA_init(p: response, type: responseType);
60268
60269 /* Verify that the EventLoop is running */
60270 UA_EventLoop *el = client->config.eventLoop;
60271 if(!el || el->state != UA_EVENTLOOPSTATE_STARTED) {
60272 respHeader->serviceResult = UA_STATUSCODE_BADINTERNALERROR;
60273 return;
60274 }
60275
60276 /* Check that the SecureChannel is open and also a Session active (if we
60277 * want a Session). Otherwise reopen. */
60278 if(!isFullyConnected(client)) {
60279 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60280 msg: "Re-establish the connction for the synchronous service call");
60281 connectSync(client);
60282 if(client->connectStatus != UA_STATUSCODE_GOOD) {
60283 respHeader->serviceResult = client->connectStatus;
60284 return;
60285 }
60286 }
60287
60288 /* Store the channelId to detect if the channel was changed by a
60289 * reconnection within the EventLoop run method. */
60290 UA_UInt32 channelId = client->channel.securityToken.channelId;
60291
60292 /* Send the request */
60293 UA_UInt32 requestId = 0;
60294 UA_StatusCode retval = sendRequest(client, request, requestType, requestId: &requestId);
60295 if(retval != UA_STATUSCODE_GOOD) {
60296 /* If sending failed, the status is set to closing. The SecureChannel is
60297 * the actually closed in the next iteration of the EventLoop. */
60298 UA_assert(client->channel.state == UA_SECURECHANNELSTATE_CLOSING ||
60299 client->channel.state == UA_SECURECHANNELSTATE_CLOSED);
60300 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60301 msg: "Sending the request failed with status %s",
60302 UA_StatusCode_name(code: retval));
60303 notifyClientState(client);
60304 respHeader->serviceResult = retval;
60305 return;
60306 }
60307
60308 /* Temporarily insert an AsyncServiceCall */
60309 const UA_RequestHeader *rh = (const UA_RequestHeader*)request;
60310 AsyncServiceCall ac;
60311 ac.callback = NULL;
60312 ac.userdata = NULL;
60313 ac.responseType = responseType;
60314 ac.syncResponse = (UA_Response*)response;
60315 ac.requestId = requestId;
60316 ac.start = UA_DateTime_nowMonotonic(); /* Start timeout after sending */
60317 ac.timeout = rh->timeoutHint;
60318 ac.requestHandle = rh->requestHandle;
60319 if(ac.timeout == 0)
60320 ac.timeout = UA_UINT32_MAX; /* 0 -> unlimited */
60321
60322 LIST_INSERT_HEAD(&client->asyncServiceCalls, &ac, pointers);
60323
60324 /* Time until which the request has to be answered */
60325 UA_DateTime maxDate = ac.start + ((UA_DateTime)ac.timeout * UA_DATETIME_MSEC);
60326
60327 /* Run the EventLoop until the request was processed, the request has timed
60328 * out or the client connection fails */
60329 UA_UInt32 timeout_remaining = ac.timeout;
60330 while(true) {
60331 /* Unlock before dropping into the EventLoop. The client lock is
60332 * re-taken in the network callback if an event occurs. */
60333 retval = el->run(el, timeout_remaining);
60334
60335 /* Was the response received? In that case we can directly return. The
60336 * ac was already removed from the internal linked list. */
60337 if(ac.syncResponse == NULL)
60338 return;
60339
60340 /* Check the status. Do not try to resend if the connection breaks.
60341 * Leave this to the application-level user. For example, we do not want
60342 * to call a method twice is the connection broke after sending the
60343 * request. */
60344 if(retval != UA_STATUSCODE_GOOD)
60345 break;
60346
60347 /* The connection was lost */
60348 retval = client->connectStatus;
60349 if(retval != UA_STATUSCODE_GOOD)
60350 break;
60351
60352 /* The channel is no longer the same or was closed */
60353 if(channelId != client->channel.securityToken.channelId) {
60354 retval = UA_STATUSCODE_BADSECURECHANNELCLOSED;
60355 break;
60356 }
60357
60358 /* Update the remaining timeout or break */
60359 UA_DateTime now = UA_DateTime_nowMonotonic();
60360 if(now > maxDate) {
60361 retval = UA_STATUSCODE_BADTIMEOUT;
60362 break;
60363 }
60364 timeout_remaining = (UA_UInt32)((maxDate - now) / UA_DATETIME_MSEC);
60365 }
60366
60367 /* Detach from the internal async service list */
60368 LIST_REMOVE(&ac, pointers);
60369
60370 /* Return the status code */
60371 respHeader->serviceResult = retval;
60372}
60373
60374void
60375__UA_Client_Service(UA_Client *client, const void *request,
60376 const UA_DataType *requestType, void *response,
60377 const UA_DataType *responseType) {
60378 lockClient(client);
60379 __Client_Service(client, request, requestType, response, responseType);
60380 unlockClient(client);
60381}
60382
60383/***********************************/
60384/* Handling of Async Service Calls */
60385/***********************************/
60386
60387static void
60388__Client_AsyncService_cancel(UA_Client *client, AsyncServiceCall *ac,
60389 UA_StatusCode statusCode) {
60390 /* Set the status for the synchronous service call. Don't free the ac. */
60391 if(ac->syncResponse) {
60392 ac->syncResponse->responseHeader.serviceResult = statusCode;
60393 ac->syncResponse = NULL; /* Indicate the async service call was processed */
60394 return;
60395 }
60396
60397 if(ac->callback) {
60398 /* Create an empty response with the statuscode and call the callback */
60399 UA_Response response;
60400 UA_init(p: &response, type: ac->responseType);
60401 response.responseHeader.serviceResult = statusCode;
60402 ac->callback(client, ac->userdata, ac->requestId, &response);
60403
60404 /* Clean up the response. The user callback might move data into it. For
60405 * whatever reasons. */
60406 UA_clear(p: &response, type: ac->responseType);
60407 }
60408
60409 UA_free(ptr: ac);
60410}
60411
60412void
60413__Client_AsyncService_removeAll(UA_Client *client, UA_StatusCode statusCode) {
60414 /* Make this function reentrant. One of the async callbacks could indirectly
60415 * operate on the list. Moving all elements to a local list before iterating
60416 * that. */
60417 UA_AsyncServiceList asyncServiceCalls = client->asyncServiceCalls;
60418 LIST_INIT(&client->asyncServiceCalls);
60419 if(asyncServiceCalls.lh_first)
60420 asyncServiceCalls.lh_first->pointers.le_prev = &asyncServiceCalls.lh_first;
60421
60422 /* Cancel and remove the elements from the local list */
60423 AsyncServiceCall *ac, *ac_tmp;
60424 LIST_FOREACH_SAFE(ac, &asyncServiceCalls, pointers, ac_tmp) {
60425 LIST_REMOVE(ac, pointers);
60426 __Client_AsyncService_cancel(client, ac, statusCode);
60427 }
60428}
60429
60430UA_StatusCode
60431UA_Client_modifyAsyncCallback(UA_Client *client, UA_UInt32 requestId,
60432 void *userdata, UA_ClientAsyncServiceCallback callback) {
60433 lockClient(client);
60434 AsyncServiceCall *ac;
60435 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
60436 LIST_FOREACH(ac, &client->asyncServiceCalls, pointers) {
60437 if(ac->requestId == requestId) {
60438 ac->callback = callback;
60439 ac->userdata = userdata;
60440 res = UA_STATUSCODE_GOOD;
60441 break;
60442 }
60443 }
60444 unlockClient(client);
60445 return res;
60446}
60447
60448UA_StatusCode
60449__Client_AsyncService(UA_Client *client, const void *request,
60450 const UA_DataType *requestType,
60451 UA_ClientAsyncServiceCallback callback,
60452 const UA_DataType *responseType,
60453 void *userdata, UA_UInt32 *requestId) {
60454 UA_LOCK_ASSERT(&client->clientMutex, 1);
60455
60456 /* Is the SecureChannel connected? */
60457 if(client->channel.state != UA_SECURECHANNELSTATE_OPEN) {
60458 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60459 msg: "SecureChannel must be connected to send request");
60460 return UA_STATUSCODE_BADSERVERNOTCONNECTED;
60461 }
60462
60463 /* Prepare the entry for the linked list */
60464 AsyncServiceCall *ac = (AsyncServiceCall*)UA_malloc(size: sizeof(AsyncServiceCall));
60465 if(!ac)
60466 return UA_STATUSCODE_BADOUTOFMEMORY;
60467
60468 /* Call the service and set the requestId */
60469 UA_StatusCode retval = sendRequest(client, request, requestType, requestId: &ac->requestId);
60470 if(retval != UA_STATUSCODE_GOOD) {
60471 /* If sending failed, the status is set to closing. The SecureChannel is
60472 * the actually closed in the next iteration of the EventLoop. */
60473 UA_assert(client->channel.state == UA_SECURECHANNELSTATE_CLOSING ||
60474 client->channel.state == UA_SECURECHANNELSTATE_CLOSED);
60475 UA_free(ptr: ac);
60476 notifyClientState(client);
60477 return retval;
60478 }
60479
60480 /* Set up the AsyncServiceCall for processing the response */
60481 const UA_RequestHeader *rh = (const UA_RequestHeader*)request;
60482 ac->callback = callback;
60483 ac->responseType = responseType;
60484 ac->userdata = userdata;
60485 ac->syncResponse = NULL;
60486 ac->start = UA_DateTime_nowMonotonic();
60487 ac->timeout = rh->timeoutHint;
60488 ac->requestHandle = rh->requestHandle;
60489 if(ac->timeout == 0)
60490 ac->timeout = UA_UINT32_MAX; /* 0 -> unlimited */
60491
60492 LIST_INSERT_HEAD(&client->asyncServiceCalls, ac, pointers);
60493
60494 /* Return the generated request id */
60495 if(requestId)
60496 *requestId = ac->requestId;
60497
60498 /* Notify the userland if a change happened */
60499 notifyClientState(client);
60500
60501 return UA_STATUSCODE_GOOD;
60502}
60503
60504UA_StatusCode
60505__UA_Client_AsyncService(UA_Client *client, const void *request,
60506 const UA_DataType *requestType,
60507 UA_ClientAsyncServiceCallback callback,
60508 const UA_DataType *responseType,
60509 void *userdata, UA_UInt32 *requestId) {
60510 lockClient(client);
60511 UA_StatusCode res =
60512 __Client_AsyncService(client, request, requestType, callback, responseType,
60513 userdata, requestId);
60514 unlockClient(client);
60515 return res;
60516}
60517
60518static UA_StatusCode
60519cancelByRequestHandle(UA_Client *client, UA_UInt32 requestHandle, UA_UInt32 *cancelCount) {
60520 UA_CancelRequest creq;
60521 UA_CancelRequest_init(p: &creq);
60522 creq.requestHandle = requestHandle;
60523 UA_CancelResponse cresp;
60524 UA_CancelResponse_init(p: &cresp);
60525 __Client_Service(client, request: &creq, requestType: &UA_TYPES[UA_TYPES_CANCELREQUEST],
60526 response: &cresp, responseType: &UA_TYPES[UA_TYPES_CANCELRESPONSE]);
60527 if(cancelCount)
60528 *cancelCount = cresp.cancelCount;
60529 UA_StatusCode res = cresp.responseHeader.serviceResult;
60530 UA_CancelResponse_clear(p: &cresp);
60531 return res;
60532}
60533
60534UA_StatusCode
60535UA_Client_cancelByRequestHandle(UA_Client *client, UA_UInt32 requestHandle,
60536 UA_UInt32 *cancelCount) {
60537 lockClient(client);
60538 UA_StatusCode res = cancelByRequestHandle(client, requestHandle, cancelCount);
60539 unlockClient(client);
60540 return res;
60541}
60542
60543UA_StatusCode
60544UA_Client_cancelByRequestId(UA_Client *client, UA_UInt32 requestId,
60545 UA_UInt32 *cancelCount) {
60546 lockClient(client);
60547 UA_StatusCode res = UA_STATUSCODE_BADNOTFOUND;
60548 AsyncServiceCall *ac;
60549 LIST_FOREACH(ac, &client->asyncServiceCalls, pointers) {
60550 if(ac->requestId != requestId)
60551 continue;
60552 res = cancelByRequestHandle(client, requestHandle: ac->requestHandle, cancelCount);
60553 break;
60554 }
60555 unlockClient(client);
60556 return res;
60557}
60558
60559/*******************/
60560/* Timed Callbacks */
60561/*******************/
60562
60563UA_StatusCode
60564UA_Client_addTimedCallback(UA_Client *client, UA_ClientCallback callback,
60565 void *data, UA_DateTime date, UA_UInt64 *callbackId) {
60566 if(!client->config.eventLoop)
60567 return UA_STATUSCODE_BADINTERNALERROR;
60568 lockClient(client);
60569 UA_StatusCode res = client->config.eventLoop->
60570 addTimedCallback(client->config.eventLoop, (UA_Callback)callback,
60571 client, data, date, callbackId);
60572 unlockClient(client);
60573 return res;
60574}
60575
60576UA_StatusCode
60577UA_Client_addRepeatedCallback(UA_Client *client, UA_ClientCallback callback,
60578 void *data, UA_Double interval_ms, UA_UInt64 *callbackId) {
60579 if(!client->config.eventLoop)
60580 return UA_STATUSCODE_BADINTERNALERROR;
60581 lockClient(client);
60582 UA_StatusCode res = client->config.eventLoop->
60583 addCyclicCallback(client->config.eventLoop, (UA_Callback)callback,
60584 client, data, interval_ms, NULL,
60585 UA_TIMER_HANDLE_CYCLEMISS_WITH_CURRENTTIME, callbackId);
60586 unlockClient(client);
60587 return res;
60588}
60589
60590UA_StatusCode
60591UA_Client_changeRepeatedCallbackInterval(UA_Client *client, UA_UInt64 callbackId,
60592 UA_Double interval_ms) {
60593 if(!client->config.eventLoop)
60594 return UA_STATUSCODE_BADINTERNALERROR;
60595 lockClient(client);
60596 UA_StatusCode res = client->config.eventLoop->
60597 modifyCyclicCallback(client->config.eventLoop, callbackId, interval_ms,
60598 NULL, UA_TIMER_HANDLE_CYCLEMISS_WITH_CURRENTTIME);
60599 unlockClient(client);
60600 return res;
60601}
60602
60603void
60604UA_Client_removeCallback(UA_Client *client, UA_UInt64 callbackId) {
60605 if(!client->config.eventLoop)
60606 return;
60607 lockClient(client);
60608 client->config.eventLoop->
60609 removeCyclicCallback(client->config.eventLoop, callbackId);
60610 unlockClient(client);
60611}
60612
60613/**********************/
60614/* Housekeeping Tasks */
60615/**********************/
60616
60617static void
60618asyncServiceTimeoutCheck(UA_Client *client) {
60619 /* Make this function reentrant. One of the async callbacks could indirectly
60620 * operate on the list. Moving all elements to a local list before iterating
60621 * that. */
60622 UA_AsyncServiceList asyncServiceCalls;
60623 AsyncServiceCall *ac, *ac_tmp;
60624 UA_DateTime now = UA_DateTime_nowMonotonic();
60625 LIST_INIT(&asyncServiceCalls);
60626 LIST_FOREACH_SAFE(ac, &client->asyncServiceCalls, pointers, ac_tmp) {
60627 if(!ac->timeout)
60628 continue;
60629 if(ac->start + (UA_DateTime)(ac->timeout * UA_DATETIME_MSEC) <= now) {
60630 LIST_REMOVE(ac, pointers);
60631 LIST_INSERT_HEAD(&asyncServiceCalls, ac, pointers);
60632 }
60633 }
60634
60635 /* Cancel and remove the elements from the local list */
60636 LIST_FOREACH_SAFE(ac, &asyncServiceCalls, pointers, ac_tmp) {
60637 LIST_REMOVE(ac, pointers);
60638 __Client_AsyncService_cancel(client, ac, UA_STATUSCODE_BADTIMEOUT);
60639 }
60640}
60641
60642static void
60643backgroundConnectivityCallback(UA_Client *client, void *userdata,
60644 UA_UInt32 requestId, const UA_ReadResponse *response) {
60645 lockClient(client);
60646 if(response->responseHeader.serviceResult == UA_STATUSCODE_BADTIMEOUT) {
60647 if(client->config.inactivityCallback)
60648 client->config.inactivityCallback(client);
60649 }
60650 client->pendingConnectivityCheck = false;
60651 client->lastConnectivityCheck = UA_DateTime_nowMonotonic();
60652 unlockClient(client);
60653}
60654
60655static void
60656__Client_backgroundConnectivity(UA_Client *client) {
60657 if(!client->config.connectivityCheckInterval)
60658 return;
60659
60660 if(client->pendingConnectivityCheck)
60661 return;
60662
60663 UA_DateTime now = UA_DateTime_nowMonotonic();
60664 UA_DateTime nextDate = client->lastConnectivityCheck +
60665 (UA_DateTime)(client->config.connectivityCheckInterval * UA_DATETIME_MSEC);
60666 if(now <= nextDate)
60667 return;
60668
60669 /* Prepare the request */
60670 UA_ReadValueId rvid;
60671 UA_ReadValueId_init(p: &rvid);
60672 rvid.attributeId = UA_ATTRIBUTEID_VALUE;
60673 rvid.nodeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS_STATE);
60674 UA_ReadRequest request;
60675 UA_ReadRequest_init(p: &request);
60676 request.nodesToRead = &rvid;
60677 request.nodesToReadSize = 1;
60678 UA_StatusCode retval =
60679 __Client_AsyncService(client, request: &request, requestType: &UA_TYPES[UA_TYPES_READREQUEST],
60680 callback: (UA_ClientAsyncServiceCallback)backgroundConnectivityCallback,
60681 responseType: &UA_TYPES[UA_TYPES_READRESPONSE], NULL, NULL);
60682 if(retval == UA_STATUSCODE_GOOD)
60683 client->pendingConnectivityCheck = true;
60684}
60685
60686/* Regular housekeeping activities in the client -- called via a cyclic callback */
60687static void
60688clientHouseKeeping(UA_Client *client, void *_) {
60689 lockClient(client);
60690
60691 UA_LOG_DEBUG(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60692 msg: "Internally check the the client state and "
60693 "required activities");
60694
60695 /* Renew Secure Channel */
60696 __Client_renewSecureChannel(client);
60697
60698 /* Send read requests from time to time to test the connectivity */
60699 __Client_backgroundConnectivity(client);
60700
60701#ifdef UA_ENABLE_SUBSCRIPTIONS
60702 /* Feed the server PublishRequests for the Subscriptions */
60703 __Client_Subscriptions_backgroundPublish(client);
60704
60705 /* Check for inactive Subscriptions */
60706 __Client_Subscriptions_backgroundPublishInactivityCheck(client);
60707#endif
60708
60709 /* Did async services time out? Process callbacks with an error code */
60710 asyncServiceTimeoutCheck(client);
60711
60712 /* Log and notify user if the client state has changed */
60713 notifyClientState(client);
60714
60715 unlockClient(client);
60716}
60717
60718UA_StatusCode
60719__UA_Client_startup(UA_Client *client) {
60720 UA_LOCK_ASSERT(&client->clientMutex, 1);
60721
60722 UA_EventLoop *el = client->config.eventLoop;
60723 UA_CHECK_ERROR(el != NULL,
60724 return UA_STATUSCODE_BADINTERNALERROR,
60725 client->config.logging, UA_LOGCATEGORY_CLIENT,
60726 "No EventLoop configured");
60727
60728 /* Set up the repeated timer callback for checking the internal state. Like
60729 * in the public API UA_Client_addRepeatedCallback, but without locking the
60730 * mutex again */
60731 UA_StatusCode rv = UA_STATUSCODE_GOOD;
60732 if(!client->houseKeepingCallbackId) {
60733 rv = el->addCyclicCallback(el, (UA_Callback)clientHouseKeeping,
60734 client, NULL, 1000.0, NULL,
60735 UA_TIMER_HANDLE_CYCLEMISS_WITH_CURRENTTIME,
60736 &client->houseKeepingCallbackId);
60737 UA_CHECK_STATUS(rv, return rv);
60738 }
60739
60740 /* Start the EventLoop? */
60741 if(el->state == UA_EVENTLOOPSTATE_FRESH) {
60742 rv = el->start(el);
60743 UA_CHECK_STATUS(rv, return rv);
60744 }
60745
60746 return UA_STATUSCODE_GOOD;
60747}
60748
60749UA_StatusCode
60750UA_Client_run_iterate(UA_Client *client, UA_UInt32 timeout) {
60751 /* Make sure the EventLoop has been started */
60752 lockClient(client);
60753 UA_StatusCode rv = __UA_Client_startup(client);
60754 unlockClient(client);
60755 UA_CHECK_STATUS(rv, return rv);
60756
60757 /* All timers and network events are triggered in the EventLoop. Release the
60758 * client lock before. The callbacks from the EventLoop take the lock
60759 * again. */
60760 UA_EventLoop *el = client->config.eventLoop;
60761 rv = el->run(el, timeout);
60762 UA_CHECK_STATUS(rv, return rv);
60763 return client->connectStatus;
60764}
60765
60766const UA_DataType *
60767UA_Client_findDataType(UA_Client *client, const UA_NodeId *typeId) {
60768 return UA_findDataTypeWithCustom(typeId, customTypes: client->config.customDataTypes);
60769}
60770
60771/*************************/
60772/* Connection Attributes */
60773/*************************/
60774
60775#define UA_CONNECTIONATTRIBUTESSIZE 3
60776static const UA_QualifiedName connectionAttributes[UA_CONNECTIONATTRIBUTESSIZE] = {
60777 {0, UA_STRING_STATIC("serverDescription")},
60778 {0, UA_STRING_STATIC("securityPolicyUri")},
60779 {0, UA_STRING_STATIC("securityMode")}
60780};
60781
60782static UA_StatusCode
60783getConnectionttribute(UA_Client *client, const UA_QualifiedName key,
60784 UA_Variant *outValue, UA_Boolean copy) {
60785 if(!outValue)
60786 return UA_STATUSCODE_BADINTERNALERROR;
60787
60788 UA_Variant localAttr;
60789
60790 if(UA_QualifiedName_equal(p1: &key, p2: &connectionAttributes[0])) {
60791 /* ServerDescription */
60792 UA_Variant_setScalar(v: &localAttr, p: &client->endpoint.server,
60793 type: &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]);
60794 } else if(UA_QualifiedName_equal(p1: &key, p2: &connectionAttributes[1])) {
60795 /* SecurityPolicyUri */
60796 const UA_SecurityPolicy *sp = client->channel.securityPolicy;
60797 if(!sp)
60798 return UA_STATUSCODE_BADNOTCONNECTED;
60799 UA_Variant_setScalar(v: &localAttr, p: (void*)(uintptr_t)&sp->policyUri,
60800 type: &UA_TYPES[UA_TYPES_STRING]);
60801 } else if(UA_QualifiedName_equal(p1: &key, p2: &connectionAttributes[2])) {
60802 /* SecurityMode */
60803 UA_Variant_setScalar(v: &localAttr, p: &client->channel.securityMode,
60804 type: &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE]);
60805 } else {
60806 return UA_STATUSCODE_BADINTERNALERROR;
60807 }
60808
60809 if(copy)
60810 return UA_Variant_copy(src: &localAttr, dst: outValue);
60811
60812 localAttr.storageType = UA_VARIANT_DATA_NODELETE;
60813 *outValue = localAttr;
60814 return UA_STATUSCODE_GOOD;
60815}
60816
60817UA_StatusCode
60818UA_Client_getConnectionAttribute(UA_Client *client, const UA_QualifiedName key,
60819 UA_Variant *outValue) {
60820 lockClient(client);
60821 UA_StatusCode res = getConnectionttribute(client, key, outValue, false);
60822 unlockClient(client);
60823 return res;
60824}
60825
60826UA_StatusCode
60827UA_Client_getConnectionAttributeCopy(UA_Client *client, const UA_QualifiedName key,
60828 UA_Variant *outValue) {
60829 lockClient(client);
60830 UA_StatusCode res = getConnectionttribute(client, key, outValue, true);
60831 unlockClient(client);
60832 return res;
60833}
60834
60835UA_StatusCode
60836UA_Client_getConnectionAttribute_scalar(UA_Client *client,
60837 const UA_QualifiedName key,
60838 const UA_DataType *type,
60839 void *outValue) {
60840 lockClient(client);
60841
60842 UA_Variant attr;
60843 UA_StatusCode res = getConnectionttribute(client, key, outValue: &attr, false);
60844 if(res != UA_STATUSCODE_GOOD) {
60845 unlockClient(client);
60846 return res;
60847 }
60848
60849 if(!UA_Variant_hasScalarType(v: &attr, type)) {
60850 unlockClient(client);
60851 return UA_STATUSCODE_BADNOTFOUND;
60852 }
60853
60854 memcpy(dest: outValue, src: attr.data, n: type->memSize);
60855
60856 unlockClient(client);
60857 return UA_STATUSCODE_GOOD;
60858}
60859
60860void lockClient(UA_Client *client) {
60861 if(UA_LIKELY(client->config.eventLoop && client->config.eventLoop->lock))
60862 client->config.eventLoop->lock(client->config.eventLoop);
60863 UA_LOCK(&client->clientMutex);
60864}
60865
60866void unlockClient(UA_Client *client) {
60867 if(UA_LIKELY(client->config.eventLoop && client->config.eventLoop->unlock))
60868 client->config.eventLoop->unlock(client->config.eventLoop);
60869 UA_UNLOCK(&client->clientMutex);
60870}
60871
60872/**** amalgamated original file "/src/client/ua_client_connect.c" ****/
60873
60874/* This Source Code Form is subject to the terms of the Mozilla Public
60875 * License, v. 2.0. If a copy of the MPL was not distributed with this
60876 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
60877 *
60878 * Copyright 2017-2022 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
60879 * Copyright 2017-2019 (c) Fraunhofer IOSB (Author: Mark Giraud)
60880 */
60881
60882
60883
60884/* Some OPC UA servers only return all Endpoints if the EndpointURL used during
60885 * the HEL/ACK handshake exactly matches -- including the path following the
60886 * address and port! Hence for the first connection we only call FindServers and
60887 * reopen a new TCP connection using then EndpointURL found there.
60888 *
60889 * The overall process is this:
60890 * - Connect with the EndpointURL provided by the user (HEL/ACK)
60891 * - Call FindServers
60892 * - If one of the results has an exactly matching EndpointUrl, continue.
60893 * - Otherwise select a matching server, update the endpointURL member of
60894 * UA_Client and reconnect.
60895 * - Call GetEndpoints and select an Endpoint
60896 * - Open a SecureChannel and Session for that Endpoint
60897 */
60898
60899#define UA_MINMESSAGESIZE 8192
60900#define UA_SESSION_LOCALNONCELENGTH 32
60901#define MAX_DATA_SIZE 4096
60902
60903static void initConnect(UA_Client *client);
60904static UA_StatusCode createSessionAsync(UA_Client *client);
60905static UA_UserTokenPolicy *
60906findUserTokenPolicy(UA_Client *client, UA_EndpointDescription *endpoint);
60907
60908/* Get the EndpointUrl to be used right now.
60909 * This is adjusted during the discovery process.
60910 * We fall back if connecting to an EndpointUrl fails. */
60911static UA_String
60912getEndpointUrl(UA_Client *client) {
60913 if(client->endpoint.endpointUrl.length > 0)
60914 return client->endpoint.endpointUrl;
60915 if(client->discoveryUrl.length > 0)
60916 return client->discoveryUrl;
60917 return client->config.endpointUrl;
60918}
60919
60920/* If an EndpointUrl doesn't work (TCP connection fails), fall back to the
60921 * initial EndpointUrl */
60922static UA_StatusCode
60923fallbackEndpointUrl(UA_Client* client) {
60924 /* Cannot fallback, the initial EndpointUrl is already in use */
60925 UA_String currentUrl = getEndpointUrl(client);
60926 if(UA_String_equal(p1: &currentUrl, p2: &client->config.endpointUrl)) {
60927 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60928 msg: "Could not open a TCP connection to the Endpoint at %.*s",
60929 (int)client->config.endpointUrl.length,
60930 client->config.endpointUrl.data);
60931 return UA_STATUSCODE_BADCONNECTIONREJECTED;
60932 }
60933
60934 if(client->endpoint.endpointUrl.length > 0) {
60935 /* Overwrite the EndpointUrl of the Endpoint */
60936 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60937 msg: "Could not open a TCP connection to the Endpoint at %.*s. "
60938 "Overriding the endpoint description with the initial "
60939 "EndpointUrl at %.*s.",
60940 (int)client->endpoint.endpointUrl.length,
60941 client->endpoint.endpointUrl.data,
60942 (int)client->config.endpointUrl.length,
60943 client->config.endpointUrl.data);
60944 UA_String_clear(p: &client->endpoint.endpointUrl);
60945 return UA_String_copy(src: &client->config.endpointUrl,
60946 dst: &client->endpoint.endpointUrl);
60947 } else {
60948 /* Overwrite the DiscoveryUrl returned by FindServers */
60949 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
60950 msg: "The DiscoveryUrl returned by the FindServers service (%.*s) "
60951 "could not be connected. Continuing with the initial EndpointUrl "
60952 "%.*s for the GetEndpoints service.",
60953 (int)client->config.endpointUrl.length,
60954 client->config.endpointUrl.data,
60955 (int)client->config.endpointUrl.length,
60956 client->config.endpointUrl.data);
60957 UA_String_clear(p: &client->discoveryUrl);
60958 return UA_String_copy(src: &client->config.endpointUrl, dst: &client->discoveryUrl);
60959 }
60960}
60961
60962static UA_SecurityPolicy *
60963getSecurityPolicy(UA_Client *client, UA_String policyUri) {
60964 if(policyUri.length == 0)
60965 policyUri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#None");
60966 for(size_t i = 0; i < client->config.securityPoliciesSize; i++) {
60967 if(UA_String_equal(p1: &policyUri, p2: &client->config.securityPolicies[i].policyUri))
60968 return &client->config.securityPolicies[i];
60969 }
60970 return NULL;
60971}
60972
60973static UA_SecurityPolicy *
60974getAuthSecurityPolicy(UA_Client *client, UA_String policyUri) {
60975 for(size_t i = 0; i < client->config.authSecurityPoliciesSize; i++) {
60976 if(UA_String_equal(p1: &policyUri, p2: &client->config.authSecurityPolicies[i].policyUri))
60977 return &client->config.authSecurityPolicies[i];
60978 }
60979 return NULL;
60980}
60981
60982/* The endpoint is unconfigured if the description is all zeroed-out */
60983static UA_Boolean
60984endpointUnconfigured(const UA_EndpointDescription *endpoint) {
60985 UA_EndpointDescription tmp;
60986 UA_EndpointDescription_init(p: &tmp);
60987 return UA_equal(p1: &tmp, p2: endpoint, type: &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
60988}
60989
60990UA_Boolean
60991isFullyConnected(UA_Client *client) {
60992 /* No Session, but require one */
60993 if(client->sessionState != UA_SESSIONSTATE_ACTIVATED && !client->config.noSession)
60994 return false;
60995
60996 /* No SecureChannel */
60997 if(client->channel.state != UA_SECURECHANNELSTATE_OPEN)
60998 return false;
60999
61000 /* GetEndpoints handshake ongoing or not yet done */
61001 if(client->endpointsHandshake || endpointUnconfigured(endpoint: &client->endpoint))
61002 return false;
61003
61004 /* FindServers handshake ongoing or not yet done */
61005 if(client->findServersHandshake || client->discoveryUrl.length == 0)
61006 return false;
61007
61008 return true;
61009}
61010
61011#ifdef UA_ENABLE_ENCRYPTION
61012
61013/* Function to create a signature using remote certificate and nonce.
61014 * This uses the SecurityPolicy of the SecureChannel. */
61015static UA_StatusCode
61016signClientSignature(UA_Client *client, UA_ActivateSessionRequest *request) {
61017 UA_SecureChannel *channel = &client->channel;
61018 const UA_SecurityPolicy *sp = channel->securityPolicy;
61019 UA_SignatureData *sd = &request->clientSignature;
61020 const UA_SecurityPolicySignatureAlgorithm *signAlg =
61021 &sp->asymmetricModule.cryptoModule.signatureAlgorithm;
61022
61023 /* Copy the signature algorithm identifier */
61024 UA_StatusCode retval = UA_String_copy(src: &signAlg->uri, dst: &sd->algorithm);
61025 if(retval != UA_STATUSCODE_GOOD)
61026 return retval;
61027
61028 /* Allocate memory for the signature */
61029 size_t signatureSize = signAlg->getLocalSignatureSize(channel->channelContext);
61030 retval = UA_ByteString_allocBuffer(bs: &sd->signature, length: signatureSize);
61031 if(retval != UA_STATUSCODE_GOOD)
61032 return retval;
61033
61034 /* Create a temporary buffer */
61035 size_t signDataSize =
61036 channel->remoteCertificate.length + client->serverSessionNonce.length;
61037 if(signDataSize > MAX_DATA_SIZE)
61038 return UA_STATUSCODE_BADINTERNALERROR;
61039 UA_Byte buf[MAX_DATA_SIZE];
61040 UA_ByteString signData = {signDataSize, buf};
61041
61042 /* Sign the ClientSignature */
61043 memcpy(dest: buf, src: channel->remoteCertificate.data, n: channel->remoteCertificate.length);
61044 memcpy(dest: buf + channel->remoteCertificate.length, src: client->serverSessionNonce.data,
61045 n: client->serverSessionNonce.length);
61046 return signAlg->sign(channel->channelContext, &signData, &sd->signature);
61047}
61048
61049static UA_StatusCode
61050signUserTokenSignature(UA_Client *client, UA_SecurityPolicy *utsp,
61051 UA_ActivateSessionRequest *request) {
61052 /* Check the size of the content for signing and create a temporary buffer */
61053 UA_StatusCode retval = UA_STATUSCODE_GOOD;
61054 size_t signDataSize =
61055 client->channel.remoteCertificate.length + client->serverSessionNonce.length;
61056 if(signDataSize > MAX_DATA_SIZE)
61057 return UA_STATUSCODE_BADINTERNALERROR;
61058 UA_Byte buf[MAX_DATA_SIZE];
61059 UA_ByteString signData = {signDataSize, buf};
61060
61061 /* Copy the algorithm identifier */
61062 UA_SecurityPolicySignatureAlgorithm *utpSignAlg =
61063 &utsp->asymmetricModule.cryptoModule.signatureAlgorithm;
61064 UA_SignatureData *utsd = &request->userTokenSignature;
61065 retval = UA_String_copy(src: &utpSignAlg->uri, dst: &utsd->algorithm);
61066 if(retval != UA_STATUSCODE_GOOD)
61067 return retval;
61068
61069 /* We need a channel context with the user certificate in order to reuse the
61070 * code for signing. */
61071 void *tmpCtx;
61072 retval = utsp->channelModule.newContext(utsp, &client->channel.remoteCertificate, &tmpCtx);
61073 if(retval != UA_STATUSCODE_GOOD)
61074 return retval;
61075
61076 /* Allocate memory for the signature */
61077 retval = UA_ByteString_allocBuffer(bs: &utsd->signature,
61078 length: utpSignAlg->getLocalSignatureSize(tmpCtx));
61079 if(retval != UA_STATUSCODE_GOOD)
61080 goto cleanup_utp;
61081
61082 /* Create the userTokenSignature */
61083 memcpy(dest: buf, src: client->channel.remoteCertificate.data,
61084 n: client->channel.remoteCertificate.length);
61085 memcpy(dest: buf + client->channel.remoteCertificate.length,
61086 src: client->serverSessionNonce.data, n: client->serverSessionNonce.length);
61087 retval = utpSignAlg->sign(tmpCtx, &signData, &utsd->signature);
61088
61089 /* Clean up */
61090 cleanup_utp:
61091 utsp->channelModule.deleteContext(tmpCtx);
61092 return retval;
61093}
61094
61095/* UserName and IssuedIdentity are transferred encrypted.
61096 * X509 and Anonymous are not. */
61097static UA_StatusCode
61098encryptUserIdentityToken(UA_Client *client, UA_SecurityPolicy *utsp,
61099 UA_ExtensionObject *userIdentityToken) {
61100 UA_IssuedIdentityToken *iit = NULL;
61101 UA_UserNameIdentityToken *unit = NULL;
61102 UA_ByteString *tokenData;
61103 const UA_DataType *tokenType = userIdentityToken->content.decoded.type;
61104 if(tokenType == &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN]) {
61105 iit = (UA_IssuedIdentityToken*)userIdentityToken->content.decoded.data;
61106 tokenData = &iit->tokenData;
61107 } else if(tokenType == &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]) {
61108 unit = (UA_UserNameIdentityToken*)userIdentityToken->content.decoded.data;
61109 tokenData = &unit->password;
61110 } else {
61111 return UA_STATUSCODE_GOOD;
61112 }
61113
61114 /* Create a temp channel context */
61115
61116 void *channelContext;
61117 UA_StatusCode retval = utsp->channelModule.
61118 newContext(utsp, &client->endpoint.serverCertificate, &channelContext);
61119 if(retval != UA_STATUSCODE_GOOD) {
61120 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_NETWORK,
61121 msg: "Could not instantiate the SecurityPolicy for the UserToken");
61122 return UA_STATUSCODE_BADINTERNALERROR;
61123 }
61124
61125 /* Compute the encrypted length (at least one byte padding) */
61126 size_t plainTextBlockSize = utsp->asymmetricModule.cryptoModule.
61127 encryptionAlgorithm.getRemotePlainTextBlockSize(channelContext);
61128 size_t encryptedBlockSize = utsp->asymmetricModule.cryptoModule.
61129 encryptionAlgorithm.getRemoteBlockSize(channelContext);
61130 UA_UInt32 length = (UA_UInt32)(tokenData->length + client->serverSessionNonce.length);
61131 UA_UInt32 totalLength = length + 4; /* Including the length field */
61132 size_t blocks = totalLength / plainTextBlockSize;
61133 if(totalLength % plainTextBlockSize != 0)
61134 blocks++;
61135 size_t encryptedLength = blocks * encryptedBlockSize;
61136
61137 /* Allocate memory for encryption overhead */
61138 UA_ByteString encrypted;
61139 retval = UA_ByteString_allocBuffer(bs: &encrypted, length: encryptedLength);
61140 if(retval != UA_STATUSCODE_GOOD) {
61141 utsp->channelModule.deleteContext(channelContext);
61142 return UA_STATUSCODE_BADOUTOFMEMORY;
61143 }
61144
61145 UA_Byte *pos = encrypted.data;
61146 const UA_Byte *end = &encrypted.data[encrypted.length];
61147 retval = UA_UInt32_encodeBinary(src: &length, bufPos: &pos, bufEnd: end);
61148 memcpy(dest: pos, src: tokenData->data, n: tokenData->length);
61149 memcpy(dest: &pos[tokenData->length], src: client->serverSessionNonce.data,
61150 n: client->serverSessionNonce.length);
61151 UA_assert(retval == UA_STATUSCODE_GOOD);
61152
61153 /* Add padding
61154 *
61155 * 7.36.2.2 Legacy Encrypted Token Secret Format: A Client should not add any
61156 * padding after the secret. If a Client adds padding then all bytes shall
61157 * be zero. A Server shall check for padding added by Clients and ensure
61158 * that all padding bytes are zeros. */
61159 size_t paddedLength = plainTextBlockSize * blocks;
61160 for(size_t i = totalLength; i < paddedLength; i++)
61161 encrypted.data[i] = 0;
61162 encrypted.length = paddedLength;
61163
61164 retval = utsp->asymmetricModule.cryptoModule.encryptionAlgorithm.
61165 encrypt(channelContext, &encrypted);
61166 encrypted.length = encryptedLength;
61167 UA_ByteString_clear(p: tokenData);
61168 *tokenData = encrypted;
61169
61170 /* Delete the temporary channel context */
61171 utsp->channelModule.deleteContext(channelContext);
61172
61173 if(iit) {
61174 retval |= UA_String_copy(src: &utsp->asymmetricModule.cryptoModule.encryptionAlgorithm.uri,
61175 dst: &iit->encryptionAlgorithm);
61176 } else {
61177 retval |= UA_String_copy(src: &utsp->asymmetricModule.cryptoModule.encryptionAlgorithm.uri,
61178 dst: &unit->encryptionAlgorithm);
61179 }
61180 return retval;
61181}
61182
61183/* Function to verify the signature corresponds to ClientNonce
61184 * using the local certificate */
61185static UA_StatusCode
61186checkCreateSessionSignature(UA_Client *client, const UA_SecureChannel *channel,
61187 const UA_CreateSessionResponse *response) {
61188 if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN &&
61189 channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
61190 return UA_STATUSCODE_GOOD;
61191
61192 if(!channel->securityPolicy)
61193 return UA_STATUSCODE_BADINTERNALERROR;
61194
61195 const UA_SecurityPolicy *sp = channel->securityPolicy;
61196 const UA_ByteString *lc = &sp->localCertificate;
61197
61198 size_t dataToVerifySize = lc->length + client->clientSessionNonce.length;
61199 UA_ByteString dataToVerify = UA_BYTESTRING_NULL;
61200 UA_StatusCode retval = UA_ByteString_allocBuffer(bs: &dataToVerify, length: dataToVerifySize);
61201 if(retval != UA_STATUSCODE_GOOD)
61202 return retval;
61203
61204 memcpy(dest: dataToVerify.data, src: lc->data, n: lc->length);
61205 memcpy(dest: dataToVerify.data + lc->length, src: client->clientSessionNonce.data,
61206 n: client->clientSessionNonce.length);
61207
61208 retval = sp->asymmetricModule.cryptoModule.signatureAlgorithm.
61209 verify(channel->channelContext, &dataToVerify,
61210 &response->serverSignature.signature);
61211 UA_ByteString_clear(p: &dataToVerify);
61212 return retval;
61213}
61214
61215#endif
61216
61217/***********************/
61218/* Open the Connection */
61219/***********************/
61220
61221void
61222processERRResponse(UA_Client *client, const UA_ByteString *chunk) {
61223 size_t offset = 0;
61224 UA_TcpErrorMessage errMessage;
61225 client->connectStatus =
61226 UA_decodeBinaryInternal(src: chunk, offset: &offset, dst: &errMessage,
61227 type: &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE], NULL);
61228 if(client->connectStatus != UA_STATUSCODE_GOOD) {
61229 UA_LOG_ERROR_CHANNEL(client->config.logging, &client->channel,
61230 "Received an ERR response that could not be decoded "
61231 "with StatusCode %s",
61232 UA_StatusCode_name(client->connectStatus));
61233 closeSecureChannel(client);
61234 return;
61235 }
61236
61237 UA_LOG_ERROR_CHANNEL(client->config.logging, &client->channel,
61238 "Received an ERR response with StatusCode %s and the following "
61239 "reason: %.*s", UA_StatusCode_name(errMessage.error),
61240 (int)errMessage.reason.length, errMessage.reason.data);
61241 client->connectStatus = errMessage.error;
61242 closeSecureChannel(client);
61243 UA_TcpErrorMessage_clear(p: &errMessage);
61244}
61245
61246void
61247processACKResponse(UA_Client *client, const UA_ByteString *chunk) {
61248 UA_SecureChannel *channel = &client->channel;
61249 if(channel->state != UA_SECURECHANNELSTATE_HEL_SENT) {
61250 UA_LOG_ERROR_CHANNEL(client->config.logging, channel,
61251 "SecureChannel not in the HEL-sent state");
61252 client->connectStatus = UA_STATUSCODE_BADSECURECHANNELCLOSED;
61253 closeSecureChannel(client);
61254 return;
61255 }
61256
61257 /* Decode the message */
61258 size_t offset = 0;
61259 UA_TcpAcknowledgeMessage ackMessage;
61260 client->connectStatus =
61261 UA_decodeBinaryInternal(src: chunk, offset: &offset, dst: &ackMessage,
61262 type: &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE], NULL);
61263 if(client->connectStatus != UA_STATUSCODE_GOOD) {
61264 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_NETWORK,
61265 msg: "Decoding ACK message failed");
61266 closeSecureChannel(client);
61267 return;
61268 }
61269
61270 client->connectStatus =
61271 UA_SecureChannel_processHELACK(channel, remoteConfig: &ackMessage);
61272 if(client->connectStatus != UA_STATUSCODE_GOOD) {
61273 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_NETWORK,
61274 msg: "Processing the ACK message failed with StatusCode %s",
61275 UA_StatusCode_name(code: client->connectStatus));
61276 closeSecureChannel(client);
61277 return;
61278 }
61279
61280 client->channel.state = UA_SECURECHANNELSTATE_ACK_RECEIVED;
61281}
61282
61283static UA_StatusCode
61284sendHELMessage(UA_Client *client) {
61285 UA_ConnectionManager *cm = client->channel.connectionManager;
61286 if(!UA_SecureChannel_isConnected(channel: &client->channel))
61287 return UA_STATUSCODE_BADNOTCONNECTED;
61288
61289 /* Get a buffer */
61290 UA_ByteString message;
61291 UA_StatusCode retval = cm->allocNetworkBuffer(cm, client->channel.connectionId,
61292 &message, UA_MINMESSAGESIZE);
61293 if(retval != UA_STATUSCODE_GOOD)
61294 return retval;
61295
61296 /* Prepare the HEL message and encode at offset 8 */
61297 UA_TcpHelloMessage hello;
61298 hello.protocolVersion = 0;
61299 hello.receiveBufferSize = client->config.localConnectionConfig.recvBufferSize;
61300 hello.sendBufferSize = client->config.localConnectionConfig.sendBufferSize;
61301 hello.maxMessageSize = client->config.localConnectionConfig.localMaxMessageSize;
61302 hello.maxChunkCount = client->config.localConnectionConfig.localMaxChunkCount;
61303 hello.endpointUrl = getEndpointUrl(client);
61304
61305 UA_Byte *bufPos = &message.data[8]; /* skip the header */
61306 const UA_Byte *bufEnd = &message.data[message.length];
61307 client->connectStatus =
61308 UA_encodeBinaryInternal(src: &hello, type: &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE],
61309 bufPos: &bufPos, bufEnd: &bufEnd, NULL, NULL);
61310
61311 /* Encode the message header at offset 0 */
61312 UA_TcpMessageHeader messageHeader;
61313 messageHeader.messageTypeAndChunkType = UA_CHUNKTYPE_FINAL + UA_MESSAGETYPE_HEL;
61314 messageHeader.messageSize = (UA_UInt32) ((uintptr_t)bufPos - (uintptr_t)message.data);
61315 bufPos = message.data;
61316 retval = UA_encodeBinaryInternal(src: &messageHeader,
61317 type: &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER],
61318 bufPos: &bufPos, bufEnd: &bufEnd, NULL, NULL);
61319 if(retval != UA_STATUSCODE_GOOD) {
61320 cm->freeNetworkBuffer(cm, client->channel.connectionId, &message);
61321 return retval;
61322 }
61323
61324 /* Send the HEL message */
61325 message.length = messageHeader.messageSize;
61326 retval = cm->sendWithConnection(cm, client->channel.connectionId,
61327 &UA_KEYVALUEMAP_NULL, &message);
61328 if(retval != UA_STATUSCODE_GOOD) {
61329 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT, msg: "Sending HEL failed");
61330 closeSecureChannel(client);
61331 return retval;
61332 }
61333
61334 UA_LOG_DEBUG(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT, msg: "Sent HEL message");
61335 client->channel.state = UA_SECURECHANNELSTATE_HEL_SENT;
61336 return UA_STATUSCODE_GOOD;
61337}
61338
61339void processRHEMessage(UA_Client *client, const UA_ByteString *chunk) {
61340 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT, msg: "RHE received");
61341
61342 size_t offset = 0; /* Go to the beginning of the TcpHelloMessage */
61343 UA_TcpReverseHelloMessage rheMessage;
61344 UA_StatusCode retval =
61345 UA_decodeBinaryInternal(src: chunk, offset: &offset, dst: &rheMessage,
61346 type: &UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE], NULL);
61347
61348 if(retval != UA_STATUSCODE_GOOD) {
61349 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_NETWORK,
61350 msg: "Decoding RHE message failed");
61351 closeSecureChannel(client);
61352 return;
61353 }
61354
61355 UA_String_clear(p: &client->discoveryUrl);
61356 UA_String_copy(src: &rheMessage.endpointUrl, dst: &client->discoveryUrl);
61357
61358 UA_TcpReverseHelloMessage_clear(p: &rheMessage);
61359
61360 sendHELMessage(client);
61361}
61362
61363void
61364processOPNResponse(UA_Client *client, const UA_ByteString *message) {
61365 /* Is the content of the expected type? */
61366 size_t offset = 0;
61367 UA_NodeId responseId;
61368 UA_NodeId expectedId =
61369 UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_OPENSECURECHANNELRESPONSE_ENCODING_DEFAULTBINARY);
61370 UA_StatusCode retval = UA_NodeId_decodeBinary(src: message, offset: &offset, dst: &responseId);
61371 if(retval != UA_STATUSCODE_GOOD) {
61372 closeSecureChannel(client);
61373 return;
61374 }
61375
61376 if(!UA_NodeId_equal(p1: &responseId, p2: &expectedId)) {
61377 UA_NodeId_clear(p: &responseId);
61378 closeSecureChannel(client);
61379 return;
61380 }
61381
61382 /* Decode the response */
61383 UA_OpenSecureChannelResponse response;
61384 retval = UA_decodeBinaryInternal(src: message, offset: &offset, dst: &response,
61385 type: &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE], NULL);
61386 if(retval != UA_STATUSCODE_GOOD) {
61387 closeSecureChannel(client);
61388 return;
61389 }
61390
61391 /* Check whether the nonce was reused */
61392 if(client->channel.securityMode != UA_MESSAGESECURITYMODE_NONE &&
61393 UA_ByteString_equal(p1: &client->channel.remoteNonce, p2: &response.serverNonce)) {
61394 UA_LOG_ERROR_CHANNEL(client->config.logging, &client->channel,
61395 "The server reused the last nonce");
61396 client->connectStatus = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
61397 closeSecureChannel(client);
61398 return;
61399 }
61400
61401 /* Move the nonce out of the response */
61402 UA_ByteString_clear(p: &client->channel.remoteNonce);
61403 client->channel.remoteNonce = response.serverNonce;
61404 UA_ByteString_init(p: &response.serverNonce);
61405 UA_ResponseHeader_clear(p: &response.responseHeader);
61406
61407 /* Replace the token. Keep the current token as the old token. Messages
61408 * might still arrive for the old token. */
61409 client->channel.altSecurityToken = client->channel.securityToken;
61410 client->channel.securityToken = response.securityToken;
61411 client->channel.renewState = UA_SECURECHANNELRENEWSTATE_NEWTOKEN_CLIENT;
61412
61413 /* Log a warning if the SecurityToken is not "fresh". Use the normal system
61414 * clock to do the comparison. */
61415 UA_EventLoop *el = client->config.eventLoop;
61416 UA_DateTime wallClockNow = el->dateTime_now(el);
61417 if(wallClockNow - client->channel.securityToken.createdAt >= UA_DATETIME_SEC * 10 ||
61418 wallClockNow - client->channel.securityToken.createdAt <= -UA_DATETIME_SEC * 10)
61419 UA_LOG_WARNING_CHANNEL(client->config.logging, &client->channel, "The \"CreatedAt\" "
61420 "timestamp of the received ChannelSecurityToken does not match "
61421 "with the local system clock");
61422
61423 /* The internal "monotonic" clock is used by the SecureChannel to validate
61424 * that the SecurityToken is still valid. The monotonic clock is independent
61425 * from the system clock getting changed or synchronized to a master clock
61426 * during runtime. */
61427 client->channel.securityToken.createdAt = el->dateTime_nowMonotonic(el);
61428
61429 /* Response.securityToken.revisedLifetime is UInt32, we need to cast it to
61430 * DateTime=Int64. After 75% of the lifetime the renewal takes place as
61431 * described in standard */
61432 client->nextChannelRenewal = client->channel.securityToken.createdAt +
61433 (UA_DateTime) (response.securityToken.revisedLifetime *
61434 (UA_Double) UA_DATETIME_MSEC * 0.75);
61435
61436 /* Compute the new local keys. The remote keys are updated when a message
61437 * with the new SecurityToken is received. */
61438 retval = UA_SecureChannel_generateLocalKeys(channel: &client->channel);
61439 if(retval != UA_STATUSCODE_GOOD) {
61440 closeSecureChannel(client);
61441 return;
61442 }
61443
61444 UA_Float lifetime = (UA_Float)response.securityToken.revisedLifetime / 1000;
61445 UA_Boolean renew = (client->channel.state == UA_SECURECHANNELSTATE_OPEN);
61446 if(renew) {
61447 UA_LOG_INFO_CHANNEL(client->config.logging, &client->channel, "SecureChannel "
61448 "renewed with a revised lifetime of %.2fs", lifetime);
61449 } else {
61450 UA_LOG_INFO_CHANNEL(client->config.logging, &client->channel,
61451 "SecureChannel opened with SecurityPolicy %.*s "
61452 "and a revised lifetime of %.2fs",
61453 (int)client->channel.securityPolicy->policyUri.length,
61454 client->channel.securityPolicy->policyUri.data, lifetime);
61455 }
61456
61457 client->channel.state = UA_SECURECHANNELSTATE_OPEN;
61458}
61459
61460/* OPN messges to renew the channel are sent asynchronous */
61461static void
61462sendOPNAsync(UA_Client *client, UA_Boolean renew) {
61463 if(!UA_SecureChannel_isConnected(channel: &client->channel)) {
61464 client->connectStatus = UA_STATUSCODE_BADINTERNALERROR;
61465 return;
61466 }
61467
61468 client->connectStatus =
61469 UA_SecureChannel_generateLocalNonce(channel: &client->channel);
61470 if(client->connectStatus != UA_STATUSCODE_GOOD)
61471 return;
61472
61473 /* Prepare the OpenSecureChannelRequest */
61474 UA_OpenSecureChannelRequest opnSecRq;
61475 UA_OpenSecureChannelRequest_init(p: &opnSecRq);
61476 opnSecRq.requestHeader.timestamp = UA_DateTime_now();
61477 opnSecRq.requestHeader.authenticationToken = client->authenticationToken;
61478 opnSecRq.securityMode = client->channel.securityMode;
61479 opnSecRq.clientNonce = client->channel.localNonce;
61480 opnSecRq.requestedLifetime = client->config.secureChannelLifeTime;
61481 if(renew) {
61482 opnSecRq.requestType = UA_SECURITYTOKENREQUESTTYPE_RENEW;
61483 UA_LOG_DEBUG_CHANNEL(client->config.logging, &client->channel,
61484 "Requesting to renew the SecureChannel");
61485 } else {
61486 opnSecRq.requestType = UA_SECURITYTOKENREQUESTTYPE_ISSUE;
61487 UA_LOG_DEBUG_CHANNEL(client->config.logging, &client->channel,
61488 "Requesting to open a SecureChannel");
61489 }
61490
61491 /* Prepare the entry for the linked list */
61492 UA_UInt32 requestId = ++client->requestId;
61493
61494 /* Send the OPN message */
61495 UA_LOG_DEBUG(logger: client->config.logging, category: UA_LOGCATEGORY_SECURECHANNEL,
61496 msg: "Requesting to open a SecureChannel");
61497 client->connectStatus =
61498 UA_SecureChannel_sendAsymmetricOPNMessage(channel: &client->channel, requestId, content: &opnSecRq,
61499 contentType: &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST]);
61500 if(client->connectStatus != UA_STATUSCODE_GOOD) {
61501 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_SECURECHANNEL,
61502 msg: "Sending OPN message failed with error %s",
61503 UA_StatusCode_name(code: client->connectStatus));
61504 closeSecureChannel(client);
61505 return;
61506 }
61507
61508 /* Update the state */
61509 client->channel.renewState = UA_SECURECHANNELRENEWSTATE_SENT;
61510 if(client->channel.state < UA_SECURECHANNELSTATE_OPN_SENT)
61511 client->channel.state = UA_SECURECHANNELSTATE_OPN_SENT;
61512
61513 UA_LOG_DEBUG(logger: client->config.logging, category: UA_LOGCATEGORY_SECURECHANNEL,
61514 msg: "OPN message sent");
61515}
61516
61517UA_StatusCode
61518__Client_renewSecureChannel(UA_Client *client) {
61519 UA_LOCK_ASSERT(&client->clientMutex, 1);
61520
61521 /* Check if OPN has been sent or the SecureChannel is still valid */
61522 if(client->channel.state != UA_SECURECHANNELSTATE_OPEN ||
61523 client->channel.renewState == UA_SECURECHANNELRENEWSTATE_SENT ||
61524 client->nextChannelRenewal > UA_DateTime_nowMonotonic())
61525 return UA_STATUSCODE_GOODCALLAGAIN;
61526
61527 sendOPNAsync(client, true);
61528
61529 return client->connectStatus;
61530}
61531
61532UA_StatusCode
61533UA_Client_renewSecureChannel(UA_Client *client) {
61534 lockClient(client);
61535 UA_StatusCode res = __Client_renewSecureChannel(client);
61536 unlockClient(client);
61537 return res;
61538}
61539
61540static void
61541responseActivateSession(UA_Client *client, void *userdata,
61542 UA_UInt32 requestId, void *response) {
61543 UA_LOCK_ASSERT(&client->clientMutex, 1);
61544
61545 UA_ActivateSessionResponse *ar = (UA_ActivateSessionResponse*)response;
61546 if(ar->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
61547 /* Activating the Session failed */
61548 cleanupSession(client);
61549
61550 /* Configuration option to not create a new Session */
61551 if(client->config.noNewSession) {
61552 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61553 msg: "Session cannot be activated with StatusCode %s. "
61554 "The client is configured not to create a new Session.",
61555 UA_StatusCode_name(code: ar->responseHeader.serviceResult));
61556 client->connectStatus = ar->responseHeader.serviceResult;
61557 closeSecureChannel(client);
61558 return;
61559 }
61560
61561 /* The Session is no longer usable. Create a brand new one. */
61562 if(ar->responseHeader.serviceResult == UA_STATUSCODE_BADSESSIONIDINVALID ||
61563 ar->responseHeader.serviceResult == UA_STATUSCODE_BADSESSIONCLOSED) {
61564 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61565 msg: "Session to be activated no longer exists. Create a new Session.");
61566 client->connectStatus = createSessionAsync(client);
61567 return;
61568 }
61569
61570 /* Something else is wrong. Maybe the credentials no longer work. Give up. */
61571 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61572 msg: "Session cannot be activated with StatusCode %s. "
61573 "The client cannot recover from this, closing the connection.",
61574 UA_StatusCode_name(code: ar->responseHeader.serviceResult));
61575 client->connectStatus = ar->responseHeader.serviceResult;
61576 closeSecureChannel(client);
61577 return;
61578 }
61579
61580 /* Replace the nonce */
61581 UA_ByteString_clear(p: &client->serverSessionNonce);
61582 client->serverSessionNonce = ar->serverNonce;
61583 UA_ByteString_init(p: &ar->serverNonce);
61584
61585 client->sessionState = UA_SESSIONSTATE_ACTIVATED;
61586 notifyClientState(client);
61587
61588 /* Immediately check if publish requests are outstanding - for example when
61589 * an existing Session has been reattached / activated. */
61590#ifdef UA_ENABLE_SUBSCRIPTIONS
61591 __Client_Subscriptions_backgroundPublish(client);
61592#endif
61593}
61594
61595static UA_StatusCode
61596activateSessionAsync(UA_Client *client) {
61597 UA_LOCK_ASSERT(&client->clientMutex, 1);
61598
61599 if(client->sessionState != UA_SESSIONSTATE_CREATED &&
61600 client->sessionState != UA_SESSIONSTATE_ACTIVATED) {
61601 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61602 msg: "Can not activate session, session neither created nor activated. "
61603 "Actual state: '%u'", client->sessionState);
61604 return UA_STATUSCODE_BADSESSIONCLOSED;
61605 }
61606
61607 const UA_UserTokenPolicy *utp = findUserTokenPolicy(client, endpoint: &client->endpoint);
61608 if(!utp) {
61609 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_NETWORK,
61610 msg: "Could not find a matching UserTokenPolicy in the endpoint");
61611 return UA_STATUSCODE_BADINTERNALERROR;
61612 }
61613
61614 /* Initialize the request */
61615 UA_ActivateSessionRequest request;
61616 UA_ActivateSessionRequest_init(p: &request);
61617
61618 /* Set the requested LocaleIds */
61619 UA_StatusCode retval = UA_STATUSCODE_GOOD;
61620 if(client->config.sessionLocaleIdsSize && client->config.sessionLocaleIds) {
61621 retval = UA_Array_copy(src: client->config.sessionLocaleIds,
61622 size: client->config.sessionLocaleIdsSize,
61623 dst: (void **)&request.localeIds, type: &UA_TYPES[UA_TYPES_LOCALEID]);
61624 if(retval != UA_STATUSCODE_GOOD)
61625 return retval;
61626 request.localeIdsSize = client->config.sessionLocaleIdsSize;
61627 }
61628
61629 /* Set the User Identity Token. If not defined use an anonymous token. Use
61630 * the PolicyId from the UserTokenPolicy. All token types have the PolicyId
61631 * string as the first element. */
61632 UA_AnonymousIdentityToken anonToken;
61633 retval = UA_ExtensionObject_copy(src: &client->config.userIdentityToken,
61634 dst: &request.userIdentityToken);
61635 if(request.userIdentityToken.encoding != UA_EXTENSIONOBJECT_ENCODED_NOBODY) {
61636 UA_String *policyId = (UA_String*)request.userIdentityToken.content.decoded.data;
61637 UA_String_clear(p: policyId);
61638 retval = UA_String_copy(src: &utp->policyId, dst: policyId);
61639 } else {
61640 UA_AnonymousIdentityToken_init(p: &anonToken);
61641 UA_ExtensionObject_setValueNoDelete(eo: &request.userIdentityToken, p: &anonToken,
61642 type: &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]);
61643 anonToken.policyId = utp->policyId;
61644 }
61645 if(retval != UA_STATUSCODE_GOOD)
61646 return retval;
61647
61648#ifdef UA_ENABLE_ENCRYPTION
61649 UA_SecurityPolicy *utsp = NULL;
61650 UA_SecureChannel *channel = &client->channel;
61651
61652 if(request.userIdentityToken.content.decoded.type ==
61653 &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN])
61654 goto utp_done;
61655
61656 /* Does the UserTokenPolicy have encryption? If not specifically defined in
61657 * the UserTokenPolicy, then the SecurityPolicy of the underlying endpoint
61658 * (SecureChannel) is used. */
61659 UA_String tokenSecurityPolicyUri = (utp->securityPolicyUri.length > 0) ?
61660 utp->securityPolicyUri : client->endpoint.securityPolicyUri;
61661 const UA_String none = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#None");
61662 if(UA_String_equal(p1: &none, p2: &tokenSecurityPolicyUri)) {
61663 if(UA_String_equal(p1: &none, p2: &client->channel.securityPolicy->policyUri)) {
61664 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61665 msg: "!!! Warning !!! AuthenticationToken is transmitted "
61666 "without encryption");
61667 }
61668 goto utp_done;
61669 }
61670
61671 /* Get the SecurityPolicy for authentication */
61672 utsp = getAuthSecurityPolicy(client, policyUri: tokenSecurityPolicyUri);
61673 if(!utsp) {
61674 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61675 msg: "UserTokenPolicy %.*s not available for authentication",
61676 (int)tokenSecurityPolicyUri.length, tokenSecurityPolicyUri.data);
61677 retval = UA_STATUSCODE_BADSECURITYPOLICYREJECTED;
61678 goto utp_done;
61679 }
61680
61681 /* Encrypt the UserIdentityToken */
61682 retval = encryptUserIdentityToken(client, utsp, userIdentityToken: &request.userIdentityToken);
61683
61684 /* Create the UserTokenSignature if this is possible for the token.
61685 * The certificate is already loaded into the utsp. */
61686 if(utp->tokenType == UA_USERTOKENTYPE_CERTIFICATE)
61687 retval |= signUserTokenSignature(client, utsp, request: &request);
61688
61689 utp_done:
61690 /* Create the client signature with the SecurityPolicy of the SecurteChannel */
61691 if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
61692 channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
61693 retval |= signClientSignature(client, request: &request);
61694#endif
61695
61696 /* Send the request */
61697 if(UA_LIKELY(retval == UA_STATUSCODE_GOOD))
61698 retval = __Client_AsyncService(client, request: &request,
61699 requestType: &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST],
61700 callback: (UA_ClientAsyncServiceCallback)responseActivateSession,
61701 responseType: &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE],
61702 NULL, NULL);
61703
61704 /* On success, advance the session state */
61705 if(retval == UA_STATUSCODE_GOOD)
61706 client->sessionState = UA_SESSIONSTATE_ACTIVATE_REQUESTED;
61707 else
61708 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61709 msg: "ActivateSession failed when sending the request with error code %s",
61710 UA_StatusCode_name(code: retval));
61711
61712 /* Clean up */
61713 UA_ActivateSessionRequest_clear(p: &request);
61714 return retval;
61715}
61716
61717static const UA_String binaryTransport =
61718 UA_STRING_STATIC("http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary");
61719
61720/* Find a matching endpoint -- the UserTokenPolicy is matched later */
61721static UA_Boolean
61722matchEndpoint(UA_Client *client, const UA_EndpointDescription *endpoint, unsigned i) {
61723 /* Matching ApplicationUri if defined */
61724 if(client->config.applicationUri.length > 0 &&
61725 !UA_String_equal(p1: &client->config.applicationUri,
61726 p2: &endpoint->server.applicationUri)) {
61727 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61728 msg: "Rejecting endpoint %u: application uri not match", i);
61729 return false;
61730 }
61731
61732 /* Look out for binary transport endpoints.
61733 * Note: Siemens returns empty ProfileUrl, we will accept it as binary. */
61734 if(endpoint->transportProfileUri.length != 0 &&
61735 !UA_String_equal(p1: &endpoint->transportProfileUri, p2: &binaryTransport)) {
61736 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61737 msg: "Rejecting endpoint %u: transport profile does not match", i);
61738 return false;
61739 }
61740
61741 /* Valid SecurityMode? */
61742 if(endpoint->securityMode < 1 || endpoint->securityMode > 3) {
61743 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61744 msg: "Rejecting endpoint %u: invalid security mode", i);
61745 return false;
61746 }
61747
61748 /* Selected SecurityMode? */
61749 if(client->config.securityMode > 0 &&
61750 client->config.securityMode != endpoint->securityMode) {
61751 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61752 msg: "Rejecting endpoint %u: security mode does not match", i);
61753 return false;
61754 }
61755
61756 /* Matching SecurityPolicy? */
61757 if(client->config.securityPolicyUri.length > 0 &&
61758 !UA_String_equal(p1: &client->config.securityPolicyUri, p2: &endpoint->securityPolicyUri)) {
61759 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61760 msg: "Rejecting endpoint %u: security policy does not match the configuration", i);
61761 return false;
61762 }
61763
61764 /* SecurityPolicy available? */
61765 if(!getSecurityPolicy(client, policyUri: endpoint->securityPolicyUri)) {
61766 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61767 msg: "Rejecting endpoint %u: security policy not available", i);
61768 return false;
61769 }
61770
61771 return true;
61772}
61773
61774/* Match the policy with the configured user token */
61775static UA_Boolean
61776matchUserToken(UA_Client *client,
61777 const UA_UserTokenPolicy *tokenPolicy) {
61778 const UA_DataType *tokenType =
61779 client->config.userIdentityToken.content.decoded.type;
61780
61781 if(tokenPolicy->tokenType == UA_USERTOKENTYPE_ANONYMOUS &&
61782 (tokenType == &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN] || !tokenType))
61783 return true;
61784
61785 if(tokenPolicy->tokenType == UA_USERTOKENTYPE_USERNAME &&
61786 tokenType == &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN])
61787 return true;
61788
61789 if(tokenPolicy->tokenType == UA_USERTOKENTYPE_CERTIFICATE &&
61790 tokenType == &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN])
61791 return true;
61792
61793 if(tokenPolicy->tokenType == UA_USERTOKENTYPE_ISSUEDTOKEN &&
61794 tokenType == &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN])
61795 return true;
61796
61797 return false;
61798}
61799
61800/* Returns a matching UserTokenPolicy from the EndpointDescription. If a
61801 * UserTokenPolicy is configured in the client config, then we need an exact
61802 * match. */
61803static UA_UserTokenPolicy *
61804findUserTokenPolicy(UA_Client *client, UA_EndpointDescription *endpoint) {
61805 /* Was a UserTokenPolicy configured? Then we need an exact match. */
61806 UA_UserTokenPolicy *requiredTokenPolicy = NULL;
61807 UA_UserTokenPolicy tmp;
61808 UA_UserTokenPolicy_init(p: &tmp);
61809 if(!UA_equal(p1: &tmp, p2: &client->config.userTokenPolicy, type: &UA_TYPES[UA_TYPES_USERTOKENPOLICY]))
61810 requiredTokenPolicy = &client->config.userTokenPolicy;
61811
61812 for(size_t j = 0; j < endpoint->userIdentityTokensSize; ++j) {
61813 /* Is the SecurityPolicy available? */
61814 UA_UserTokenPolicy *tokenPolicy = &endpoint->userIdentityTokens[j];
61815
61816 UA_String tokenPolicyUri = tokenPolicy->securityPolicyUri;
61817 if(UA_String_isEmpty(s: &tokenPolicyUri))
61818 tokenPolicyUri = endpoint->securityPolicyUri;
61819
61820 /* Ignore missing auth security policy for anonymous tokens */
61821 if(client->config.userIdentityToken.content.decoded.type &&
61822 client->config.userIdentityToken.content.decoded.type !=
61823 &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]) {
61824 const UA_String none = UA_STRING_STATIC("http://opcfoundation.org/UA/SecurityPolicy#None");
61825 /* activateSessionAsync() handles the None case separately without accessing authSecurityPolicies */
61826 if(!UA_String_equal(p1: &none, p2: &tokenPolicyUri) && !getAuthSecurityPolicy(client, policyUri: tokenPolicyUri))
61827 continue;
61828 }
61829
61830 /* Required SecurityPolicyUri in the configuration? */
61831 if(!UA_String_isEmpty(s: &client->config.authSecurityPolicyUri) &&
61832 !UA_String_equal(p1: &client->config.authSecurityPolicyUri,
61833 p2: &tokenPolicyUri))
61834 continue;
61835
61836 /* Match (entire) UserTokenPolicy if defined in the configuration? */
61837 if(requiredTokenPolicy &&
61838 !UA_equal(p1: requiredTokenPolicy, p2: tokenPolicy, type: &UA_TYPES[UA_TYPES_USERTOKENPOLICY]))
61839 continue;
61840
61841 /* Match with the configured UserToken */
61842 if(!matchUserToken(client, tokenPolicy))
61843 continue;
61844
61845 /* Found a match? */
61846 return tokenPolicy;
61847 }
61848
61849 return NULL;
61850}
61851
61852/* Combination of UA_Client_getEndpointsInternal and getEndpoints */
61853static void
61854responseGetEndpoints(UA_Client *client, void *userdata,
61855 UA_UInt32 requestId, void *response) {
61856 UA_LOCK_ASSERT(&client->clientMutex, 1);
61857
61858 client->endpointsHandshake = false;
61859
61860 UA_LOG_DEBUG(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61861 msg: "Received GetEndpointsResponse");
61862
61863 UA_GetEndpointsResponse *resp = (UA_GetEndpointsResponse*)response;
61864
61865 /* GetEndpoints not possible. Fail the connection */
61866 if(resp->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
61867 /* Fail the connection attempt if the SecureChannel is still connected.
61868 * If the SecureChannel is (intentionally or unintentionally) closed,
61869 * the connectStatus should come from there. */
61870 if(UA_SecureChannel_isConnected(channel: &client->channel)) {
61871 client->connectStatus = resp->responseHeader.serviceResult;
61872 closeSecureChannel(client);
61873 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61874 msg: "GetEndpointRequest failed with error code %s",
61875 UA_StatusCode_name(code: client->connectStatus));
61876 }
61877
61878 UA_GetEndpointsResponse_clear(p: resp);
61879 return;
61880 }
61881
61882 /* Warn if the Endpoints look incomplete / don't match the EndpointUrl */
61883 Client_warnEndpointsResult(client, response: resp, endpointUrl: &client->discoveryUrl);
61884
61885 const size_t notFound = (size_t)-1;
61886 size_t bestEndpointIndex = notFound;
61887 UA_Byte bestEndpointLevel = 0;
61888
61889 /* Find a matching combination of Endpoint and UserTokenPolicy */
61890 for(size_t i = 0; i < resp->endpointsSize; ++i) {
61891 UA_EndpointDescription* endpoint = &resp->endpoints[i];
61892
61893 /* Do we already have a better candidate? */
61894 if(endpoint->securityLevel < bestEndpointLevel)
61895 continue;
61896
61897 /* Does the endpoint match the client configuration? */
61898 if(!matchEndpoint(client, endpoint, i: (unsigned)i))
61899 continue;
61900
61901 /* Do we want a session? If yes, then the endpoint needs to have a
61902 * UserTokenPolicy that matches the configuration. */
61903 if(!client->config.noSession && !findUserTokenPolicy(client, endpoint)) {
61904 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61905 msg: "Rejecting endpoint %lu: No matching UserTokenPolicy",
61906 (long unsigned)i);
61907 continue;
61908 }
61909
61910 /* Best endpoint so far */
61911 bestEndpointLevel = endpoint->securityLevel;
61912 bestEndpointIndex = i;
61913 }
61914
61915 /* No matching endpoint found */
61916 if(bestEndpointIndex == notFound) {
61917 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61918 msg: "No suitable endpoint found");
61919 client->connectStatus = UA_STATUSCODE_BADIDENTITYTOKENREJECTED;
61920 closeSecureChannel(client);
61921 return;
61922 }
61923
61924 /* Store the endpoint description in the client. It contains the
61925 * ApplicationDescription and the UserTokenPolicies. We continue to look up
61926 * the matching UserTokenPolicy from there. */
61927 UA_EndpointDescription_clear(p: &client->endpoint);
61928 client->endpoint = resp->endpoints[bestEndpointIndex];
61929 UA_EndpointDescription_init(p: &resp->endpoints[bestEndpointIndex]);
61930
61931#if UA_LOGLEVEL <= 300
61932 const char *securityModeNames[3] = {"None", "Sign", "SignAndEncrypt"};
61933 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61934 msg: "Selected endpoint with EndpointUrl %.*s, SecurityMode "
61935 "%s and SecurityPolicy %.*s",
61936 (int)client->endpoint.endpointUrl.length,
61937 client->endpoint.endpointUrl.data,
61938 securityModeNames[client->endpoint.securityMode - 1],
61939 (int)client->endpoint.securityPolicyUri.length,
61940 client->endpoint.securityPolicyUri.data);
61941#endif
61942
61943 /* A different SecurityMode or SecurityPolicy is defined by the Endpoint.
61944 * Close the SecureChannel and reconnect. */
61945 if(client->endpoint.securityMode != client->channel.securityMode ||
61946 !UA_String_equal(p1: &client->endpoint.securityPolicyUri,
61947 p2: &client->channel.securityPolicy->policyUri)) {
61948 closeSecureChannel(client);
61949 return;
61950 }
61951
61952 /* We were using a distinct discovery URL and we are switching away from it.
61953 * Close the SecureChannel to reopen with the EndpointUrl. If an endpoint
61954 * was selected, then we use the endpointUrl for the HEL message. */
61955 if(client->discoveryUrl.length > 0 &&
61956 !UA_String_equal(p1: &client->discoveryUrl, p2: &client->endpoint.endpointUrl)) {
61957 closeSecureChannel(client);
61958 return;
61959 }
61960
61961 /* Nothing to do. We have selected an endpoint that we can use to open a
61962 * Session on the current SecureChannel. */
61963}
61964
61965static UA_StatusCode
61966requestGetEndpoints(UA_Client *client) {
61967 UA_LOCK_ASSERT(&client->clientMutex, 1);
61968
61969 UA_GetEndpointsRequest request;
61970 UA_GetEndpointsRequest_init(p: &request);
61971 request.endpointUrl = getEndpointUrl(client);
61972
61973 UA_StatusCode retval =
61974 __Client_AsyncService(client, request: &request, requestType: &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST],
61975 callback: (UA_ClientAsyncServiceCallback) responseGetEndpoints,
61976 responseType: &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE], NULL, NULL);
61977 if(retval != UA_STATUSCODE_GOOD) {
61978 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61979 msg: "RequestGetEndpoints failed when sending the request with error code %s",
61980 UA_StatusCode_name(code: retval));
61981 return retval;
61982 }
61983
61984 client->endpointsHandshake = true;
61985 return UA_STATUSCODE_GOOD;
61986}
61987
61988static void
61989responseFindServers(UA_Client *client, void *userdata,
61990 UA_UInt32 requestId, void *response) {
61991 client->findServersHandshake = false;
61992 UA_LOG_DEBUG(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
61993 msg: "Received FindServersResponse");
61994
61995 /* Error handling. Log the error but continue to connect with the current
61996 * EndpointURL. */
61997 UA_FindServersResponse *fsr = (UA_FindServersResponse*)response;
61998 if(fsr->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
61999 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62000 msg: "FindServers failed with error code %s. Continue with the "
62001 "EndpointURL %.*s.",
62002 UA_StatusCode_name(code: fsr->responseHeader.serviceResult),
62003 (int)client->config.endpointUrl.length,
62004 client->config.endpointUrl.data);
62005 UA_String_clear(p: &client->discoveryUrl);
62006 UA_String_copy(src: &client->config.endpointUrl, dst: &client->discoveryUrl);
62007 return;
62008 }
62009
62010 /* Check if one of the returned servers matches the EndpointURL already used */
62011 for(size_t i = 0; i < fsr->serversSize; i++) {
62012 UA_ApplicationDescription *server = &fsr->servers[i];
62013
62014 /* Filter by the ApplicationURI if defined */
62015 if(client->config.applicationUri.length > 0 &&
62016 !UA_String_equal(p1: &client->config.applicationUri, p2: &server->applicationUri))
62017 continue;
62018
62019 for(size_t j = 0; j < server->discoveryUrlsSize; j++) {
62020 if(UA_String_equal(p1: &client->config.endpointUrl, p2: &server->discoveryUrls[j])) {
62021 UA_String_clear(p: &client->discoveryUrl);
62022 client->discoveryUrl = server->discoveryUrls[j];
62023 UA_String_init(p: &server->discoveryUrls[j]);
62024 return;
62025 }
62026 }
62027 }
62028
62029 /* The current EndpointURL is not usable. Pick the first "opc.tcp" DiscoveryUrl of a
62030 * returned server. */
62031 for(size_t i = 0; i < fsr->serversSize; i++) {
62032 UA_ApplicationDescription *server = &fsr->servers[i];
62033 if(server->applicationType != UA_APPLICATIONTYPE_SERVER &&
62034 server->applicationType != UA_APPLICATIONTYPE_CLIENTANDSERVER &&
62035 server->applicationType != UA_APPLICATIONTYPE_DISCOVERYSERVER)
62036 continue;
62037
62038 /* Filter by the ApplicationURI if defined */
62039 if(client->config.applicationUri.length > 0 &&
62040 !UA_String_equal(p1: &client->config.applicationUri, p2: &server->applicationUri))
62041 continue;
62042
62043 for(size_t j = 0; j < server->discoveryUrlsSize; j++) {
62044 /* Try to parse the DiscoveryUrl. This weeds out http schemas (etc.)
62045 * and invalid DiscoveryUrls in general. */
62046 UA_String hostname, path;
62047 UA_UInt16 port;
62048 UA_StatusCode res =
62049 UA_parseEndpointUrl(endpointUrl: &server->discoveryUrls[j], outHostname: &hostname, outPort: &port, outPath: &path);
62050 if(res != UA_STATUSCODE_GOOD)
62051 continue;
62052
62053 /* Use this DiscoveryUrl in the client */
62054 UA_String_clear(p: &client->discoveryUrl);
62055 client->discoveryUrl = server->discoveryUrls[j];
62056 UA_String_init(p: &server->discoveryUrls[j]);
62057
62058 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62059 msg: "Use the EndpointURL %.*s returned from FindServers and reconnect",
62060 (int)client->discoveryUrl.length, client->discoveryUrl.data);
62061
62062 /* Close the SecureChannel to build it up new with the correct
62063 * EndpointURL in the HEL/ACK handshake. In closeSecureChannel the
62064 * received client->endpoint is reset also. */
62065 closeSecureChannel(client);
62066 return;
62067 }
62068 }
62069
62070 /* Could not find a suitable server. Try to continue with the
62071 * original EndpointURL. */
62072 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62073 msg: "FindServers did not returned a suitable DiscoveryURL. "
62074 "Continue with the EndpointURL %.*s.",
62075 (int)client->config.endpointUrl.length,
62076 client->config.endpointUrl.data);
62077 UA_String_clear(p: &client->discoveryUrl);
62078 UA_String_copy(src: &client->config.endpointUrl, dst: &client->discoveryUrl);
62079}
62080
62081static UA_StatusCode
62082requestFindServers(UA_Client *client) {
62083 UA_FindServersRequest request;
62084 UA_FindServersRequest_init(p: &request);
62085 request.requestHeader.timestamp = UA_DateTime_now();
62086 request.requestHeader.timeoutHint = 10000;
62087 request.endpointUrl = client->config.endpointUrl;
62088 UA_StatusCode retval =
62089 __Client_AsyncService(client, request: &request, requestType: &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST],
62090 callback: (UA_ClientAsyncServiceCallback) responseFindServers,
62091 responseType: &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE], NULL, NULL);
62092 if(retval != UA_STATUSCODE_GOOD) {
62093 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62094 msg: "FindServers failed when sending the request with error code %s",
62095 UA_StatusCode_name(code: retval));
62096 return retval;
62097 }
62098
62099 client->findServersHandshake = true;
62100 return UA_STATUSCODE_GOOD;
62101}
62102
62103static void
62104createSessionCallback(UA_Client *client, void *userdata,
62105 UA_UInt32 requestId, void *response) {
62106 UA_LOCK_ASSERT(&client->clientMutex, 1);
62107
62108 UA_CreateSessionResponse *sessionResponse = (UA_CreateSessionResponse*)response;
62109 UA_StatusCode res = sessionResponse->responseHeader.serviceResult;
62110 if(res != UA_STATUSCODE_GOOD)
62111 goto cleanup;
62112
62113#ifdef UA_ENABLE_ENCRYPTION
62114 if(client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGN ||
62115 client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
62116 /* Verify the session response was created with the same certificate as
62117 * the SecureChannel */
62118 if(!UA_ByteString_equal(p1: &sessionResponse->serverCertificate,
62119 p2: &client->channel.remoteCertificate)) {
62120 res = UA_STATUSCODE_BADCERTIFICATEINVALID;
62121 goto cleanup;
62122 }
62123
62124 /* Verify the client signature */
62125 res = checkCreateSessionSignature(client, channel: &client->channel, response: sessionResponse);
62126 if(res != UA_STATUSCODE_GOOD)
62127 goto cleanup;
62128 }
62129#endif
62130
62131 /* Copy nonce and AuthenticationToken */
62132 UA_ByteString_clear(p: &client->serverSessionNonce);
62133 UA_NodeId_clear(p: &client->authenticationToken);
62134 res |= UA_ByteString_copy(src: &sessionResponse->serverNonce,
62135 dst: &client->serverSessionNonce);
62136 res |= UA_NodeId_copy(src: &sessionResponse->authenticationToken,
62137 dst: &client->authenticationToken);
62138 if(res != UA_STATUSCODE_GOOD)
62139 goto cleanup;
62140
62141 /* Activate the new Session */
62142 client->sessionState = UA_SESSIONSTATE_CREATED;
62143
62144 cleanup:
62145 client->connectStatus = res;
62146 if(client->connectStatus != UA_STATUSCODE_GOOD)
62147 client->sessionState = UA_SESSIONSTATE_CLOSED;
62148}
62149
62150static UA_StatusCode
62151createSessionAsync(UA_Client *client) {
62152 UA_LOCK_ASSERT(&client->clientMutex, 1);
62153
62154 /* Generate the local nonce for the session */
62155 UA_StatusCode res = UA_STATUSCODE_GOOD;
62156 if(client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGN ||
62157 client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
62158 if(client->clientSessionNonce.length != UA_SESSION_LOCALNONCELENGTH) {
62159 UA_ByteString_clear(p: &client->clientSessionNonce);
62160 res = UA_ByteString_allocBuffer(bs: &client->clientSessionNonce,
62161 UA_SESSION_LOCALNONCELENGTH);
62162 if(res != UA_STATUSCODE_GOOD)
62163 return res;
62164 }
62165 res = client->channel.securityPolicy->symmetricModule.
62166 generateNonce(client->channel.securityPolicy->policyContext,
62167 &client->clientSessionNonce);
62168 if(res != UA_STATUSCODE_GOOD)
62169 return res;
62170 }
62171
62172 /* Prepare and send the request */
62173 UA_CreateSessionRequest request;
62174 UA_CreateSessionRequest_init(p: &request);
62175 request.clientNonce = client->clientSessionNonce;
62176 request.requestedSessionTimeout = client->config.requestedSessionTimeout;
62177 request.maxResponseMessageSize = UA_INT32_MAX;
62178 request.endpointUrl = client->endpoint.endpointUrl;
62179 request.clientDescription = client->config.clientDescription;
62180 request.sessionName = client->config.sessionName;
62181 if(client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGN ||
62182 client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
62183 request.clientCertificate = client->channel.securityPolicy->localCertificate;
62184 }
62185
62186 res = __Client_AsyncService(client, request: &request,
62187 requestType: &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST],
62188 callback: (UA_ClientAsyncServiceCallback)createSessionCallback,
62189 responseType: &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE], NULL, NULL);
62190
62191 if(res == UA_STATUSCODE_GOOD)
62192 client->sessionState = UA_SESSIONSTATE_CREATE_REQUESTED;
62193 else
62194 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62195 msg: "CreateSession failed when sending the request with "
62196 "error code %s", UA_StatusCode_name(code: res));
62197
62198 return res;
62199}
62200
62201static UA_StatusCode
62202initSecurityPolicy(UA_Client *client) {
62203 /* Find the SecurityPolicy */
62204 UA_SecurityPolicy *sp =
62205 getSecurityPolicy(client, policyUri: client->endpoint.securityPolicyUri);
62206
62207 /* Unknown SecurityPolicy -- we would never select such an endpoint */
62208 if(!sp)
62209 return UA_STATUSCODE_BADINTERNALERROR;
62210
62211 /* Already initialized -- check we are using the configured SecurityPolicy */
62212 if(client->channel.securityPolicy)
62213 return (client->channel.securityPolicy == sp) ?
62214 UA_STATUSCODE_GOOD : UA_STATUSCODE_BADINTERNALERROR;
62215
62216 /* Set the SecurityMode -- none if no endpoint is selected so far */
62217 client->channel.securityMode = client->endpoint.securityMode;
62218 if(client->channel.securityMode == UA_MESSAGESECURITYMODE_INVALID)
62219 client->channel.securityMode = UA_MESSAGESECURITYMODE_NONE;
62220
62221 /* Instantiate the SecurityPolicy context with the remote certificate */
62222 return UA_SecureChannel_setSecurityPolicy(channel: &client->channel, securityPolicy: sp,
62223 remoteCertificate: &client->endpoint.serverCertificate);
62224}
62225
62226static void
62227connectActivity(UA_Client *client) {
62228 UA_LOCK_ASSERT(&client->clientMutex, 1);
62229 UA_LOG_TRACE(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62230 msg: "Client connect iterate");
62231
62232 /* Could not connect with an error that canot be recovered from */
62233 if(client->connectStatus != UA_STATUSCODE_GOOD)
62234 return;
62235
62236 /* Already connected */
62237 if(client->sessionState == UA_SESSIONSTATE_ACTIVATED)
62238 return;
62239
62240 /* Switch on the SecureChannel state */
62241 switch(client->channel.state) {
62242 /* Nothing to do if the connection has not opened fully */
62243 case UA_SECURECHANNELSTATE_CONNECTING:
62244 case UA_SECURECHANNELSTATE_REVERSE_CONNECTED:
62245 case UA_SECURECHANNELSTATE_CLOSING:
62246 case UA_SECURECHANNELSTATE_HEL_SENT:
62247 case UA_SECURECHANNELSTATE_OPN_SENT:
62248 return;
62249
62250 /* Send HEL */
62251 case UA_SECURECHANNELSTATE_CONNECTED:
62252 client->connectStatus = sendHELMessage(client);
62253 return;
62254
62255 /* ACK receieved. Send OPN. */
62256 case UA_SECURECHANNELSTATE_ACK_RECEIVED:
62257 sendOPNAsync(client, false); /* Send OPN */
62258 return;
62259
62260 /* The channel is open -> continue with the Session handling */
62261 case UA_SECURECHANNELSTATE_OPEN:
62262 break;
62263
62264 /* The connection is closed. Reset the SecureChannel and open a new TCP
62265 * connection */
62266 case UA_SECURECHANNELSTATE_CLOSED:
62267 if(client->config.noReconnect)
62268 client->connectStatus = UA_STATUSCODE_BADNOTCONNECTED;
62269 else
62270 initConnect(client); /* Sets the connectStatus internally */
62271 return;
62272
62273 /* These states should never occur for the client */
62274 default:
62275 client->connectStatus = UA_STATUSCODE_BADINTERNALERROR;
62276 return;
62277 }
62278
62279 /* <-- The SecureChannel is open --> */
62280
62281 /* Ongoing handshake -> Waiting for a response */
62282 if(client->endpointsHandshake || client->findServersHandshake)
62283 return;
62284
62285 /* Call FindServers to see if we should reconnect with another EndpointUrl.
62286 * This needs to be done before GetEndpoints, as the set of returned
62287 * endpoints may depend on the EndpointUrl used during the initial HEL/ACK
62288 * handshake. */
62289 if(client->discoveryUrl.length == 0) {
62290 client->connectStatus = requestFindServers(client);
62291 return;
62292 }
62293
62294 /* GetEndpoints to identify the remote side and/or reset the SecureChannel
62295 * with encryption */
62296 if(endpointUnconfigured(endpoint: &client->endpoint)) {
62297 client->connectStatus = requestGetEndpoints(client);
62298 return;
62299 }
62300
62301 /* Have the final SecureChannel but no session */
62302 if(client->config.noSession)
62303 return;
62304
62305 /* Create and Activate the Session */
62306 switch(client->sessionState) {
62307 /* Send a CreateSessionRequest */
62308 case UA_SESSIONSTATE_CLOSED:
62309 client->connectStatus = createSessionAsync(client);
62310 return;
62311
62312 /* Activate the Session */
62313 case UA_SESSIONSTATE_CREATED:
62314 client->connectStatus = activateSessionAsync(client);
62315 return;
62316
62317 case UA_SESSIONSTATE_CREATE_REQUESTED:
62318 case UA_SESSIONSTATE_ACTIVATE_REQUESTED:
62319 case UA_SESSIONSTATE_ACTIVATED:
62320 case UA_SESSIONSTATE_CLOSING:
62321 return; /* Nothing to do */
62322
62323 /* These states should never occur for the client */
62324 default:
62325 client->connectStatus = UA_STATUSCODE_BADINTERNALERROR;
62326 break;
62327 }
62328}
62329
62330static UA_StatusCode
62331verifyClientSecureChannelHeader(void *application, UA_SecureChannel *channel,
62332 const UA_AsymmetricAlgorithmSecurityHeader *asymHeader) {
62333 UA_Client *client = (UA_Client*)application;
62334 const UA_SecurityPolicy *sp = channel->securityPolicy;
62335 UA_assert(sp != NULL);
62336
62337 /* Check the SecurityPolicyUri */
62338 if(asymHeader->securityPolicyUri.length > 0 &&
62339 !UA_String_equal(p1: &sp->policyUri, p2: &asymHeader->securityPolicyUri)) {
62340 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62341 msg: "The server uses a different SecurityPolicy from the client");
62342 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
62343 }
62344
62345 /* Get the remote certificate.
62346 * Omit the remainder if an entire certificate chain was sent. */
62347 UA_ByteString serverCert = getLeafCertificate(chain: asymHeader->senderCertificate);
62348
62349 /* If encryption is enabled, then a server certificate is defined.
62350 * Otherwise the creation of the SecureChannel would have failed. */
62351 UA_assert(channel->securityMode == UA_MESSAGESECURITYMODE_NONE ||
62352 serverCert.length > 0);
62353
62354 /* If a server certificate is sent in the asymHeader, check that the same
62355 * certificate was defined for the endpoint */
62356 if(serverCert.length > 0 &&
62357 !UA_String_equal(p1: &serverCert, p2: &client->endpoint.serverCertificate)) {
62358 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62359 msg: "The server certificate is different from the EndpointDescription");
62360 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
62361 }
62362
62363 /* Verify the certificate the server assumes on our end */
62364 UA_StatusCode res = sp->asymmetricModule.
62365 compareCertificateThumbprint(sp, &asymHeader->receiverCertificateThumbprint);
62366 if(res != UA_STATUSCODE_GOOD) {
62367 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62368 msg: "The server does not use the client certificate "
62369 "used for the selected SecurityPolicy");
62370 return res;
62371 }
62372
62373 return UA_STATUSCODE_GOOD;
62374}
62375
62376/* The local ApplicationURI has to match the certificates of the
62377 * SecurityPolicies */
62378static void
62379verifyClientApplicationURI(const UA_Client *client) {
62380#if defined(UA_ENABLE_ENCRYPTION) && (UA_LOGLEVEL <= 400)
62381 for(size_t i = 0; i < client->config.securityPoliciesSize; i++) {
62382 UA_SecurityPolicy *sp = &client->config.securityPolicies[i];
62383 if(!sp->localCertificate.data) {
62384 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62385 msg: "skip verifying ApplicationURI for the SecurityPolicy %.*s",
62386 (int)sp->policyUri.length, sp->policyUri.data);
62387 continue;
62388 }
62389
62390 UA_StatusCode retval =
62391 client->config.certificateVerification.
62392 verifyApplicationURI(&client->config.certificateVerification,
62393 &sp->localCertificate,
62394 &client->config.clientDescription.applicationUri);
62395 if(retval != UA_STATUSCODE_GOOD) {
62396 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62397 msg: "The configured ApplicationURI does not match the URI "
62398 "specified in the certificate for the SecurityPolicy %.*s",
62399 (int)sp->policyUri.length, sp->policyUri.data);
62400 }
62401 }
62402#endif
62403}
62404
62405static void
62406delayedNetworkCallback(void *application, void *context);
62407
62408static void
62409__Client_networkCallback(UA_ConnectionManager *cm, uintptr_t connectionId,
62410 void *application, void **connectionContext,
62411 UA_ConnectionState state, const UA_KeyValueMap *params,
62412 UA_ByteString msg) {
62413 /* Take the client lock */
62414 UA_Client *client = (UA_Client*)application;
62415 lockClient(client);
62416
62417 UA_LOG_TRACE(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT, msg: "Client network callback");
62418
62419 /* A new connection with no context pointer attached */
62420 if(!*connectionContext) {
62421 /* Inconsistent SecureChannel state. Has to be fresh for a new
62422 * connection. */
62423 if(client->channel.state != UA_SECURECHANNELSTATE_CLOSED &&
62424 client->channel.state != UA_SECURECHANNELSTATE_REVERSE_LISTENING) {
62425 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62426 msg: "Cannot open a connection, the SecureChannel is already used");
62427 client->connectStatus = UA_STATUSCODE_BADINTERNALERROR;
62428 notifyClientState(client);
62429 unlockClient(client);
62430 return;
62431 }
62432
62433 /* Initialize the client connection and attach to the EventLoop connection */
62434 client->channel.connectionManager = cm;
62435 client->channel.connectionId = connectionId;
62436 *connectionContext = &client->channel;
62437 }
62438
62439 /* The connection is closing in the EventLoop. This is the last callback
62440 * from that connection. Clean up the SecureChannel in the client. */
62441 if(state == UA_CONNECTIONSTATE_CLOSING) {
62442 UA_LOG_INFO_CHANNEL(client->config.logging, &client->channel,
62443 "SecureChannel closed");
62444
62445 /* Set to closing (could be done already in UA_SecureChannel_shutdown).
62446 * This impacts the handling of cancelled requests below. */
62447 UA_SecureChannelState oldState = client->channel.state;
62448 client->channel.state = UA_SECURECHANNELSTATE_CLOSING;
62449
62450 /* Set the Session to CREATED if it was ACTIVATED */
62451 if(client->sessionState == UA_SESSIONSTATE_ACTIVATED)
62452 client->sessionState = UA_SESSIONSTATE_CREATED;
62453
62454 /* Delete outstanding async services - the RequestId is no longer valid. Do
62455 * this after setting the Session state. Otherwise we send out new Publish
62456 * Requests immediately. */
62457 __Client_AsyncService_removeAll(client, UA_STATUSCODE_BADSECURECHANNELCLOSED);
62458
62459 /* Clean up the channel and set the status to CLOSED */
62460 UA_SecureChannel_clear(channel: &client->channel);
62461
62462 /* The connection closed before it actually opened. Since we are
62463 * connecting asynchronously, this happens when the TCP connection
62464 * fails. Try to fall back on the initial EndpointUrl. */
62465 if(oldState == UA_SECURECHANNELSTATE_CONNECTING &&
62466 client->connectStatus == UA_STATUSCODE_GOOD)
62467 client->connectStatus = fallbackEndpointUrl(client);
62468
62469 /* Try to reconnect */
62470 goto continue_connect;
62471 }
62472
62473 /* Update the SecureChannel state */
62474 if(UA_LIKELY(state == UA_CONNECTIONSTATE_ESTABLISHED)) {
62475 /* The connection is now open on the TCP level. Set the SecureChannel
62476 * state to reflect this. Otherwise later consistency checks for the
62477 * received messages fail. */
62478 if(client->channel.state < UA_SECURECHANNELSTATE_CONNECTED)
62479 client->channel.state = UA_SECURECHANNELSTATE_CONNECTED;
62480 } else /* state == UA_CONNECTIONSTATE_OPENING */ {
62481 /* The connection was opened on our end only. Waiting for the TCP handshake
62482 * to complete. */
62483 client->channel.state = UA_SECURECHANNELSTATE_CONNECTING;
62484 }
62485
62486 /* Received a message. Process the message with the SecureChannel. */
62487 UA_StatusCode res = UA_SecureChannel_loadBuffer(channel: &client->channel, buffer: msg);
62488 while(UA_LIKELY(res == UA_STATUSCODE_GOOD)) {
62489 UA_MessageType messageType;
62490 UA_UInt32 requestId = 0;
62491 UA_ByteString payload = UA_BYTESTRING_NULL;
62492 UA_Boolean copied = false;
62493 res = UA_SecureChannel_getCompleteMessage(channel: &client->channel, messageType: &messageType, requestId: &requestId,
62494 payload: &payload, copied: &copied);
62495 if(res != UA_STATUSCODE_GOOD || payload.length == 0)
62496 break;
62497 res = processServiceResponse(client, channel: &client->channel,
62498 messageType, requestId, message: &payload);
62499 if(copied)
62500 UA_ByteString_clear(p: &payload);
62501
62502 /* Abort after synchronous processing of a message.
62503 * Add a delayed callback to process the remaining buffer ASAP. */
62504 if(res == UA_STATUSCODE_GOODCOMPLETESASYNCHRONOUSLY) {
62505 if(client->channel.unprocessed.length > client->channel.unprocessedOffset &&
62506 client->channel.unprocessedDelayed.callback == NULL) {
62507 client->channel.unprocessedDelayed.callback = delayedNetworkCallback;
62508 client->channel.unprocessedDelayed.application = client;
62509 client->channel.unprocessedDelayed.context = &client->channel;
62510 UA_EventLoop *el = client->config.eventLoop;
62511 el->addDelayedCallback(el, &client->channel.unprocessedDelayed);
62512 }
62513 res = UA_STATUSCODE_GOOD;
62514 break;
62515 }
62516 }
62517 res |= UA_SecureChannel_persistBuffer(channel: &client->channel);
62518
62519 if(res != UA_STATUSCODE_GOOD) {
62520 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62521 msg: "Processing the message returned the error code %s",
62522 UA_StatusCode_name(code: res));
62523
62524 /* If processing the buffer fails before the SecureChannel has opened,
62525 * then the client cannot recover. Set the connectStatus to reflect
62526 * this. The application is notified when the socket has closed. */
62527 if(client->channel.state != UA_SECURECHANNELSTATE_OPEN)
62528 client->connectStatus = res;
62529
62530 /* Close the SecureChannel, but don't notify the client right away.
62531 * Return immediately. notifyClientState will be called in the next
62532 * callback from the ConnectionManager when the connection closes with a
62533 * StatusCode.
62534 *
62535 * If the connectStatus is still good (the SecureChannel was fully
62536 * opened before), then a reconnect is attempted. */
62537 closeSecureChannel(client);
62538 unlockClient(client);
62539 return;
62540 }
62541
62542 continue_connect:
62543 /* Trigger the next action from our end to fully open up the connection */
62544 if(!isFullyConnected(client))
62545 connectActivity(client);
62546 notifyClientState(client);
62547 unlockClient(client);
62548}
62549
62550static void
62551delayedNetworkCallback(void *application, void *context) {
62552 UA_Client *client = (UA_Client*)application;
62553 client->channel.unprocessedDelayed.callback = NULL;
62554 if(client->channel.state >= UA_SECURECHANNELSTATE_CONNECTING)
62555 __Client_networkCallback(cm: client->channel.connectionManager,
62556 connectionId: client->channel.connectionId,
62557 application: client, connectionContext: &context,
62558 state: UA_CONNECTIONSTATE_ESTABLISHED,
62559 params: &UA_KEYVALUEMAP_NULL, msg: UA_BYTESTRING_NULL);
62560}
62561
62562/* Initialize a TCP connection. Writes the result to client->connectStatus. */
62563static void
62564initConnect(UA_Client *client) {
62565 UA_LOCK_ASSERT(&client->clientMutex, 1);
62566 if(client->channel.state != UA_SECURECHANNELSTATE_CLOSED) {
62567 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62568 msg: "Client connection already initiated");
62569 return;
62570 }
62571
62572 /* An exact endpoint was configured. Use it. */
62573 if(!endpointUnconfigured(endpoint: &client->config.endpoint)) {
62574 UA_EndpointDescription_clear(p: &client->endpoint);
62575 client->connectStatus =
62576 UA_EndpointDescription_copy(src: &client->config.endpoint, dst: &client->endpoint);
62577 UA_CHECK_STATUS(client->connectStatus, return);
62578 }
62579
62580 /* Start the EventLoop if not already started */
62581 client->connectStatus = __UA_Client_startup(client);
62582 UA_CHECK_STATUS(client->connectStatus, return);
62583
62584 /* Consistency check the client's own ApplicationURI.
62585 * Problems are only logged. */
62586 verifyClientApplicationURI(client);
62587
62588 /* Initialize the SecureChannel */
62589 UA_SecureChannel_clear(channel: &client->channel);
62590 client->channel.config = client->config.localConnectionConfig;
62591 client->channel.certificateVerification = &client->config.certificateVerification;
62592 client->channel.processOPNHeader = verifyClientSecureChannelHeader;
62593 client->channel.processOPNHeaderApplication = client;
62594
62595 /* Initialize the SecurityPolicy */
62596 client->connectStatus = initSecurityPolicy(client);
62597 if(client->connectStatus != UA_STATUSCODE_GOOD)
62598 return;
62599
62600 /* Extract hostname and port from the URL */
62601 UA_String hostname = UA_STRING_NULL;
62602 UA_String path = UA_STRING_NULL;
62603 UA_UInt16 port = 4840;
62604
62605 client->connectStatus =
62606 UA_parseEndpointUrl(endpointUrl: &client->config.endpointUrl, outHostname: &hostname, outPort: &port, outPath: &path);
62607 if(client->connectStatus != UA_STATUSCODE_GOOD) {
62608 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_NETWORK,
62609 msg: "OPC UA URL is invalid: %.*s",
62610 (int)client->config.endpointUrl.length,
62611 client->config.endpointUrl.data);
62612 return;
62613 }
62614
62615 /* Initialize the TCP connection */
62616 UA_String tcpString = UA_STRING(chars: "tcp");
62617 for(UA_EventSource *es = client->config.eventLoop->eventSources;
62618 es != NULL; es = es->next) {
62619 /* Is this a usable connection manager? */
62620 if(es->eventSourceType != UA_EVENTSOURCETYPE_CONNECTIONMANAGER)
62621 continue;
62622 UA_ConnectionManager *cm = (UA_ConnectionManager*)es;
62623 if(!UA_String_equal(p1: &tcpString, p2: &cm->protocol))
62624 continue;
62625
62626 /* Set up the parameters */
62627 UA_KeyValuePair params[2];
62628 params[0].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "port");
62629 UA_Variant_setScalar(v: &params[0].value, p: &port, type: &UA_TYPES[UA_TYPES_UINT16]);
62630 params[1].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "address");
62631 UA_Variant_setScalar(v: &params[1].value, p: &hostname, type: &UA_TYPES[UA_TYPES_STRING]);
62632
62633 UA_KeyValueMap paramMap;
62634 paramMap.map = params;
62635 paramMap.mapSize = 2;
62636
62637 /* Open the client TCP connection */
62638 UA_StatusCode res = cm->openConnection(cm, &paramMap, client, NULL, __Client_networkCallback);
62639 if(res == UA_STATUSCODE_GOOD)
62640 break;
62641 }
62642
62643 /* The channel has not opened */
62644 if(client->channel.state == UA_SECURECHANNELSTATE_CLOSED)
62645 client->connectStatus = UA_STATUSCODE_BADINTERNALERROR;
62646
62647 /* Opening the TCP connection failed */
62648 if(client->connectStatus != UA_STATUSCODE_GOOD) {
62649 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62650 msg: "Could not open a TCP connection to %.*s",
62651 (int)client->config.endpointUrl.length,
62652 client->config.endpointUrl.data);
62653 client->connectStatus = UA_STATUSCODE_BADCONNECTIONCLOSED;
62654 }
62655}
62656
62657void
62658connectSync(UA_Client *client) {
62659 UA_LOCK_ASSERT(&client->clientMutex, 1);
62660
62661 /* Initialize the connection */
62662 initConnect(client);
62663 notifyClientState(client);
62664 if(client->connectStatus != UA_STATUSCODE_GOOD)
62665 return;
62666
62667 UA_DateTime now = UA_DateTime_nowMonotonic();
62668 UA_DateTime maxDate = now + ((UA_DateTime)client->config.timeout * UA_DATETIME_MSEC);
62669
62670 /* EventLoop is started. Otherwise initConnect would have failed. */
62671 UA_EventLoop *el = client->config.eventLoop;
62672 UA_assert(el);
62673
62674 /* Run the EventLoop until connected, connect fail or timeout. Write the
62675 * iterate result to the connectStatus. So we do not attempt to restore a
62676 * failed connection during the sync connect. */
62677 while(client->connectStatus == UA_STATUSCODE_GOOD &&
62678 !isFullyConnected(client)) {
62679
62680 /* Timeout -> abort */
62681 now = UA_DateTime_nowMonotonic();
62682 if(maxDate < now) {
62683 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62684 msg: "The connection has timed out before it could be fully opened");
62685 client->connectStatus = UA_STATUSCODE_BADTIMEOUT;
62686 closeSecureChannel(client);
62687 /* Continue to run. So the SecureChannel is fully closed in the next
62688 * EventLoop iteration. */
62689 }
62690
62691 /* Drop into the EventLoop */
62692 UA_StatusCode res = el->run(el, (UA_UInt32)((maxDate - now) / UA_DATETIME_MSEC));
62693 if(res != UA_STATUSCODE_GOOD) {
62694 client->connectStatus = res;
62695 closeSecureChannel(client);
62696 }
62697
62698 notifyClientState(client);
62699 }
62700}
62701
62702UA_StatusCode
62703connectInternal(UA_Client *client, UA_Boolean async) {
62704 UA_LOCK_ASSERT(&client->clientMutex, 1);
62705
62706 /* Reset the connectStatus. This should be the only place where we can
62707 * recover from a bad connectStatus. */
62708 client->connectStatus = UA_STATUSCODE_GOOD;
62709
62710 if(async)
62711 initConnect(client);
62712 else
62713 connectSync(client);
62714 notifyClientState(client);
62715 return client->connectStatus;
62716}
62717
62718UA_StatusCode
62719connectSecureChannel(UA_Client *client, const char *endpointUrl) {
62720 UA_LOCK_ASSERT(&client->clientMutex, 1);
62721
62722 UA_ClientConfig *cc = UA_Client_getConfig(client);
62723 cc->noSession = true;
62724 UA_String_clear(p: &cc->endpointUrl);
62725 cc->endpointUrl = UA_STRING_ALLOC(endpointUrl);
62726 return connectInternal(client, false);
62727}
62728
62729UA_StatusCode
62730__UA_Client_connect(UA_Client *client, UA_Boolean async) {
62731 lockClient(client);
62732 connectInternal(client, async);
62733 unlockClient(client);
62734 return client->connectStatus;
62735}
62736
62737static UA_StatusCode
62738activateSessionSync(UA_Client *client) {
62739 UA_LOCK_ASSERT(&client->clientMutex, 1);
62740
62741 UA_DateTime now = UA_DateTime_nowMonotonic();
62742 UA_DateTime maxDate = now + ((UA_DateTime)client->config.timeout * UA_DATETIME_MSEC);
62743
62744 /* Try to activate */
62745 UA_StatusCode res = activateSessionAsync(client);
62746 if(res != UA_STATUSCODE_GOOD)
62747 return res;
62748
62749 /* EventLoop is started. Otherwise activateSessionAsync would have failed. */
62750 UA_EventLoop *el = client->config.eventLoop;
62751 UA_assert(el);
62752 while(client->sessionState != UA_SESSIONSTATE_ACTIVATED &&
62753 client->connectStatus == UA_STATUSCODE_GOOD) {
62754
62755 /* Timeout -> abort */
62756 now = UA_DateTime_nowMonotonic();
62757 if(maxDate < now) {
62758 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62759 msg: "The connection has timed out before it could be fully opened");
62760 client->connectStatus = UA_STATUSCODE_BADTIMEOUT;
62761 closeSecureChannel(client);
62762 /* Continue to run. So the SecureChannel is fully closed in the next
62763 * EventLoop iteration. */
62764 }
62765
62766 /* Drop into the EventLoop */
62767 res = el->run(el, (UA_UInt32)((maxDate - now) / UA_DATETIME_MSEC));
62768 if(res != UA_STATUSCODE_GOOD) {
62769 client->connectStatus = res;
62770 closeSecureChannel(client);
62771 }
62772
62773 notifyClientState(client);
62774 }
62775
62776 return client->connectStatus;
62777}
62778
62779UA_StatusCode
62780UA_Client_activateCurrentSession(UA_Client *client) {
62781 lockClient(client);
62782 UA_StatusCode res = activateSessionSync(client);
62783 notifyClientState(client);
62784 unlockClient(client);
62785 return res != UA_STATUSCODE_GOOD ? res : client->connectStatus;
62786}
62787
62788UA_StatusCode
62789UA_Client_activateCurrentSessionAsync(UA_Client *client) {
62790 lockClient(client);
62791 UA_StatusCode res = activateSessionAsync(client);
62792 notifyClientState(client);
62793 unlockClient(client);
62794 return res != UA_STATUSCODE_GOOD ? res : client->connectStatus;
62795}
62796
62797UA_StatusCode
62798UA_Client_getSessionAuthenticationToken(UA_Client *client, UA_NodeId *authenticationToken,
62799 UA_ByteString *serverNonce) {
62800 lockClient(client);
62801 if(client->sessionState != UA_SESSIONSTATE_CREATED &&
62802 client->sessionState != UA_SESSIONSTATE_ACTIVATED) {
62803 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62804 msg: "There is no current session");
62805 unlockClient(client);
62806 return UA_STATUSCODE_BADSESSIONCLOSED;
62807 }
62808
62809 UA_StatusCode res = UA_NodeId_copy(src: &client->authenticationToken, dst: authenticationToken);
62810 res |= UA_ByteString_copy(src: &client->serverSessionNonce, dst: serverNonce);
62811 unlockClient(client);
62812 return res;
62813}
62814
62815static UA_StatusCode
62816switchSession(UA_Client *client,
62817 const UA_NodeId authenticationToken,
62818 const UA_ByteString serverNonce) {
62819 /* Check that there is no pending session in the client */
62820 if(client->sessionState != UA_SESSIONSTATE_CLOSED) {
62821 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62822 msg: "Cannot activate a session with a different AuthenticationToken "
62823 "when the client already has a Session.");
62824 return UA_STATUSCODE_BADINTERNALERROR;
62825 }
62826
62827 /* Replace token and nonce */
62828 UA_NodeId_clear(p: &client->authenticationToken);
62829 UA_ByteString_clear(p: &client->serverSessionNonce);
62830 UA_StatusCode res = UA_NodeId_copy(src: &authenticationToken, dst: &client->authenticationToken);
62831 res |= UA_ByteString_copy(src: &serverNonce, dst: &client->serverSessionNonce);
62832 if(res != UA_STATUSCODE_GOOD)
62833 return res;
62834
62835 /* Notify that we have now a created session */
62836 client->sessionState = UA_SESSIONSTATE_CREATED;
62837 notifyClientState(client);
62838
62839 return UA_STATUSCODE_GOOD;
62840}
62841
62842UA_StatusCode
62843UA_Client_activateSession(UA_Client *client,
62844 const UA_NodeId authenticationToken,
62845 const UA_ByteString serverNonce) {
62846 lockClient(client);
62847 UA_StatusCode res = switchSession(client, authenticationToken, serverNonce);
62848 if(res != UA_STATUSCODE_GOOD) {
62849 unlockClient(client);
62850 return res;
62851 }
62852 res = activateSessionSync(client);
62853 notifyClientState(client);
62854 unlockClient(client);
62855 return res != UA_STATUSCODE_GOOD ? res : client->connectStatus;
62856}
62857
62858UA_StatusCode
62859UA_Client_activateSessionAsync(UA_Client *client,
62860 const UA_NodeId authenticationToken,
62861 const UA_ByteString serverNonce) {
62862 lockClient(client);
62863 UA_StatusCode res = switchSession(client, authenticationToken, serverNonce);
62864 if(res != UA_STATUSCODE_GOOD) {
62865 unlockClient(client);
62866 return res;
62867 }
62868 res = activateSessionAsync(client);
62869 notifyClientState(client);
62870 unlockClient(client);
62871 return res != UA_STATUSCODE_GOOD ? res : client->connectStatus;
62872}
62873
62874static void
62875disconnectListenSockets(UA_Client *client) {
62876 UA_ConnectionManager *cm = client->reverseConnectionCM;
62877 for(size_t i = 0; i < 16; i++) {
62878 if(client->reverseConnectionIds[i] != 0) {
62879 cm->closeConnection(cm, client->reverseConnectionIds[i]);
62880 }
62881 }
62882}
62883
62884/* ConnectionContext meaning:
62885 * - NULL: New listen connection
62886 * - &client->channel: Established active socket to a server
62887 * - &client->reverseConnectionIds[*] == connectionId: Established listen socket
62888 * - &client->reverseConnectionIds[*] != connectionId: New active socket */
62889static void
62890__Client_reverseConnectCallback(UA_ConnectionManager *cm, uintptr_t connectionId,
62891 void *application, void **connectionContext,
62892 UA_ConnectionState state, const UA_KeyValueMap *params,
62893 UA_ByteString msg) {
62894 UA_Client *client = (UA_Client*)application;
62895 lockClient(client);
62896
62897 if(!*connectionContext) {
62898 /* Store the new listen connection */
62899 size_t i = 0;
62900 for(; i < 16; i++) {
62901 if(client->reverseConnectionIds[i] == 0) {
62902 client->reverseConnectionIds[i] = connectionId;
62903 client->reverseConnectionCM = cm;
62904 *connectionContext = &client->reverseConnectionIds[i];
62905 if(client->channel.state == UA_SECURECHANNELSTATE_CLOSED)
62906 client->channel.state = UA_SECURECHANNELSTATE_REVERSE_LISTENING;
62907 break;
62908 }
62909 }
62910 /* All slots are full, close */
62911 if(i == 16) {
62912 cm->closeConnection(cm, connectionId);
62913 unlockClient(client);
62914 return;
62915 }
62916 } else if(*connectionContext == &client->channel ||
62917 *(uintptr_t*)*connectionContext != connectionId) {
62918 /* Active socket */
62919
62920 /* New active socket */
62921 if(*connectionContext != &client->channel) {
62922 /* The client already has an active connection */
62923 if(client->channel.connectionId) {
62924 cm->closeConnection(cm, connectionId);
62925 unlockClient(client);
62926 return;
62927 }
62928
62929 /* Set the connection the SecureChannel */
62930 client->channel.connectionId = connectionId;
62931 client->channel.connectionManager = cm;
62932 *connectionContext = &client->channel;
62933
62934 /* Don't keep the listen sockets when an active connection is open */
62935 disconnectListenSockets(client);
62936
62937 /* Set the channel state. The notification callback is called within
62938 * __Client_reverseConnectCallback. */
62939 if(client->channel.state == UA_SECURECHANNELSTATE_REVERSE_LISTENING)
62940 client->channel.state = UA_SECURECHANNELSTATE_REVERSE_CONNECTED;
62941 }
62942
62943 /* Handle the active connection in the normal network callback */
62944 unlockClient(client);
62945 __Client_networkCallback(cm, connectionId, application,
62946 connectionContext, state, params, msg);
62947 return;
62948 }
62949
62950 /* Close the listen socket. Was this the last one? */
62951 if(state == UA_CONNECTIONSTATE_CLOSING) {
62952 UA_Byte count = 0;
62953 for(size_t i = 0; i < 16; i++) {
62954 if(client->reverseConnectionIds[i] == connectionId)
62955 client->reverseConnectionIds[i] = 0;
62956 if(client->reverseConnectionIds[i] != 0)
62957 count++;
62958 }
62959 /* The last connection was closed */
62960 if(count == 0 && client->channel.connectionId == 0)
62961 client->channel.state = UA_SECURECHANNELSTATE_CLOSED;
62962 }
62963
62964 notifyClientState(client);
62965 unlockClient(client);
62966}
62967
62968UA_StatusCode
62969UA_Client_startListeningForReverseConnect(UA_Client *client,
62970 const UA_String *listenHostnames,
62971 size_t listenHostnamesLength,
62972 UA_UInt16 port) {
62973 lockClient(client);
62974
62975 if(client->channel.state != UA_SECURECHANNELSTATE_CLOSED) {
62976 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
62977 msg: "Unable to listen for reverse connect while the client "
62978 "is connected or already listening");
62979 unlockClient(client);
62980 return UA_STATUSCODE_BADINVALIDSTATE;
62981 }
62982
62983 const UA_String tcpString = UA_STRING_STATIC("tcp");
62984 UA_StatusCode res = UA_STATUSCODE_BADINTERNALERROR;
62985
62986 client->connectStatus = UA_STATUSCODE_GOOD;
62987 client->channel.renewState = UA_SECURECHANNELRENEWSTATE_NORMAL;
62988
62989 UA_SecureChannel_init(channel: &client->channel);
62990 client->channel.config = client->config.localConnectionConfig;
62991 client->channel.certificateVerification = &client->config.certificateVerification;
62992 client->channel.processOPNHeader = verifyClientSecureChannelHeader;
62993 client->channel.processOPNHeaderApplication = client;
62994 client->channel.connectionId = 0;
62995
62996 client->connectStatus = initSecurityPolicy(client);
62997 if(client->connectStatus != UA_STATUSCODE_GOOD)
62998 return client->connectStatus;
62999
63000 UA_EventLoop *el = client->config.eventLoop;
63001 if(!el) {
63002 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
63003 msg: "No EventLoop configured");
63004 unlockClient(client);
63005 return UA_STATUSCODE_BADINTERNALERROR;
63006 }
63007
63008 if(el->state != UA_EVENTLOOPSTATE_STARTED) {
63009 res = el->start(el);
63010 UA_CHECK_STATUS(res, unlockClient(client); return res);
63011 }
63012
63013 UA_ConnectionManager *cm = NULL;
63014 for(UA_EventSource *es = el->eventSources; es != NULL; es = es->next) {
63015 if(es->eventSourceType != UA_EVENTSOURCETYPE_CONNECTIONMANAGER)
63016 continue;
63017 cm = (UA_ConnectionManager*)es;
63018 if(UA_String_equal(p1: &tcpString, p2: &cm->protocol))
63019 break;
63020 cm = NULL;
63021 }
63022
63023 if(!cm) {
63024 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
63025 msg: "Could not find a TCP connection manager, unable to "
63026 "listen for reverse connect");
63027 unlockClient(client);
63028 return UA_STATUSCODE_BADINTERNALERROR;
63029 }
63030
63031 client->channel.connectionManager = cm;
63032
63033 UA_KeyValuePair params[4];
63034 bool booleanTrue = true;
63035 params[0].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "port");
63036 UA_Variant_setScalar(v: &params[0].value, p: &port, type: &UA_TYPES[UA_TYPES_UINT16]);
63037 params[1].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "address");
63038 UA_Variant_setArray(v: &params[1].value, array: (void *)(uintptr_t)listenHostnames,
63039 arraySize: listenHostnamesLength, type: &UA_TYPES[UA_TYPES_STRING]);
63040 params[2].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "listen");
63041 UA_Variant_setScalar(v: &params[2].value, p: &booleanTrue, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
63042 params[3].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "reuse");
63043 UA_Variant_setScalar(v: &params[3].value, p: &booleanTrue, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
63044
63045 UA_KeyValueMap paramMap;
63046 paramMap.map = params;
63047 paramMap.mapSize = 4;
63048
63049 res = cm->openConnection(cm, &paramMap, client, NULL, __Client_reverseConnectCallback);
63050
63051 /* Opening the TCP connection failed */
63052 if(res != UA_STATUSCODE_GOOD) {
63053 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
63054 msg: "Failed to open a listening TCP socket for reverse connect");
63055 res = UA_STATUSCODE_BADCONNECTIONCLOSED;
63056 }
63057
63058 unlockClient(client);
63059 return res;
63060}
63061
63062/************************/
63063/* Close the Connection */
63064/************************/
63065
63066void
63067closeSecureChannel(UA_Client *client) {
63068 /* If we close SecureChannel when the Session is still active, set to
63069 * created. Otherwise the Session would remain active until the connection
63070 * callback is called for the closing connection. */
63071 if(client->sessionState == UA_SESSIONSTATE_ACTIVATED)
63072 client->sessionState = UA_SESSIONSTATE_CREATED;
63073
63074 /* Prevent recursion */
63075 if(client->channel.state == UA_SECURECHANNELSTATE_CLOSING ||
63076 client->channel.state == UA_SECURECHANNELSTATE_CLOSED)
63077 return;
63078
63079 UA_LOG_DEBUG_CHANNEL(client->config.logging, &client->channel,
63080 "Closing the channel");
63081
63082 disconnectListenSockets(client);
63083
63084 /* Send CLO if the SecureChannel is open */
63085 if(client->channel.state == UA_SECURECHANNELSTATE_OPEN) {
63086 UA_LOG_DEBUG_CHANNEL(client->config.logging, &client->channel,
63087 "Sending the CLO message");
63088
63089 /* Manually set up the header (otherwise done in sendRequest) */
63090 UA_CloseSecureChannelRequest request;
63091 UA_CloseSecureChannelRequest_init(p: &request);
63092 request.requestHeader.requestHandle = ++client->requestHandle;
63093 request.requestHeader.timestamp = UA_DateTime_now();
63094 request.requestHeader.timeoutHint = client->config.timeout;
63095 request.requestHeader.authenticationToken = client->authenticationToken;
63096 UA_SecureChannel_sendSymmetricMessage(channel: &client->channel, requestId: ++client->requestId,
63097 messageType: UA_MESSAGETYPE_CLO, payload: &request,
63098 payloadType: &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]);
63099 }
63100
63101 /* The connection is eventually closed in the next callback from the
63102 * ConnectionManager with the appropriate status code. Don't set the
63103 * connection closed right away! */
63104 UA_SecureChannel_shutdown(channel: &client->channel, shutdownReason: UA_SHUTDOWNREASON_CLOSE);
63105}
63106
63107static void
63108sendCloseSession(UA_Client *client) {
63109 UA_CloseSessionRequest request;
63110 UA_CloseSessionRequest_init(p: &request);
63111 request.deleteSubscriptions = true;
63112 UA_CloseSessionResponse response;
63113 __Client_Service(client, request: &request, requestType: &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST],
63114 response: &response, responseType: &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE]);
63115 UA_CloseSessionRequest_clear(p: &request);
63116 UA_CloseSessionResponse_clear(p: &response);
63117
63118 /* Set after sending the message to prevent immediate reoping during the
63119 * service call */
63120 client->sessionState = UA_SESSIONSTATE_CLOSING;
63121}
63122
63123void
63124cleanupSession(UA_Client *client) {
63125 UA_NodeId_clear(p: &client->authenticationToken);
63126 client->requestHandle = 0;
63127
63128#ifdef UA_ENABLE_SUBSCRIPTIONS
63129 /* We need to clean up the subscriptions */
63130 __Client_Subscriptions_clean(client);
63131#endif
63132
63133 /* Delete outstanding async services */
63134 __Client_AsyncService_removeAll(client, UA_STATUSCODE_BADSESSIONCLOSED);
63135
63136#ifdef UA_ENABLE_SUBSCRIPTIONS
63137 client->currentlyOutStandingPublishRequests = 0;
63138#endif
63139
63140 client->sessionState = UA_SESSIONSTATE_CLOSED;
63141}
63142
63143static void
63144disconnectSecureChannel(UA_Client *client, UA_Boolean sync) {
63145 /* Clean the DiscoveryUrl and endpoint description when the connection is
63146 * explicitly closed */
63147 UA_String_clear(p: &client->discoveryUrl);
63148 UA_EndpointDescription_clear(p: &client->endpoint);
63149
63150 /* Close the SecureChannel */
63151 closeSecureChannel(client);
63152
63153 /* Manually set the status to closed to prevent an automatic reconnection */
63154 if(client->connectStatus == UA_STATUSCODE_GOOD)
63155 client->connectStatus = UA_STATUSCODE_BADCONNECTIONCLOSED;
63156
63157 /* In the synchronous case, loop until the client has actually closed. */
63158 UA_EventLoop *el = client->config.eventLoop;
63159 if(sync && el &&
63160 el->state != UA_EVENTLOOPSTATE_FRESH &&
63161 el->state != UA_EVENTLOOPSTATE_STOPPED) {
63162 while(client->channel.state != UA_SECURECHANNELSTATE_CLOSED) {
63163 el->run(el, 100);
63164 }
63165 }
63166
63167 notifyClientState(client);
63168}
63169
63170UA_StatusCode
63171UA_Client_disconnectSecureChannel(UA_Client *client) {
63172 lockClient(client);
63173 disconnectSecureChannel(client, true);
63174 unlockClient(client);
63175 return UA_STATUSCODE_GOOD;
63176}
63177
63178UA_StatusCode
63179UA_Client_disconnectSecureChannelAsync(UA_Client *client) {
63180 lockClient(client);
63181 disconnectSecureChannel(client, false);
63182 unlockClient(client);
63183 return UA_STATUSCODE_GOOD;
63184}
63185
63186UA_StatusCode
63187UA_Client_disconnect(UA_Client *client) {
63188 lockClient(client);
63189 if(client->sessionState == UA_SESSIONSTATE_ACTIVATED)
63190 sendCloseSession(client);
63191 cleanupSession(client);
63192 disconnectSecureChannel(client, true);
63193 unlockClient(client);
63194 return UA_STATUSCODE_GOOD;
63195}
63196
63197static void
63198closeSessionCallback(UA_Client *client, void *userdata,
63199 UA_UInt32 requestId, void *response) {
63200 lockClient(client);
63201 cleanupSession(client);
63202 disconnectSecureChannel(client, false);
63203 notifyClientState(client);
63204 unlockClient(client);
63205}
63206
63207UA_StatusCode
63208UA_Client_disconnectAsync(UA_Client *client) {
63209 lockClient(client);
63210
63211 if(client->sessionState == UA_SESSIONSTATE_CLOSED ||
63212 client->sessionState == UA_SESSIONSTATE_CLOSING) {
63213 disconnectSecureChannel(client, false);
63214 notifyClientState(client);
63215 unlockClient(client);
63216 return UA_STATUSCODE_GOOD;
63217 }
63218
63219 /* Set before sending the message to prevent recursion */
63220 client->sessionState = UA_SESSIONSTATE_CLOSING;
63221
63222 UA_CloseSessionRequest request;
63223 UA_CloseSessionRequest_init(p: &request);
63224 request.deleteSubscriptions = true;
63225 UA_StatusCode res =
63226 __Client_AsyncService(client, request: &request, requestType: &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST],
63227 callback: (UA_ClientAsyncServiceCallback)closeSessionCallback,
63228 responseType: &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE], NULL, NULL);
63229 if(res != UA_STATUSCODE_GOOD) {
63230 /* Sending the close request failed. Continue to close the connection
63231 * anyway. */
63232 cleanupSession(client);
63233 disconnectSecureChannel(client, false);
63234 }
63235
63236 notifyClientState(client);
63237 unlockClient(client);
63238 return res;
63239}
63240
63241/**** amalgamated original file "/src/client/ua_client_discovery.c" ****/
63242
63243/* This Source Code Form is subject to the terms of the Mozilla Public
63244 * License, v. 2.0. If a copy of the MPL was not distributed with this
63245 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
63246 *
63247 * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
63248 * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB
63249 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
63250 */
63251
63252
63253/* Helper method for additional warnings */
63254void
63255Client_warnEndpointsResult(UA_Client *client,
63256 const UA_GetEndpointsResponse *response,
63257 const UA_String *endpointUrl) {
63258 if(response->endpointsSize == 0) {
63259 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
63260 msg: "The server did not return any endpoints. "
63261 "Did you use the correct endpointUrl?");
63262 return;
63263 }
63264
63265 if(!UA_String_equal(p1: endpointUrl, p2: &response->endpoints[0].endpointUrl) ||
63266 (response->endpoints[0].server.discoveryUrlsSize > 0 &&
63267 !UA_String_equal(p1: endpointUrl, p2: &response->endpoints[0].server.discoveryUrls[0]))) {
63268 UA_String *betterUrl = &response->endpoints[0].endpointUrl;
63269 if(response->endpoints[0].server.discoveryUrlsSize > 0)
63270 betterUrl = &response->endpoints[0].server.discoveryUrls[0];
63271 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
63272 msg: "The server returned Endpoints with a different EndpointUrl %.*s than was "
63273 "used to initialize the connection: %.*s. Some servers require a complete "
63274 "match of the EndpointUrl/DiscoveryUrl (including the path) "
63275 "to return all endpoints.",
63276 (int)betterUrl->length, betterUrl->data,
63277 (int)endpointUrl->length, endpointUrl->data);
63278 }
63279}
63280
63281/* Gets a list of endpoints. Memory is allocated for endpointDescription array */
63282static UA_StatusCode
63283getEndpointsInternal(UA_Client *client, const UA_String endpointUrl,
63284 size_t *endpointDescriptionsSize,
63285 UA_EndpointDescription **endpointDescriptions) {
63286 UA_LOCK_ASSERT(&client->clientMutex, 1);
63287
63288 UA_GetEndpointsRequest request;
63289 UA_GetEndpointsRequest_init(p: &request);
63290 request.requestHeader.timestamp = UA_DateTime_now();
63291 request.requestHeader.timeoutHint = 10000;
63292 // assume the endpointurl outlives the service call
63293 request.endpointUrl = endpointUrl;
63294
63295 UA_GetEndpointsResponse response;
63296 __Client_Service(client, request: &request, requestType: &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST],
63297 response: &response, responseType: &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]);
63298
63299 if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
63300 UA_StatusCode retval = response.responseHeader.serviceResult;
63301 UA_LOG_ERROR(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
63302 msg: "GetEndpointRequest failed with error code %s",
63303 UA_StatusCode_name(code: retval));
63304 UA_GetEndpointsResponse_clear(p: &response);
63305 return retval;
63306 }
63307
63308 *endpointDescriptions = response.endpoints;
63309 *endpointDescriptionsSize = response.endpointsSize;
63310 response.endpoints = NULL;
63311 response.endpointsSize = 0;
63312 UA_GetEndpointsResponse_clear(p: &response);
63313 return UA_STATUSCODE_GOOD;
63314}
63315
63316UA_StatusCode
63317UA_Client_getEndpoints(UA_Client *client, const char *serverUrl,
63318 size_t *endpointDescriptionsSize,
63319 UA_EndpointDescription** endpointDescriptions) {
63320 lockClient(client);
63321
63322 UA_Boolean connected = (client->channel.state == UA_SECURECHANNELSTATE_OPEN);
63323 /* Client is already connected to a different server */
63324 if(connected && strncmp(s1: (const char*)client->config.endpoint.endpointUrl.data, s2: serverUrl,
63325 n: client->config.endpoint.endpointUrl.length) != 0) {
63326 unlockClient(client);
63327 return UA_STATUSCODE_BADINVALIDARGUMENT;
63328 }
63329
63330 UA_StatusCode retval;
63331 const UA_String url = UA_STRING(chars: (char*)(uintptr_t)serverUrl);
63332 if(!connected) {
63333 retval = connectSecureChannel(client, endpointUrl: serverUrl);
63334 if(retval != UA_STATUSCODE_GOOD) {
63335 unlockClient(client);
63336 return retval;
63337 }
63338 }
63339 retval = getEndpointsInternal(client, endpointUrl: url, endpointDescriptionsSize,
63340 endpointDescriptions);
63341 unlockClient(client);
63342
63343 if(!connected)
63344 UA_Client_disconnect(client);
63345 return retval;
63346}
63347
63348UA_StatusCode
63349UA_Client_findServers(UA_Client *client, const char *serverUrl,
63350 size_t serverUrisSize, UA_String *serverUris,
63351 size_t localeIdsSize, UA_String *localeIds,
63352 size_t *registeredServersSize,
63353 UA_ApplicationDescription **registeredServers) {
63354 lockClient(client);
63355 UA_Boolean connected = (client->channel.state == UA_SECURECHANNELSTATE_OPEN);
63356 /* Client is already connected to a different server */
63357 if(connected && strncmp(s1: (const char*)client->config.endpoint.endpointUrl.data, s2: serverUrl,
63358 n: client->config.endpoint.endpointUrl.length) != 0) {
63359 unlockClient(client);
63360 return UA_STATUSCODE_BADINVALIDARGUMENT;
63361 }
63362
63363 UA_StatusCode retval;
63364 if(!connected) {
63365 retval = connectSecureChannel(client, endpointUrl: serverUrl);
63366 if(retval != UA_STATUSCODE_GOOD) {
63367 unlockClient(client);
63368 return retval;
63369 }
63370 }
63371
63372 /* Prepare the request */
63373 UA_FindServersRequest request;
63374 UA_FindServersRequest_init(p: &request);
63375 request.serverUrisSize = serverUrisSize;
63376 request.serverUris = serverUris;
63377 request.localeIdsSize = localeIdsSize;
63378 request.localeIds = localeIds;
63379
63380 /* Send the request */
63381 UA_FindServersResponse response;
63382 __Client_Service(client, request: &request, requestType: &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST],
63383 response: &response, responseType: &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]);
63384
63385 unlockClient(client);
63386
63387 /* Process the response */
63388 retval = response.responseHeader.serviceResult;
63389 if(retval == UA_STATUSCODE_GOOD) {
63390 *registeredServersSize = response.serversSize;
63391 *registeredServers = response.servers;
63392 response.serversSize = 0;
63393 response.servers = NULL;
63394 } else {
63395 *registeredServersSize = 0;
63396 *registeredServers = NULL;
63397 }
63398
63399 /* Clean up */
63400 UA_FindServersResponse_clear(p: &response);
63401 if(!connected)
63402 UA_Client_disconnect(client);
63403 return retval;
63404}
63405
63406UA_StatusCode
63407UA_Client_findServersOnNetwork(UA_Client *client, const char *serverUrl,
63408 UA_UInt32 startingRecordId, UA_UInt32 maxRecordsToReturn,
63409 size_t serverCapabilityFilterSize, UA_String *serverCapabilityFilter,
63410 size_t *serverOnNetworkSize, UA_ServerOnNetwork **serverOnNetwork) {
63411 lockClient(client);
63412
63413 UA_Boolean connected = (client->channel.state == UA_SECURECHANNELSTATE_OPEN);
63414 /* Client is already connected to a different server */
63415 if(connected && strncmp(s1: (const char*)client->config.endpoint.endpointUrl.data, s2: serverUrl,
63416 n: client->config.endpoint.endpointUrl.length) != 0) {
63417 unlockClient(client);
63418 return UA_STATUSCODE_BADINVALIDARGUMENT;
63419 }
63420
63421 UA_StatusCode retval;
63422 if(!connected) {
63423 retval = connectSecureChannel(client, endpointUrl: serverUrl);
63424 if(retval != UA_STATUSCODE_GOOD) {
63425 lockClient(client);
63426 return retval;
63427 }
63428 }
63429
63430 /* Prepare the request */
63431 UA_FindServersOnNetworkRequest request;
63432 UA_FindServersOnNetworkRequest_init(p: &request);
63433 request.startingRecordId = startingRecordId;
63434 request.maxRecordsToReturn = maxRecordsToReturn;
63435 request.serverCapabilityFilterSize = serverCapabilityFilterSize;
63436 request.serverCapabilityFilter = serverCapabilityFilter;
63437
63438 /* Send the request */
63439 UA_FindServersOnNetworkResponse response;
63440 __Client_Service(client, request: &request, requestType: &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST],
63441 response: &response, responseType: &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE]);
63442
63443 unlockClient(client);
63444
63445 /* Process the response */
63446 retval = response.responseHeader.serviceResult;
63447 if(retval == UA_STATUSCODE_GOOD) {
63448 *serverOnNetworkSize = response.serversSize;
63449 *serverOnNetwork = response.servers;
63450 response.serversSize = 0;
63451 response.servers = NULL;
63452 } else {
63453 *serverOnNetworkSize = 0;
63454 *serverOnNetwork = NULL;
63455 }
63456
63457 /* Clean up */
63458 UA_FindServersOnNetworkResponse_clear(p: &response);
63459 if(!connected)
63460 UA_Client_disconnect(client);
63461 return retval;
63462}
63463
63464/**** amalgamated original file "/src/client/ua_client_highlevel.c" ****/
63465
63466/* This Source Code Form is subject to the terms of the Mozilla Public
63467 * License, v. 2.0. If a copy of the MPL was not distributed with this
63468 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
63469 *
63470 * Copyright 2015-2021 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
63471 * Copyright 2015 (c) Oleksiy Vasylyev
63472 * Copyright 2017 (c) Florian Palm
63473 * Copyright 2016 (c) Chris Iatrou
63474 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
63475 * Copyright 2018 (c) Fabian Arndt
63476 * Copyright 2018 (c) Peter Rustler, basyskom GmbH
63477 */
63478
63479
63480/* The highlevel client API is an "outer onion layer". This file does not
63481 * include ua_client_internal.h on purpose. */
63482
63483UA_StatusCode
63484UA_Client_NamespaceGetIndex(UA_Client *client, UA_String *namespaceUri,
63485 UA_UInt16 *namespaceIndex) {
63486 UA_ReadRequest request;
63487 UA_ReadRequest_init(p: &request);
63488 UA_ReadValueId id;
63489 UA_ReadValueId_init(p: &id);
63490 id.attributeId = UA_ATTRIBUTEID_VALUE;
63491 id.nodeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_NAMESPACEARRAY);
63492 request.nodesToRead = &id;
63493 request.nodesToReadSize = 1;
63494
63495 UA_ReadResponse response = UA_Client_Service_read(client, request);
63496
63497 UA_StatusCode retval = UA_STATUSCODE_GOOD;
63498 if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD)
63499 retval = response.responseHeader.serviceResult;
63500 else if(response.resultsSize != 1 || !response.results[0].hasValue)
63501 retval = UA_STATUSCODE_BADNODEATTRIBUTESINVALID;
63502 else if(response.results[0].value.type != &UA_TYPES[UA_TYPES_STRING])
63503 retval = UA_STATUSCODE_BADTYPEMISMATCH;
63504
63505 if(retval != UA_STATUSCODE_GOOD) {
63506 UA_ReadResponse_clear(p: &response);
63507 return retval;
63508 }
63509
63510 retval = UA_STATUSCODE_BADNOTFOUND;
63511 UA_String *ns = (UA_String *)response.results[0].value.data;
63512 for(size_t i = 0; i < response.results[0].value.arrayLength; ++i) {
63513 if(UA_String_equal(p1: namespaceUri, p2: &ns[i])) {
63514 *namespaceIndex = (UA_UInt16)i;
63515 retval = UA_STATUSCODE_GOOD;
63516 break;
63517 }
63518 }
63519
63520 UA_ReadResponse_clear(p: &response);
63521 return retval;
63522}
63523
63524UA_StatusCode
63525UA_Client_forEachChildNodeCall(UA_Client *client, UA_NodeId parentNodeId,
63526 UA_NodeIteratorCallback callback, void *handle) {
63527 UA_BrowseRequest bReq;
63528 UA_BrowseRequest_init(p: &bReq);
63529 bReq.requestedMaxReferencesPerNode = 0;
63530 bReq.nodesToBrowse = UA_BrowseDescription_new();
63531 bReq.nodesToBrowseSize = 1;
63532 UA_NodeId_copy(src: &parentNodeId, dst: &bReq.nodesToBrowse[0].nodeId);
63533 bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; //return everything
63534 bReq.nodesToBrowse[0].browseDirection = UA_BROWSEDIRECTION_BOTH;
63535
63536 UA_BrowseResponse bResp = UA_Client_Service_browse(client, request: bReq);
63537
63538 UA_StatusCode retval = bResp.responseHeader.serviceResult;
63539 if(retval == UA_STATUSCODE_GOOD) {
63540 for(size_t i = 0; i < bResp.resultsSize; ++i) {
63541 for(size_t j = 0; j < bResp.results[i].referencesSize; ++j) {
63542 UA_ReferenceDescription *ref = &bResp.results[i].references[j];
63543 retval |= callback(ref->nodeId.nodeId, !ref->isForward,
63544 ref->referenceTypeId, handle);
63545 }
63546 }
63547 }
63548
63549 UA_BrowseRequest_clear(p: &bReq);
63550 UA_BrowseResponse_clear(p: &bResp);
63551 return retval;
63552}
63553
63554/*******************/
63555/* Node Management */
63556/*******************/
63557
63558UA_StatusCode
63559UA_Client_addReference(UA_Client *client, const UA_NodeId sourceNodeId,
63560 const UA_NodeId referenceTypeId, UA_Boolean isForward,
63561 const UA_String targetServerUri,
63562 const UA_ExpandedNodeId targetNodeId,
63563 UA_NodeClass targetNodeClass) {
63564 UA_AddReferencesItem item;
63565 UA_AddReferencesItem_init(p: &item);
63566 item.sourceNodeId = sourceNodeId;
63567 item.referenceTypeId = referenceTypeId;
63568 item.isForward = isForward;
63569 item.targetServerUri = targetServerUri;
63570 item.targetNodeId = targetNodeId;
63571 item.targetNodeClass = targetNodeClass;
63572 UA_AddReferencesRequest request;
63573 UA_AddReferencesRequest_init(p: &request);
63574 request.referencesToAdd = &item;
63575 request.referencesToAddSize = 1;
63576 UA_AddReferencesResponse response = UA_Client_Service_addReferences(client, request);
63577 UA_StatusCode retval = response.responseHeader.serviceResult;
63578 if(retval != UA_STATUSCODE_GOOD) {
63579 UA_AddReferencesResponse_clear(p: &response);
63580 return retval;
63581 }
63582 if(response.resultsSize != 1) {
63583 UA_AddReferencesResponse_clear(p: &response);
63584 return UA_STATUSCODE_BADUNEXPECTEDERROR;
63585 }
63586 retval = response.results[0];
63587 UA_AddReferencesResponse_clear(p: &response);
63588 return retval;
63589}
63590
63591UA_StatusCode
63592UA_Client_deleteReference(UA_Client *client, const UA_NodeId sourceNodeId,
63593 const UA_NodeId referenceTypeId, UA_Boolean isForward,
63594 const UA_ExpandedNodeId targetNodeId,
63595 UA_Boolean deleteBidirectional) {
63596 UA_DeleteReferencesItem item;
63597 UA_DeleteReferencesItem_init(p: &item);
63598 item.sourceNodeId = sourceNodeId;
63599 item.referenceTypeId = referenceTypeId;
63600 item.isForward = isForward;
63601 item.targetNodeId = targetNodeId;
63602 item.deleteBidirectional = deleteBidirectional;
63603 UA_DeleteReferencesRequest request;
63604 UA_DeleteReferencesRequest_init(p: &request);
63605 request.referencesToDelete = &item;
63606 request.referencesToDeleteSize = 1;
63607 UA_DeleteReferencesResponse response = UA_Client_Service_deleteReferences(client, request);
63608 UA_StatusCode retval = response.responseHeader.serviceResult;
63609 if(retval != UA_STATUSCODE_GOOD) {
63610 UA_DeleteReferencesResponse_clear(p: &response);
63611 return retval;
63612 }
63613 if(response.resultsSize != 1) {
63614 UA_DeleteReferencesResponse_clear(p: &response);
63615 return UA_STATUSCODE_BADUNEXPECTEDERROR;
63616 }
63617 retval = response.results[0];
63618 UA_DeleteReferencesResponse_clear(p: &response);
63619 return retval;
63620}
63621
63622UA_StatusCode
63623UA_Client_deleteNode(UA_Client *client, const UA_NodeId nodeId,
63624 UA_Boolean deleteTargetReferences) {
63625 UA_DeleteNodesItem item;
63626 UA_DeleteNodesItem_init(p: &item);
63627 item.nodeId = nodeId;
63628 item.deleteTargetReferences = deleteTargetReferences;
63629 UA_DeleteNodesRequest request;
63630 UA_DeleteNodesRequest_init(p: &request);
63631 request.nodesToDelete = &item;
63632 request.nodesToDeleteSize = 1;
63633 UA_DeleteNodesResponse response = UA_Client_Service_deleteNodes(client, request);
63634 UA_StatusCode retval = response.responseHeader.serviceResult;
63635 if(retval != UA_STATUSCODE_GOOD) {
63636 UA_DeleteNodesResponse_clear(p: &response);
63637 return retval;
63638 }
63639 if(response.resultsSize != 1) {
63640 UA_DeleteNodesResponse_clear(p: &response);
63641 return UA_STATUSCODE_BADUNEXPECTEDERROR;
63642 }
63643 retval = response.results[0];
63644 UA_DeleteNodesResponse_clear(p: &response);
63645 return retval;
63646}
63647
63648UA_StatusCode
63649__UA_Client_addNode(UA_Client *client, const UA_NodeClass nodeClass,
63650 const UA_NodeId requestedNewNodeId, const UA_NodeId parentNodeId,
63651 const UA_NodeId referenceTypeId, const UA_QualifiedName browseName,
63652 const UA_NodeId typeDefinition, const UA_NodeAttributes *attr,
63653 const UA_DataType *attributeType, UA_NodeId *outNewNodeId) {
63654 UA_AddNodesRequest request;
63655 UA_AddNodesRequest_init(p: &request);
63656 UA_AddNodesItem item;
63657 UA_AddNodesItem_init(p: &item);
63658 item.parentNodeId.nodeId = parentNodeId;
63659 item.referenceTypeId = referenceTypeId;
63660 item.requestedNewNodeId.nodeId = requestedNewNodeId;
63661 item.browseName = browseName;
63662 item.nodeClass = nodeClass;
63663 item.typeDefinition.nodeId = typeDefinition;
63664 item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
63665 item.nodeAttributes.content.decoded.type = attributeType;
63666 item.nodeAttributes.content.decoded.data = (void*)(uintptr_t)attr; // hack. is not written into.
63667 request.nodesToAdd = &item;
63668 request.nodesToAddSize = 1;
63669 UA_AddNodesResponse response = UA_Client_Service_addNodes(client, request);
63670
63671 UA_StatusCode retval = response.responseHeader.serviceResult;
63672 if(retval != UA_STATUSCODE_GOOD) {
63673 UA_AddNodesResponse_clear(p: &response);
63674 return retval;
63675 }
63676
63677 if(response.resultsSize != 1) {
63678 UA_AddNodesResponse_clear(p: &response);
63679 return UA_STATUSCODE_BADUNEXPECTEDERROR;
63680 }
63681
63682 /* Move the id of the created node */
63683 retval = response.results[0].statusCode;
63684 if(retval == UA_STATUSCODE_GOOD && outNewNodeId) {
63685 *outNewNodeId = response.results[0].addedNodeId;
63686 UA_NodeId_init(p: &response.results[0].addedNodeId);
63687 }
63688
63689 UA_AddNodesResponse_clear(p: &response);
63690 return retval;
63691}
63692
63693/********/
63694/* Call */
63695/********/
63696
63697UA_StatusCode
63698UA_Client_call(UA_Client *client, const UA_NodeId objectId,
63699 const UA_NodeId methodId, size_t inputSize,
63700 const UA_Variant *input, size_t *outputSize,
63701 UA_Variant **output) {
63702 /* Set up the request */
63703 UA_CallRequest request;
63704 UA_CallRequest_init(p: &request);
63705 UA_CallMethodRequest item;
63706 UA_CallMethodRequest_init(p: &item);
63707 item.methodId = methodId;
63708 item.objectId = objectId;
63709 item.inputArguments = (UA_Variant *)(void*)(uintptr_t)input; // cast const...
63710 item.inputArgumentsSize = inputSize;
63711 request.methodsToCall = &item;
63712 request.methodsToCallSize = 1;
63713
63714 /* Call the service */
63715 UA_CallResponse response = UA_Client_Service_call(client, request);
63716 UA_StatusCode retval = response.responseHeader.serviceResult;
63717 if(retval == UA_STATUSCODE_GOOD) {
63718 if(response.resultsSize == 1)
63719 retval = response.results[0].statusCode;
63720 else
63721 retval = UA_STATUSCODE_BADUNEXPECTEDERROR;
63722 }
63723 if(UA_StatusCode_isBad(code: retval)) {
63724 UA_CallResponse_clear(p: &response);
63725 return retval;
63726 }
63727
63728 /* Move the output arguments */
63729 if(output != NULL && outputSize != NULL) {
63730 *output = response.results[0].outputArguments;
63731 *outputSize = response.results[0].outputArgumentsSize;
63732 response.results[0].outputArguments = NULL;
63733 response.results[0].outputArgumentsSize = 0;
63734 }
63735 UA_CallResponse_clear(p: &response);
63736 return retval;
63737}
63738
63739/********************/
63740/* Write Attributes */
63741/********************/
63742
63743UA_StatusCode
63744__UA_Client_writeAttribute(UA_Client *client, const UA_NodeId *nodeId,
63745 UA_AttributeId attributeId, const void *in,
63746 const UA_DataType *inDataType) {
63747 if(!in || !inDataType)
63748 return UA_STATUSCODE_BADTYPEMISMATCH;
63749
63750 UA_WriteValue wValue;
63751 UA_WriteValue_init(p: &wValue);
63752 wValue.nodeId = *nodeId;
63753 wValue.attributeId = attributeId;
63754 if(attributeId == UA_ATTRIBUTEID_VALUE &&
63755 inDataType == &UA_TYPES[UA_TYPES_VARIANT]) {
63756 wValue.value.value = *(const UA_Variant*)in;
63757 wValue.value.hasValue = true;
63758 } else if(attributeId == UA_ATTRIBUTEID_VALUE &&
63759 inDataType == &UA_TYPES[UA_TYPES_DATAVALUE]) {
63760 wValue.value = *(const UA_DataValue*)in;
63761 } else {
63762 /* Hack to get rid of the const annotation.
63763 * The value is never written into. */
63764 UA_Variant_setScalar(v: &wValue.value.value, p: (void*)(uintptr_t)in, type: inDataType);
63765 wValue.value.hasValue = true;
63766 }
63767 UA_WriteRequest wReq;
63768 UA_WriteRequest_init(p: &wReq);
63769 wReq.nodesToWrite = &wValue;
63770 wReq.nodesToWriteSize = 1;
63771
63772 UA_WriteResponse wResp = UA_Client_Service_write(client, request: wReq);
63773
63774 UA_StatusCode retval = wResp.responseHeader.serviceResult;
63775 if(retval == UA_STATUSCODE_GOOD) {
63776 if(wResp.resultsSize == 1)
63777 retval = wResp.results[0];
63778 else
63779 retval = UA_STATUSCODE_BADUNEXPECTEDERROR;
63780 }
63781
63782 UA_WriteResponse_clear(p: &wResp);
63783 return retval;
63784}
63785
63786UA_StatusCode
63787UA_Client_writeArrayDimensionsAttribute(UA_Client *client, const UA_NodeId nodeId,
63788 size_t newArrayDimensionsSize,
63789 const UA_UInt32 *newArrayDimensions) {
63790 if(!newArrayDimensions)
63791 return UA_STATUSCODE_BADTYPEMISMATCH;
63792
63793 UA_WriteValue wValue;
63794 UA_WriteValue_init(p: &wValue);
63795 wValue.nodeId = nodeId;
63796 wValue.attributeId = UA_ATTRIBUTEID_ARRAYDIMENSIONS;
63797 UA_Variant_setArray(v: &wValue.value.value, array: (void*)(uintptr_t)newArrayDimensions,
63798 arraySize: newArrayDimensionsSize, type: &UA_TYPES[UA_TYPES_UINT32]);
63799 wValue.value.hasValue = true;
63800 UA_WriteRequest wReq;
63801 UA_WriteRequest_init(p: &wReq);
63802 wReq.nodesToWrite = &wValue;
63803 wReq.nodesToWriteSize = 1;
63804
63805 UA_WriteResponse wResp = UA_Client_Service_write(client, request: wReq);
63806
63807 UA_StatusCode retval = wResp.responseHeader.serviceResult;
63808 if(retval == UA_STATUSCODE_GOOD) {
63809 if(wResp.resultsSize == 1)
63810 retval = wResp.results[0];
63811 else
63812 retval = UA_STATUSCODE_BADUNEXPECTEDERROR;
63813 }
63814 UA_WriteResponse_clear(p: &wResp);
63815 return retval;
63816}
63817
63818/*******************/
63819/* Read Attributes */
63820/*******************/
63821
63822UA_StatusCode
63823__UA_Client_readAttribute(UA_Client *client, const UA_NodeId *nodeId,
63824 UA_AttributeId attributeId, void *out,
63825 const UA_DataType *outDataType) {
63826 UA_ReadValueId item;
63827 UA_ReadValueId_init(p: &item);
63828 item.nodeId = *nodeId;
63829 item.attributeId = attributeId;
63830 UA_ReadRequest request;
63831 UA_ReadRequest_init(p: &request);
63832 request.nodesToRead = &item;
63833 request.nodesToReadSize = 1;
63834 UA_ReadResponse response = UA_Client_Service_read(client, request);
63835 UA_StatusCode retval = response.responseHeader.serviceResult;
63836 if(retval == UA_STATUSCODE_GOOD) {
63837 if(response.resultsSize == 1)
63838 retval = response.results[0].status;
63839 else
63840 retval = UA_STATUSCODE_BADUNEXPECTEDERROR;
63841 }
63842 if(!UA_StatusCode_isEqualTop(s1: retval,UA_STATUSCODE_GOOD)) {
63843 UA_ReadResponse_clear(p: &response);
63844 return retval;
63845 }
63846
63847 /* Set the StatusCode */
63848 UA_DataValue *res = response.results;
63849 if(res->hasStatus)
63850 retval = res->status;
63851
63852 /* Return early of no value is given */
63853 if(!res->hasValue) {
63854 retval = UA_STATUSCODE_BADUNEXPECTEDERROR;
63855 UA_ReadResponse_clear(p: &response);
63856 return retval;
63857 }
63858
63859 /* Copy value into out */
63860 if(attributeId == UA_ATTRIBUTEID_VALUE) {
63861 memcpy(dest: out, src: &res->value, n: sizeof(UA_Variant));
63862 UA_Variant_init(p: &res->value);
63863 } else if(attributeId == UA_ATTRIBUTEID_NODECLASS) {
63864 memcpy(dest: out, src: (UA_NodeClass*)res->value.data, n: sizeof(UA_NodeClass));
63865 } else if(UA_Variant_isScalar(v: &res->value) &&
63866 res->value.type == outDataType) {
63867 memcpy(dest: out, src: res->value.data, n: res->value.type->memSize);
63868 UA_free(ptr: res->value.data);
63869 res->value.data = NULL;
63870 } else {
63871 retval = UA_STATUSCODE_BADUNEXPECTEDERROR;
63872 }
63873
63874 UA_ReadResponse_clear(p: &response);
63875 return retval;
63876}
63877
63878static UA_StatusCode
63879processReadArrayDimensionsResult(UA_ReadResponse *response,
63880 UA_UInt32 **outArrayDimensions,
63881 size_t *outArrayDimensionsSize) {
63882 UA_StatusCode retval = response->responseHeader.serviceResult;
63883 if(retval != UA_STATUSCODE_GOOD)
63884 return retval;
63885
63886 if(response->resultsSize != 1)
63887 return UA_STATUSCODE_BADUNEXPECTEDERROR;
63888
63889 retval = response->results[0].status;
63890 if(!UA_StatusCode_isEqualTop(s1: retval,UA_STATUSCODE_GOOD))
63891 return retval;
63892
63893 UA_DataValue *res = &response->results[0];
63894 if(!res->hasValue ||
63895 UA_Variant_isScalar(v: &res->value) ||
63896 res->value.type != &UA_TYPES[UA_TYPES_UINT32])
63897 return UA_STATUSCODE_BADUNEXPECTEDERROR;
63898
63899 /* Move results */
63900 *outArrayDimensions = (UA_UInt32*)res->value.data;
63901 *outArrayDimensionsSize = res->value.arrayLength;
63902 res->value.data = NULL;
63903 res->value.arrayLength = 0;
63904 return UA_STATUSCODE_GOOD;
63905}
63906
63907UA_StatusCode
63908UA_Client_readArrayDimensionsAttribute(UA_Client *client, const UA_NodeId nodeId,
63909 size_t *outArrayDimensionsSize,
63910 UA_UInt32 **outArrayDimensions) {
63911 UA_ReadValueId item;
63912 UA_ReadValueId_init(p: &item);
63913 item.nodeId = nodeId;
63914 item.attributeId = UA_ATTRIBUTEID_ARRAYDIMENSIONS;
63915 UA_ReadRequest request;
63916 UA_ReadRequest_init(p: &request);
63917 request.nodesToRead = &item;
63918 request.nodesToReadSize = 1;
63919
63920 UA_ReadResponse response = UA_Client_Service_read(client, request);
63921 UA_StatusCode retval = processReadArrayDimensionsResult(response: &response, outArrayDimensions,
63922 outArrayDimensionsSize);
63923 UA_ReadResponse_clear(p: &response);
63924 return retval;
63925}
63926
63927/*********************/
63928/* Historical Access */
63929/*********************/
63930
63931static UA_HistoryReadResponse
63932__UA_Client_HistoryRead(UA_Client *client, const UA_NodeId *nodeId,
63933 UA_ExtensionObject* details, UA_String indexRange,
63934 UA_TimestampsToReturn timestampsToReturn,
63935 UA_ByteString continuationPoint, UA_Boolean releaseConti) {
63936
63937 UA_HistoryReadValueId item;
63938 UA_HistoryReadValueId_init(p: &item);
63939
63940 item.nodeId = *nodeId;
63941 item.indexRange = indexRange;
63942 item.continuationPoint = continuationPoint;
63943 item.dataEncoding = UA_QUALIFIEDNAME(nsIndex: 0, chars: "");
63944
63945 UA_HistoryReadRequest request;
63946 UA_HistoryReadRequest_init(p: &request);
63947
63948 request.nodesToRead = &item;
63949 request.nodesToReadSize = 1;
63950 request.timestampsToReturn = timestampsToReturn; // Defaults to Source
63951 request.releaseContinuationPoints = releaseConti; // No values are returned, if true
63952
63953 /* Build ReadDetails */
63954 request.historyReadDetails = *details;
63955
63956 return UA_Client_Service_historyRead(client, request);
63957}
63958
63959static UA_StatusCode
63960__UA_Client_HistoryRead_service(UA_Client *client, const UA_NodeId *nodeId,
63961 const UA_HistoricalIteratorCallback callback,
63962 UA_ExtensionObject *details, UA_String indexRange,
63963 UA_TimestampsToReturn timestampsToReturn,
63964 void *callbackContext) {
63965
63966 UA_ByteString continuationPoint = UA_BYTESTRING_NULL;
63967 UA_Boolean continuationAvail = false;
63968 UA_Boolean fetchMore = false;
63969 UA_StatusCode retval = UA_STATUSCODE_GOOD;
63970
63971 do {
63972 /* We release the continuation point, if no more data is requested by the user */
63973 UA_Boolean cleanup = !fetchMore && continuationAvail;
63974 UA_HistoryReadResponse response =
63975 __UA_Client_HistoryRead(client, nodeId, details, indexRange, timestampsToReturn, continuationPoint, releaseConti: cleanup);
63976
63977 if(cleanup) {
63978 retval = response.responseHeader.serviceResult;
63979cleanup: UA_HistoryReadResponse_clear(p: &response);
63980 UA_ByteString_clear(p: &continuationPoint);
63981 return retval;
63982 }
63983
63984 retval = response.responseHeader.serviceResult;
63985 if(retval == UA_STATUSCODE_GOOD) {
63986 if(response.resultsSize == 1)
63987 retval = response.results[0].statusCode;
63988 else
63989 retval = UA_STATUSCODE_BADUNEXPECTEDERROR;
63990 }
63991 if(!UA_StatusCode_isEqualTop(s1: retval,UA_STATUSCODE_GOOD))
63992 goto cleanup;
63993
63994 UA_HistoryReadResult *res = response.results;
63995
63996 /* Clear old and check / store new continuation point */
63997 UA_ByteString_clear(p: &continuationPoint);
63998 UA_ByteString_copy(src: &res->continuationPoint, dst: &continuationPoint);
63999 continuationAvail = !UA_ByteString_equal(p1: &continuationPoint, p2: &UA_BYTESTRING_NULL);
64000
64001 /* Client callback with possibility to request further values */
64002 fetchMore = callback(client, nodeId, continuationAvail, &res->historyData, callbackContext);
64003
64004 /* Regular cleanup */
64005 UA_HistoryReadResponse_clear(p: &response);
64006 } while(continuationAvail);
64007
64008 return retval;
64009}
64010
64011UA_StatusCode
64012UA_Client_HistoryRead_events(UA_Client *client, const UA_NodeId *nodeId,
64013 const UA_HistoricalIteratorCallback callback,
64014 UA_DateTime startTime, UA_DateTime endTime,
64015 UA_String indexRange, const UA_EventFilter filter, UA_UInt32 numValuesPerNode,
64016 UA_TimestampsToReturn timestampsToReturn, void *callbackContext) {
64017
64018 UA_ReadEventDetails details;
64019 UA_ReadEventDetails_init(p: &details);
64020 details.filter = filter;
64021
64022 // At least two of the following parameters must be set
64023 details.numValuesPerNode = numValuesPerNode; // 0 = return all / max server is capable of
64024 details.startTime = startTime;
64025 details.endTime = endTime;
64026
64027 UA_ExtensionObject detailsExtensionObject;
64028 UA_ExtensionObject_init(p: &detailsExtensionObject);
64029 detailsExtensionObject.content.decoded.type = &UA_TYPES[UA_TYPES_READEVENTDETAILS];
64030 detailsExtensionObject.content.decoded.data = &details;
64031 detailsExtensionObject.encoding = UA_EXTENSIONOBJECT_DECODED;
64032
64033 return __UA_Client_HistoryRead_service(client, nodeId, callback, details: &detailsExtensionObject,
64034 indexRange, timestampsToReturn, callbackContext);
64035}
64036
64037static UA_StatusCode
64038__UA_Client_HistoryRead_service_rawMod(UA_Client *client, const UA_NodeId *nodeId,
64039 const UA_HistoricalIteratorCallback callback,
64040 UA_DateTime startTime,UA_DateTime endTime,
64041 UA_String indexRange, UA_Boolean returnBounds, UA_UInt32 numValuesPerNode,
64042 UA_Boolean readModified, UA_TimestampsToReturn timestampsToReturn,
64043 void *callbackContext) {
64044
64045 UA_ReadRawModifiedDetails details;
64046 UA_ReadRawModifiedDetails_init(p: &details);
64047 details.isReadModified = readModified; // Return only modified values
64048 details.returnBounds = returnBounds; // Return values pre / post given range
64049
64050 // At least two of the following parameters must be set
64051 details.numValuesPerNode = numValuesPerNode; // 0 = return all / max server is capable of
64052 details.startTime = startTime;
64053 details.endTime = endTime;
64054
64055 UA_ExtensionObject detailsExtensionObject;
64056 UA_ExtensionObject_init(p: &detailsExtensionObject);
64057 detailsExtensionObject.content.decoded.type = &UA_TYPES[UA_TYPES_READRAWMODIFIEDDETAILS];
64058 detailsExtensionObject.content.decoded.data = &details;
64059 detailsExtensionObject.encoding = UA_EXTENSIONOBJECT_DECODED;
64060
64061 return __UA_Client_HistoryRead_service(client, nodeId, callback,
64062 details: &detailsExtensionObject, indexRange,
64063 timestampsToReturn, callbackContext);
64064}
64065
64066UA_StatusCode
64067UA_Client_HistoryRead_raw(UA_Client *client, const UA_NodeId *nodeId,
64068 const UA_HistoricalIteratorCallback callback,
64069 UA_DateTime startTime, UA_DateTime endTime,
64070 UA_String indexRange, UA_Boolean returnBounds, UA_UInt32 numValuesPerNode,
64071 UA_TimestampsToReturn timestampsToReturn, void *callbackContext) {
64072
64073 return __UA_Client_HistoryRead_service_rawMod(client, nodeId, callback, startTime, endTime, indexRange, returnBounds,
64074 numValuesPerNode, false, timestampsToReturn, callbackContext);
64075}
64076
64077UA_StatusCode
64078UA_Client_HistoryRead_modified(UA_Client *client, const UA_NodeId *nodeId,
64079 const UA_HistoricalIteratorCallback callback,
64080 UA_DateTime startTime, UA_DateTime endTime,
64081 UA_String indexRange, UA_Boolean returnBounds, UA_UInt32 maxItems,
64082 UA_TimestampsToReturn timestampsToReturn, void *callbackContext) {
64083 return __UA_Client_HistoryRead_service_rawMod(client, nodeId, callback, startTime,
64084 endTime, indexRange, returnBounds, numValuesPerNode: maxItems,
64085 true, timestampsToReturn, callbackContext);
64086}
64087
64088static UA_HistoryUpdateResponse
64089__UA_Client_HistoryUpdate(UA_Client *client, void *details, size_t typeId) {
64090 UA_HistoryUpdateRequest request;
64091 UA_HistoryUpdateRequest_init(p: &request);
64092
64093 UA_ExtensionObject extension;
64094 UA_ExtensionObject_init(p: &extension);
64095 request.historyUpdateDetailsSize = 1;
64096 request.historyUpdateDetails = &extension;
64097
64098 extension.encoding = UA_EXTENSIONOBJECT_DECODED;
64099 extension.content.decoded.type = &UA_TYPES[typeId];
64100 extension.content.decoded.data = details;
64101
64102 UA_HistoryUpdateResponse response;
64103 response = UA_Client_Service_historyUpdate(client, request);
64104 return response;
64105}
64106
64107static UA_StatusCode
64108__UA_Client_HistoryUpdate_updateData(UA_Client *client, const UA_NodeId *nodeId,
64109 UA_PerformUpdateType type, UA_DataValue *value) {
64110 UA_StatusCode ret = UA_STATUSCODE_GOOD;
64111 UA_UpdateDataDetails details;
64112 UA_UpdateDataDetails_init(p: &details);
64113
64114 details.performInsertReplace = type;
64115 details.updateValuesSize = 1;
64116 details.updateValues = value;
64117 UA_NodeId_copy(src: nodeId, dst: &details.nodeId);
64118
64119 UA_HistoryUpdateResponse response;
64120 response = __UA_Client_HistoryUpdate(client, details: &details, UA_TYPES_UPDATEDATADETAILS);
64121 if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
64122 ret = response.responseHeader.serviceResult;
64123 goto cleanup;
64124 }
64125 if(response.resultsSize != 1 || response.results[0].operationResultsSize != 1) {
64126 ret = UA_STATUSCODE_BADUNEXPECTEDERROR;
64127 goto cleanup;
64128 }
64129 if(response.results[0].statusCode != UA_STATUSCODE_GOOD) {
64130 ret = response.results[0].statusCode;
64131 goto cleanup;
64132 }
64133 ret = response.results[0].operationResults[0];
64134cleanup:
64135 UA_HistoryUpdateResponse_clear(p: &response);
64136 UA_NodeId_clear(p: &details.nodeId);
64137 return ret;
64138}
64139
64140UA_StatusCode
64141UA_Client_HistoryUpdate_insert(UA_Client *client, const UA_NodeId *nodeId,
64142 UA_DataValue *value) {
64143 return __UA_Client_HistoryUpdate_updateData(client, nodeId,
64144 type: UA_PERFORMUPDATETYPE_INSERT,
64145 value);
64146}
64147
64148UA_StatusCode
64149UA_Client_HistoryUpdate_replace(UA_Client *client, const UA_NodeId *nodeId,
64150 UA_DataValue *value) {
64151 return __UA_Client_HistoryUpdate_updateData(client, nodeId,
64152 type: UA_PERFORMUPDATETYPE_REPLACE,
64153 value);
64154}
64155
64156UA_StatusCode
64157UA_Client_HistoryUpdate_update(UA_Client *client, const UA_NodeId *nodeId,
64158 UA_DataValue *value) {
64159 return __UA_Client_HistoryUpdate_updateData(client, nodeId,
64160 type: UA_PERFORMUPDATETYPE_UPDATE,
64161 value);
64162}
64163
64164UA_StatusCode
64165UA_Client_HistoryUpdate_deleteRaw(UA_Client *client, const UA_NodeId *nodeId,
64166 UA_DateTime startTimestamp, UA_DateTime endTimestamp) {
64167 UA_DeleteRawModifiedDetails details;
64168 UA_DeleteRawModifiedDetails_init(p: &details);
64169 details.isDeleteModified = false;
64170 details.startTime = startTimestamp;
64171 details.endTime = endTimestamp;
64172 UA_NodeId_copy(src: nodeId, dst: &details.nodeId);
64173
64174 UA_StatusCode ret = UA_STATUSCODE_GOOD;
64175 UA_HistoryUpdateResponse response;
64176 response = __UA_Client_HistoryUpdate(client, details: &details, UA_TYPES_DELETERAWMODIFIEDDETAILS);
64177 if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
64178 ret = response.responseHeader.serviceResult;
64179 goto cleanup;
64180 }
64181 if(response.resultsSize != 1) {
64182 ret = UA_STATUSCODE_BADUNEXPECTEDERROR;
64183 goto cleanup;
64184 }
64185
64186 ret = response.results[0].statusCode;
64187
64188cleanup:
64189 UA_HistoryUpdateResponse_clear(p: &response);
64190 UA_NodeId_clear(p: &details.nodeId);
64191 return ret;
64192}
64193
64194/*******************/
64195/* Async Functions */
64196/*******************/
64197
64198UA_StatusCode
64199__UA_Client_writeAttribute_async(UA_Client *client, const UA_NodeId *nodeId,
64200 UA_AttributeId attributeId, const void *in,
64201 const UA_DataType *inDataType, UA_ClientAsyncServiceCallback callback,
64202 void *userdata, UA_UInt32 *reqId) {
64203 if(!in)
64204 return UA_STATUSCODE_BADTYPEMISMATCH;
64205
64206 UA_WriteValue wValue;
64207 UA_WriteValue_init(p: &wValue);
64208 wValue.nodeId = *nodeId;
64209 wValue.attributeId = attributeId;
64210 if(attributeId == UA_ATTRIBUTEID_VALUE)
64211 wValue.value.value = *(const UA_Variant*) in;
64212 else
64213 /* hack. is never written into. */
64214 UA_Variant_setScalar(v: &wValue.value.value, p: (void*) (uintptr_t) in,
64215 type: inDataType);
64216 wValue.value.hasValue = true;
64217 UA_WriteRequest wReq;
64218 UA_WriteRequest_init(p: &wReq);
64219 wReq.nodesToWrite = &wValue;
64220 wReq.nodesToWriteSize = 1;
64221
64222 return __UA_Client_AsyncService(client, request: &wReq,
64223 requestType: &UA_TYPES[UA_TYPES_WRITEREQUEST], callback,
64224 responseType: &UA_TYPES[UA_TYPES_WRITERESPONSE], userdata, requestId: reqId);
64225}
64226
64227UA_StatusCode
64228__UA_Client_addNode_async(UA_Client *client, const UA_NodeClass nodeClass,
64229 const UA_NodeId requestedNewNodeId, const UA_NodeId parentNodeId,
64230 const UA_NodeId referenceTypeId, const UA_QualifiedName browseName,
64231 const UA_NodeId typeDefinition, const UA_NodeAttributes *attr,
64232 const UA_DataType *attributeType, UA_NodeId *outNewNodeId,
64233 UA_ClientAsyncServiceCallback callback, void *userdata,
64234 UA_UInt32 *reqId) {
64235 UA_AddNodesRequest request;
64236 UA_AddNodesRequest_init(p: &request);
64237 UA_AddNodesItem item;
64238 UA_AddNodesItem_init(p: &item);
64239 item.parentNodeId.nodeId = parentNodeId;
64240 item.referenceTypeId = referenceTypeId;
64241 item.requestedNewNodeId.nodeId = requestedNewNodeId;
64242 item.browseName = browseName;
64243 item.nodeClass = nodeClass;
64244 item.typeDefinition.nodeId = typeDefinition;
64245 item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
64246 item.nodeAttributes.content.decoded.type = attributeType;
64247 item.nodeAttributes.content.decoded.data = (void*) (uintptr_t) attr; // hack. is not written into.
64248 request.nodesToAdd = &item;
64249 request.nodesToAddSize = 1;
64250
64251 return __UA_Client_AsyncService(client, request: &request,
64252 requestType: &UA_TYPES[UA_TYPES_ADDNODESREQUEST], callback,
64253 responseType: &UA_TYPES[UA_TYPES_ADDNODESRESPONSE], userdata, requestId: reqId);
64254
64255}
64256
64257UA_StatusCode
64258__UA_Client_call_async(UA_Client *client, const UA_NodeId objectId,
64259 const UA_NodeId methodId, size_t inputSize,
64260 const UA_Variant *input, UA_ClientAsyncServiceCallback callback,
64261 void *userdata, UA_UInt32 *reqId) {
64262 UA_CallRequest request;
64263 UA_CallRequest_init(p: &request);
64264 UA_CallMethodRequest item;
64265 UA_CallMethodRequest_init(p: &item);
64266 item.methodId = methodId;
64267 item.objectId = objectId;
64268 item.inputArguments = (UA_Variant *) (void*) (uintptr_t) input; // cast const...
64269 item.inputArgumentsSize = inputSize;
64270 request.methodsToCall = &item;
64271 request.methodsToCallSize = 1;
64272
64273 return __UA_Client_AsyncService(client, request: &request,
64274 requestType: &UA_TYPES[UA_TYPES_CALLREQUEST], callback,
64275 responseType: &UA_TYPES[UA_TYPES_CALLRESPONSE], userdata, requestId: reqId);
64276}
64277
64278/* UA_StatusCode */
64279/* UA_Cient_translateBrowsePathsToNodeIds_async(UA_Client *client, char **paths, */
64280/* UA_UInt32 *ids, size_t pathSize, */
64281/* UA_ClientAsyncTranslateCallback callback, */
64282/* void *userdata, UA_UInt32 *reqId) { */
64283/* return UA_STATUSCODE_BADNOTIMPLEMENTED; */
64284/* } */
64285
64286/*************************/
64287/* Read Single Attribute */
64288/*************************/
64289
64290typedef struct {
64291 UA_ClientAsyncOperationCallback userCallback;
64292 void *userContext;
64293 const UA_DataType *resultType; /* DataValue -> Value attribute,
64294 * Variant -> ArrayDimensions attribute */
64295} UA_AttributeReadContext;
64296
64297static void
64298AttributeReadCallback(UA_Client *client, void *userdata,
64299 UA_UInt32 requestId, UA_ReadResponse *rr) {
64300 UA_AttributeReadContext *ctx = (UA_AttributeReadContext*)userdata;
64301 UA_LOG_DEBUG(logger: UA_Client_getConfig(client)->logging, category: UA_LOGCATEGORY_CLIENT,
64302 msg: "Async read response for request %" PRIu32, requestId);
64303
64304 UA_DataValue *dv = NULL;
64305
64306 /* Check the ServiceResult */
64307 UA_StatusCode res = rr->responseHeader.serviceResult;
64308 if(res != UA_STATUSCODE_GOOD)
64309 goto finish;
64310
64311 /* Check result array size */
64312 if(rr->resultsSize != 1) {
64313 res = UA_STATUSCODE_BADINTERNALERROR;
64314 goto finish;
64315 }
64316
64317 /* A Value attribute */
64318 dv = &rr->results[0];
64319 if(ctx->resultType == &UA_TYPES[UA_TYPES_DATAVALUE]) {
64320 ctx->userCallback(client, ctx->userContext, requestId,
64321 UA_STATUSCODE_GOOD, dv);
64322 goto finish;
64323 }
64324
64325 /* An ArrayDimensions attribute. Has to be an array of UInt32. */
64326 if(ctx->resultType == &UA_TYPES[UA_TYPES_VARIANT]) {
64327 if(dv->hasValue &&
64328 UA_Variant_hasArrayType(v: &dv->value, type: &UA_TYPES[UA_TYPES_UINT32])) {
64329 ctx->userCallback(client, ctx->userContext, requestId,
64330 UA_STATUSCODE_GOOD, &dv->value);
64331 } else {
64332 res = UA_STATUSCODE_BADINTERNALERROR;
64333 }
64334 goto finish;
64335 }
64336
64337 /* Check we have a value */
64338 if(!dv->hasValue) {
64339 res = UA_STATUSCODE_BADINTERNALERROR;
64340 goto finish;
64341 }
64342
64343 /* Check the type. Try to adjust "in situ" if no match. */
64344 if(!UA_Variant_hasScalarType(v: &dv->value, type: ctx->resultType)) {
64345 /* Remember the old pointer, adjustType can "unwrap" a type but won't
64346 * free the wrapper. Because the server code still keeps the wrapper. */
64347 void *oldVal = dv->value.data;
64348 adjustType(value: &dv->value, targetType: ctx->resultType);
64349 if(dv->value.data != oldVal)
64350 UA_free(ptr: oldVal);
64351 if(!UA_Variant_hasScalarType(v: &dv->value, type: ctx->resultType)) {
64352 res = UA_STATUSCODE_BADINTERNALERROR;
64353 goto finish;
64354 }
64355 }
64356
64357 /* Callback into userland */
64358 ctx->userCallback(client, ctx->userContext, requestId,
64359 UA_STATUSCODE_GOOD, dv->value.data);
64360
64361 finish:
64362 if(res != UA_STATUSCODE_GOOD)
64363 ctx->userCallback(client, ctx->userContext, requestId, res, NULL);
64364 UA_free(ptr: ctx);
64365}
64366
64367static UA_StatusCode
64368readAttribute_async(UA_Client *client, const UA_ReadValueId *rvi,
64369 UA_TimestampsToReturn timestampsToReturn,
64370 const UA_DataType *resultType, /* For the specialized reads */
64371 UA_ClientAsyncOperationCallback callback,
64372 void *userdata, UA_UInt32 *requestId) {
64373 UA_AttributeReadContext *ctx = (UA_AttributeReadContext*)
64374 UA_malloc(size: sizeof(UA_AttributeReadContext));
64375 if(!ctx)
64376 return UA_STATUSCODE_BADOUTOFMEMORY;
64377
64378 ctx->userCallback = callback;
64379 ctx->userContext = userdata;
64380 ctx->resultType = resultType;
64381
64382 UA_ReadRequest request;
64383 UA_ReadRequest_init(p: &request);
64384 request.nodesToRead = (UA_ReadValueId*)(uintptr_t)rvi; /* hack, treated as const */
64385 request.nodesToReadSize = 1;
64386 request.timestampsToReturn = timestampsToReturn;
64387
64388 UA_StatusCode res =
64389 __UA_Client_AsyncService(client, request: &request, requestType: &UA_TYPES[UA_TYPES_READREQUEST],
64390 callback: (UA_ClientAsyncServiceCallback)AttributeReadCallback,
64391 responseType: &UA_TYPES[UA_TYPES_READRESPONSE], userdata: ctx, requestId);
64392 if(res != UA_STATUSCODE_GOOD)
64393 UA_free(ptr: ctx);
64394 return res;
64395}
64396
64397UA_StatusCode
64398UA_Client_readAttribute_async(UA_Client *client, const UA_ReadValueId *rvi,
64399 UA_TimestampsToReturn timestampsToReturn,
64400 UA_ClientAsyncReadAttributeCallback callback,
64401 void *userdata, UA_UInt32 *requestId) {
64402 return readAttribute_async(client, rvi, timestampsToReturn,
64403 resultType: &UA_TYPES[UA_TYPES_DATAVALUE], /* special handling */
64404 callback: (UA_ClientAsyncOperationCallback)callback,
64405 userdata, requestId);
64406}
64407
64408/* Helper to keep the code short */
64409static UA_StatusCode
64410readAttribute_simpleAsync(UA_Client *client, const UA_NodeId *nodeId,
64411 UA_AttributeId attributeId, const UA_DataType *resultType,
64412 UA_ClientAsyncOperationCallback callback,
64413 void *userdata, UA_UInt32 *requestId) {
64414 UA_ReadValueId rvi;
64415 UA_ReadValueId_init(p: &rvi);
64416 rvi.nodeId = *nodeId;
64417 rvi.attributeId = attributeId;
64418 return readAttribute_async(client, rvi: &rvi, timestampsToReturn: UA_TIMESTAMPSTORETURN_NEITHER,
64419 resultType, callback, userdata, requestId);
64420}
64421
64422UA_StatusCode
64423UA_Client_readValueAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64424 UA_ClientAsyncReadValueAttributeCallback callback,
64425 void *userdata, UA_UInt32 *requestId) {
64426 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_VALUE,
64427 resultType: &UA_TYPES[UA_TYPES_DATAVALUE], /* special hndling */
64428 callback: (UA_ClientAsyncOperationCallback)callback,
64429 userdata, requestId);
64430}
64431
64432UA_StatusCode
64433UA_Client_readDataTypeAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64434 UA_ClientAsyncReadDataTypeAttributeCallback callback,
64435 void *userdata, UA_UInt32 *requestId) {
64436 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_DATATYPE,
64437 resultType: &UA_TYPES[UA_TYPES_NODEID],
64438 callback: (UA_ClientAsyncOperationCallback)callback,
64439 userdata, requestId);
64440}
64441
64442UA_StatusCode
64443UA_Client_readArrayDimensionsAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64444 UA_ClientReadArrayDimensionsAttributeCallback callback,
64445 void *userdata, UA_UInt32 *requestId) {
64446 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_ARRAYDIMENSIONS,
64447 resultType: &UA_TYPES[UA_TYPES_VARIANT], /* special handling */
64448 callback: (UA_ClientAsyncOperationCallback)callback,
64449 userdata, requestId);
64450}
64451
64452UA_StatusCode
64453UA_Client_readNodeClassAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64454 UA_ClientAsyncReadNodeClassAttributeCallback callback,
64455 void *userdata, UA_UInt32 *requestId) {
64456 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_NODECLASS,
64457 resultType: &UA_TYPES[UA_TYPES_NODECLASS],
64458 callback: (UA_ClientAsyncOperationCallback)callback,
64459 userdata, requestId);
64460}
64461
64462UA_StatusCode
64463UA_Client_readBrowseNameAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64464 UA_ClientAsyncReadBrowseNameAttributeCallback callback,
64465 void *userdata, UA_UInt32 *requestId) {
64466 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_BROWSENAME,
64467 resultType: &UA_TYPES[UA_TYPES_QUALIFIEDNAME],
64468 callback: (UA_ClientAsyncOperationCallback)callback,
64469 userdata, requestId);
64470}
64471
64472UA_StatusCode
64473UA_Client_readDisplayNameAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64474 UA_ClientAsyncReadDisplayNameAttributeCallback callback,
64475 void *userdata, UA_UInt32 *requestId) {
64476 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_DISPLAYNAME,
64477 resultType: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT],
64478 callback: (UA_ClientAsyncOperationCallback)callback,
64479 userdata, requestId);
64480}
64481
64482UA_StatusCode
64483UA_Client_readDescriptionAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64484 UA_ClientAsyncReadDescriptionAttributeCallback callback,
64485 void *userdata, UA_UInt32 *requestId) {
64486 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_DESCRIPTION,
64487 resultType: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT],
64488 callback: (UA_ClientAsyncOperationCallback)callback,
64489 userdata, requestId);
64490}
64491
64492UA_StatusCode
64493UA_Client_readWriteMaskAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64494 UA_ClientAsyncReadWriteMaskAttributeCallback callback,
64495 void *userdata, UA_UInt32 *requestId) {
64496 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_WRITEMASK,
64497 resultType: &UA_TYPES[UA_TYPES_UINT32],
64498 callback: (UA_ClientAsyncOperationCallback)callback,
64499 userdata, requestId);
64500}
64501
64502UA_StatusCode UA_EXPORT
64503UA_Client_readUserWriteMaskAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64504 UA_ClientAsyncReadUserWriteMaskAttributeCallback callback,
64505 void *userdata, UA_UInt32 *requestId) {
64506 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_USERWRITEMASK,
64507 resultType: &UA_TYPES[UA_TYPES_UINT32],
64508 callback: (UA_ClientAsyncOperationCallback)callback,
64509 userdata, requestId);
64510}
64511
64512UA_StatusCode
64513UA_Client_readIsAbstractAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64514 UA_ClientAsyncReadIsAbstractAttributeCallback callback,
64515 void *userdata, UA_UInt32 *requestId) {
64516 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_ISABSTRACT,
64517 resultType: &UA_TYPES[UA_TYPES_BOOLEAN],
64518 callback: (UA_ClientAsyncOperationCallback)callback,
64519 userdata, requestId);
64520}
64521
64522UA_StatusCode
64523UA_Client_readSymmetricAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64524 UA_ClientAsyncReadSymmetricAttributeCallback callback,
64525 void *userdata, UA_UInt32 *requestId) {
64526 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_SYMMETRIC,
64527 resultType: &UA_TYPES[UA_TYPES_BOOLEAN],
64528 callback: (UA_ClientAsyncOperationCallback)callback,
64529 userdata, requestId);
64530}
64531
64532UA_StatusCode
64533UA_Client_readInverseNameAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64534 UA_ClientAsyncReadInverseNameAttributeCallback callback,
64535 void *userdata, UA_UInt32 *requestId) {
64536 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_INVERSENAME,
64537 resultType: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT],
64538 callback: (UA_ClientAsyncOperationCallback)callback,
64539 userdata, requestId);
64540}
64541
64542UA_StatusCode
64543UA_Client_readContainsNoLoopsAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64544 UA_ClientAsyncReadContainsNoLoopsAttributeCallback callback,
64545 void *userdata, UA_UInt32 *requestId) {
64546 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_CONTAINSNOLOOPS,
64547 resultType: &UA_TYPES[UA_TYPES_BOOLEAN],
64548 callback: (UA_ClientAsyncOperationCallback)callback,
64549 userdata, requestId);
64550}
64551
64552UA_StatusCode
64553UA_Client_readEventNotifierAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64554 UA_ClientAsyncReadEventNotifierAttributeCallback callback,
64555 void *userdata, UA_UInt32 *requestId) {
64556 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_EVENTNOTIFIER,
64557 resultType: &UA_TYPES[UA_TYPES_BYTE],
64558 callback: (UA_ClientAsyncOperationCallback)callback,
64559 userdata, requestId);
64560}
64561
64562UA_StatusCode
64563UA_Client_readValueRankAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64564 UA_ClientAsyncReadValueRankAttributeCallback callback,
64565 void *userdata, UA_UInt32 *requestId) {
64566 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_VALUERANK,
64567 resultType: &UA_TYPES[UA_TYPES_INT32],
64568 callback: (UA_ClientAsyncOperationCallback)callback,
64569 userdata, requestId);
64570}
64571
64572UA_StatusCode
64573UA_Client_readAccessLevelAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64574 UA_ClientAsyncReadAccessLevelAttributeCallback callback,
64575 void *userdata, UA_UInt32 *requestId) {
64576 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_ACCESSLEVEL,
64577 resultType: &UA_TYPES[UA_TYPES_BYTE],
64578 callback: (UA_ClientAsyncOperationCallback)callback,
64579 userdata, requestId);
64580}
64581
64582UA_StatusCode
64583UA_Client_readAccessLevelExAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64584 UA_ClientAsyncReadAccessLevelExAttributeCallback callback,
64585 void *userdata, UA_UInt32 *requestId) {
64586 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_ACCESSLEVELEX,
64587 resultType: &UA_TYPES[UA_TYPES_UINT32],
64588 callback: (UA_ClientAsyncOperationCallback)callback,
64589 userdata, requestId);
64590}
64591
64592UA_StatusCode
64593UA_Client_readUserAccessLevelAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64594 UA_ClientAsyncReadUserAccessLevelAttributeCallback callback,
64595 void *userdata, UA_UInt32 *requestId) {
64596 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_USERACCESSLEVEL,
64597 resultType: &UA_TYPES[UA_TYPES_BYTE],
64598 callback: (UA_ClientAsyncOperationCallback)callback,
64599 userdata, requestId);
64600}
64601
64602UA_StatusCode
64603UA_Client_readMinimumSamplingIntervalAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64604 UA_ClientAsyncReadMinimumSamplingIntervalAttributeCallback callback,
64605 void *userdata, UA_UInt32 *requestId) {
64606 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL,
64607 resultType: &UA_TYPES[UA_TYPES_DOUBLE],
64608 callback: (UA_ClientAsyncOperationCallback)callback,
64609 userdata, requestId);
64610}
64611
64612UA_StatusCode
64613UA_Client_readHistorizingAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64614 UA_ClientAsyncReadHistorizingAttributeCallback callback,
64615 void *userdata, UA_UInt32 *requestId) {
64616 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_HISTORIZING,
64617 resultType: &UA_TYPES[UA_TYPES_BOOLEAN],
64618 callback: (UA_ClientAsyncOperationCallback)callback,
64619 userdata, requestId);
64620}
64621
64622UA_StatusCode
64623UA_Client_readExecutableAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64624 UA_ClientAsyncReadExecutableAttributeCallback callback,
64625 void *userdata, UA_UInt32 *requestId) {
64626 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_EXECUTABLE,
64627 resultType: &UA_TYPES[UA_TYPES_BOOLEAN],
64628 callback: (UA_ClientAsyncOperationCallback)callback,
64629 userdata, requestId);
64630}
64631
64632UA_StatusCode
64633UA_Client_readUserExecutableAttribute_async(UA_Client *client, const UA_NodeId nodeId,
64634 UA_ClientAsyncReadUserExecutableAttributeCallback callback,
64635 void *userdata, UA_UInt32 *requestId) {
64636 return readAttribute_simpleAsync(client, nodeId: &nodeId, attributeId: UA_ATTRIBUTEID_USEREXECUTABLE,
64637 resultType: &UA_TYPES[UA_TYPES_BOOLEAN],
64638 callback: (UA_ClientAsyncOperationCallback)callback,
64639 userdata, requestId);
64640}
64641
64642/**** amalgamated original file "/src/client/ua_client_subscriptions.c" ****/
64643
64644/* This Source Code Form is subject to the terms of the Mozilla Public
64645 * License, v. 2.0. If a copy of the MPL was not distributed with this
64646 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
64647 *
64648 * Copyright 2015-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
64649 * Copyright 2015 (c) Oleksiy Vasylyev
64650 * Copyright 2016 (c) Sten Grüner
64651 * Copyright 2017-2018 (c) Thomas Stalder, Blue Time Concept SA
64652 * Copyright 2016-2017 (c) Florian Palm
64653 * Copyright 2017 (c) Frank Meerkötter
64654 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
64655 */
64656
64657
64658
64659struct UA_Client_MonitoredItem_ForDelete {
64660 UA_Client *client;
64661 UA_Client_Subscription *sub;
64662 UA_UInt32 *monitoredItemId;
64663};
64664
64665/*****************/
64666/* Subscriptions */
64667/*****************/
64668
64669static enum ZIP_CMP
64670/* For ZIP_TREE we use clientHandle comparison */
64671UA_ClientHandle_cmp(const void *a, const void *b) {
64672 const UA_Client_MonitoredItem *aa = (const UA_Client_MonitoredItem *)a;
64673 const UA_Client_MonitoredItem *bb = (const UA_Client_MonitoredItem *)b;
64674
64675 /* Compare clientHandle */
64676 if(aa->clientHandle < bb->clientHandle) {
64677 return ZIP_CMP_LESS;
64678 }
64679 if(aa->clientHandle > bb->clientHandle) {
64680 return ZIP_CMP_MORE;
64681 }
64682
64683 return ZIP_CMP_EQ;
64684}
64685
64686ZIP_FUNCTIONS(MonitorItemsTree, UA_Client_MonitoredItem, zipfields,
64687 UA_Client_MonitoredItem, zipfields, UA_ClientHandle_cmp)
64688
64689static void
64690MonitoredItem_delete(UA_Client *client, UA_Client_Subscription *sub,
64691 UA_Client_MonitoredItem *mon);
64692
64693static void
64694ua_Subscriptions_create(UA_Client *client, UA_Client_Subscription *newSub,
64695 UA_CreateSubscriptionResponse *response) {
64696 UA_LOCK_ASSERT(&client->clientMutex, 1);
64697
64698 newSub->subscriptionId = response->subscriptionId;
64699 newSub->sequenceNumber = 0;
64700 newSub->lastActivity = UA_DateTime_nowMonotonic();
64701 newSub->publishingInterval = response->revisedPublishingInterval;
64702 newSub->maxKeepAliveCount = response->revisedMaxKeepAliveCount;
64703 ZIP_INIT(&newSub->monitoredItems);
64704 LIST_INSERT_HEAD(&client->subscriptions, newSub, listEntry);
64705
64706 /* Immediately send the first publish requests if there are none
64707 * outstanding */
64708 __Client_Subscriptions_backgroundPublish(client);
64709}
64710
64711static void
64712ua_Subscriptions_create_handler(UA_Client *client, void *data,
64713 UA_UInt32 requestId, void *r) {
64714 UA_LOCK_ASSERT(&client->clientMutex, 1);
64715
64716 UA_CreateSubscriptionResponse *response = (UA_CreateSubscriptionResponse *)r;
64717 CustomCallback *cc = (CustomCallback *)data;
64718 UA_Client_Subscription *newSub = (UA_Client_Subscription *)cc->clientData;
64719 if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
64720 UA_free(ptr: newSub);
64721 goto cleanup;
64722 }
64723
64724 /* Prepare the internal representation */
64725 ua_Subscriptions_create(client, newSub, response);
64726
64727cleanup:
64728 if(cc->userCallback)
64729 cc->userCallback(client, cc->userData, requestId, response);
64730 UA_free(ptr: cc);
64731}
64732
64733UA_CreateSubscriptionResponse
64734UA_Client_Subscriptions_create(UA_Client *client,
64735 const UA_CreateSubscriptionRequest request,
64736 void *subscriptionContext,
64737 UA_Client_StatusChangeNotificationCallback statusChangeCallback,
64738 UA_Client_DeleteSubscriptionCallback deleteCallback) {
64739 lockClient(client);
64740
64741 UA_CreateSubscriptionResponse response;
64742 UA_Client_Subscription *sub = (UA_Client_Subscription *)
64743 UA_malloc(size: sizeof(UA_Client_Subscription));
64744 if(!sub) {
64745 UA_CreateSubscriptionResponse_init(p: &response);
64746 response.responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
64747 unlockClient(client);
64748 return response;
64749 }
64750 sub->context = subscriptionContext;
64751 sub->statusChangeCallback = statusChangeCallback;
64752 sub->deleteCallback = deleteCallback;
64753
64754 /* Send the request as a synchronous service call */
64755 __Client_Service(client, request: &request, requestType: &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST],
64756 response: &response, responseType: &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE]);
64757 if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
64758 UA_free(ptr: sub);
64759 unlockClient(client);
64760 return response;
64761 }
64762
64763 ua_Subscriptions_create(client, newSub: sub, response: &response);
64764
64765 unlockClient(client);
64766 return response;
64767}
64768
64769UA_StatusCode
64770UA_Client_Subscriptions_create_async(UA_Client *client,
64771 const UA_CreateSubscriptionRequest request,
64772 void *subscriptionContext,
64773 UA_Client_StatusChangeNotificationCallback statusChangeCallback,
64774 UA_Client_DeleteSubscriptionCallback deleteCallback,
64775 UA_ClientAsyncServiceCallback createCallback,
64776 void *userdata,
64777 UA_UInt32 *requestId) {
64778 CustomCallback *cc = (CustomCallback *)UA_calloc(nmemb: 1, size: sizeof(CustomCallback));
64779 if(!cc)
64780 return UA_STATUSCODE_BADOUTOFMEMORY;
64781
64782 UA_Client_Subscription *sub = (UA_Client_Subscription *)
64783 UA_malloc(size: sizeof(UA_Client_Subscription));
64784 if(!sub) {
64785 UA_free(ptr: cc);
64786 return UA_STATUSCODE_BADOUTOFMEMORY;
64787 }
64788 sub->context = subscriptionContext;
64789 sub->statusChangeCallback = statusChangeCallback;
64790 sub->deleteCallback = deleteCallback;
64791
64792 cc->userCallback = createCallback;
64793 cc->userData = userdata;
64794 cc->clientData = sub;
64795
64796 /* Send the request as asynchronous service call */
64797 return __UA_Client_AsyncService(client, request: &request, requestType: &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST],
64798 callback: ua_Subscriptions_create_handler, responseType: &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE],
64799 userdata: cc, requestId);
64800}
64801
64802static UA_Client_Subscription *
64803findSubscription(const UA_Client *client, UA_UInt32 subscriptionId) {
64804 UA_Client_Subscription *sub = NULL;
64805 LIST_FOREACH(sub, &client->subscriptions, listEntry) {
64806 if(sub->subscriptionId == subscriptionId)
64807 break;
64808 }
64809 return sub;
64810}
64811
64812static void
64813ua_Subscriptions_modify(UA_Client *client, UA_Client_Subscription *sub,
64814 const UA_ModifySubscriptionResponse *response) {
64815 sub->publishingInterval = response->revisedPublishingInterval;
64816 sub->maxKeepAliveCount = response->revisedMaxKeepAliveCount;
64817}
64818
64819static void
64820ua_Subscriptions_modify_handler(UA_Client *client, void *data, UA_UInt32 requestId,
64821 void *r) {
64822 UA_LOCK_ASSERT(&client->clientMutex, 1);
64823
64824 UA_ModifySubscriptionResponse *response = (UA_ModifySubscriptionResponse *)r;
64825 CustomCallback *cc = (CustomCallback *)data;
64826 UA_Client_Subscription *sub = findSubscription(client, subscriptionId: (UA_UInt32)(uintptr_t)cc->clientData);
64827 if(sub) {
64828 ua_Subscriptions_modify(client, sub, response);
64829 } else {
64830 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
64831 msg: "No internal representation of subscription %" PRIu32,
64832 (UA_UInt32)(uintptr_t)cc->clientData);
64833 }
64834
64835 if(cc->userCallback)
64836 cc->userCallback(client, cc->userData, requestId, response);
64837 UA_free(ptr: cc);
64838}
64839
64840UA_ModifySubscriptionResponse
64841UA_Client_Subscriptions_modify(UA_Client *client,
64842 const UA_ModifySubscriptionRequest request) {
64843 UA_ModifySubscriptionResponse response;
64844 UA_ModifySubscriptionResponse_init(p: &response);
64845
64846 /* Find the internal representation */
64847 lockClient(client);
64848 UA_Client_Subscription *sub = findSubscription(client, subscriptionId: request.subscriptionId);
64849 if(!sub) {
64850 unlockClient(client);
64851 response.responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
64852 return response;
64853 }
64854
64855 /* Call the service */
64856 __Client_Service(client,
64857 request: &request, requestType: &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST],
64858 response: &response, responseType: &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE]);
64859
64860 /* Adjust the internal representation. Lookup again for thread-safety. */
64861 sub = findSubscription(client, subscriptionId: request.subscriptionId);
64862 if(!sub) {
64863 response.responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
64864 unlockClient(client);
64865 return response;
64866 }
64867 ua_Subscriptions_modify(client, sub, response: &response);
64868 unlockClient(client);
64869 return response;
64870}
64871
64872UA_StatusCode
64873UA_Client_Subscriptions_modify_async(UA_Client *client,
64874 const UA_ModifySubscriptionRequest request,
64875 UA_ClientAsyncServiceCallback callback,
64876 void *userdata, UA_UInt32 *requestId) {
64877 lockClient(client);
64878
64879 /* Find the internal representation */
64880 UA_Client_Subscription *sub = findSubscription(client, subscriptionId: request.subscriptionId);
64881 if(!sub) {
64882 unlockClient(client);
64883 return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
64884 }
64885
64886 CustomCallback *cc = (CustomCallback *)UA_calloc(nmemb: 1, size: sizeof(CustomCallback));
64887 if(!cc) {
64888 unlockClient(client);
64889 return UA_STATUSCODE_BADOUTOFMEMORY;
64890 }
64891
64892 cc->clientData = (void *)(uintptr_t)request.subscriptionId;
64893 cc->userData = userdata;
64894 cc->userCallback = callback;
64895
64896 UA_StatusCode res =
64897 __Client_AsyncService(client, request: &request, requestType: &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST],
64898 callback: ua_Subscriptions_modify_handler, responseType: &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE],
64899 userdata: cc, requestId);
64900
64901 unlockClient(client);
64902 return res;
64903}
64904
64905static void *
64906UA_MonitoredItem_delete_wrapper(void *data, UA_Client_MonitoredItem *mon) {
64907 struct UA_Client_MonitoredItem_ForDelete *deleteMonitoredItem =
64908 (struct UA_Client_MonitoredItem_ForDelete *)data;
64909 if(deleteMonitoredItem != NULL) {
64910 if(deleteMonitoredItem->monitoredItemId != NULL &&
64911 (mon->monitoredItemId != *deleteMonitoredItem->monitoredItemId)) {
64912 return NULL;
64913 }
64914 MonitoredItem_delete(client: deleteMonitoredItem->client, sub: deleteMonitoredItem->sub, mon);
64915 }
64916 return NULL;
64917}
64918
64919static void
64920__Client_Subscription_deleteInternal(UA_Client *client,
64921 UA_Client_Subscription *sub) {
64922 /* Remove the MonitoredItems */
64923 struct UA_Client_MonitoredItem_ForDelete deleteMonitoredItem;
64924 memset(s: &deleteMonitoredItem, c: 0, n: sizeof(struct UA_Client_MonitoredItem_ForDelete));
64925 deleteMonitoredItem.client = client;
64926 deleteMonitoredItem.sub = sub;
64927 ZIP_ITER(MonitorItemsTree, &sub->monitoredItems,
64928 UA_MonitoredItem_delete_wrapper, &deleteMonitoredItem);
64929
64930 /* Call the delete callback */
64931 if(sub->deleteCallback) {
64932 void *subC = sub->context;
64933 UA_UInt32 subId = sub->subscriptionId;
64934 sub->deleteCallback(client, subId, subC);
64935 }
64936
64937 /* Remove */
64938 LIST_REMOVE(sub, listEntry);
64939 UA_free(ptr: sub);
64940}
64941
64942static void
64943__Client_Subscription_processDelete(UA_Client *client,
64944 const UA_DeleteSubscriptionsRequest *request,
64945 const UA_DeleteSubscriptionsResponse *response) {
64946 if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
64947 return;
64948
64949 /* Check that the request and response size -- use the same index for both */
64950 if(request->subscriptionIdsSize != response->resultsSize)
64951 return;
64952
64953 for(size_t i = 0; i < request->subscriptionIdsSize; i++) {
64954 if(response->results[i] != UA_STATUSCODE_GOOD &&
64955 response->results[i] != UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID)
64956 continue;
64957
64958 /* Get the Subscription */
64959 UA_Client_Subscription *sub =
64960 findSubscription(client, subscriptionId: request->subscriptionIds[i]);
64961 if(!sub) {
64962 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
64963 msg: "No internal representation of subscription %" PRIu32,
64964 request->subscriptionIds[i]);
64965 continue;
64966 }
64967
64968 /* Delete the Subscription */
64969 __Client_Subscription_deleteInternal(client, sub);
64970 }
64971}
64972
64973typedef struct {
64974 UA_DeleteSubscriptionsRequest request;
64975 UA_ClientAsyncServiceCallback userCallback;
64976 void *userData;
64977} DeleteSubscriptionCallback;
64978
64979static void
64980ua_Subscriptions_delete_handler(UA_Client *client, void *data,
64981 UA_UInt32 requestId, void *r) {
64982 UA_DeleteSubscriptionsResponse *response =
64983 (UA_DeleteSubscriptionsResponse *)r;
64984 DeleteSubscriptionCallback *dsc =
64985 (DeleteSubscriptionCallback*)data;
64986
64987 lockClient(client);
64988
64989 /* Delete */
64990 __Client_Subscription_processDelete(client, request: &dsc->request, response);
64991
64992 /* Userland Callback */
64993 dsc->userCallback(client, dsc->userData, requestId, response);
64994
64995 /* Cleanup */
64996 UA_DeleteSubscriptionsRequest_clear(p: &dsc->request);
64997 UA_free(ptr: dsc);
64998
64999 unlockClient(client);
65000}
65001
65002UA_StatusCode
65003UA_Client_Subscriptions_delete_async(UA_Client *client,
65004 const UA_DeleteSubscriptionsRequest request,
65005 UA_ClientAsyncServiceCallback callback,
65006 void *userdata, UA_UInt32 *requestId) {
65007 /* Make a copy of the request that persists into the async callback */
65008 DeleteSubscriptionCallback *dsc = (DeleteSubscriptionCallback*)
65009 UA_malloc(size: sizeof(DeleteSubscriptionCallback));
65010 if(!dsc)
65011 return UA_STATUSCODE_BADOUTOFMEMORY;
65012 dsc->userCallback = callback;
65013 dsc->userData = userdata;
65014 UA_StatusCode res = UA_DeleteSubscriptionsRequest_copy(src: &request, dst: &dsc->request);
65015 if(res != UA_STATUSCODE_GOOD) {
65016 UA_free(ptr: dsc);
65017 return res;
65018 }
65019
65020 /* Make the async call */
65021 return __UA_Client_AsyncService(client, request: &request, requestType: &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST],
65022 callback: ua_Subscriptions_delete_handler, responseType: &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE],
65023 userdata: dsc, requestId);
65024}
65025
65026UA_DeleteSubscriptionsResponse
65027UA_Client_Subscriptions_delete(UA_Client *client,
65028 const UA_DeleteSubscriptionsRequest request) {
65029 lockClient(client);
65030
65031 /* Send the request */
65032 UA_DeleteSubscriptionsResponse response;
65033 __Client_Service(client, request: &request, requestType: &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST],
65034 response: &response, responseType: &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE]);
65035
65036 /* Process */
65037 __Client_Subscription_processDelete(client, request: &request, response: &response);
65038
65039 unlockClient(client);
65040 return response;
65041}
65042
65043UA_StatusCode
65044UA_Client_Subscriptions_deleteSingle(UA_Client *client, UA_UInt32 subscriptionId) {
65045 UA_DeleteSubscriptionsRequest request;
65046 UA_DeleteSubscriptionsRequest_init(p: &request);
65047 request.subscriptionIds = &subscriptionId;
65048 request.subscriptionIdsSize = 1;
65049
65050 UA_DeleteSubscriptionsResponse response =
65051 UA_Client_Subscriptions_delete(client, request);
65052
65053 UA_StatusCode retval = response.responseHeader.serviceResult;
65054 if(retval != UA_STATUSCODE_GOOD) {
65055 UA_DeleteSubscriptionsResponse_clear(p: &response);
65056 return retval;
65057 }
65058
65059 if(response.resultsSize != 1) {
65060 UA_DeleteSubscriptionsResponse_clear(p: &response);
65061 return UA_STATUSCODE_BADINTERNALERROR;
65062 }
65063
65064 retval = response.results[0];
65065 UA_DeleteSubscriptionsResponse_clear(p: &response);
65066 return retval;
65067}
65068
65069/******************/
65070/* MonitoredItems */
65071/******************/
65072
65073static void
65074MonitoredItem_delete(UA_Client *client, UA_Client_Subscription *sub,
65075 UA_Client_MonitoredItem *mon) {
65076 UA_LOCK_ASSERT(&client->clientMutex, 1);
65077
65078 ZIP_REMOVE(MonitorItemsTree, &sub->monitoredItems, mon);
65079 if(mon->deleteCallback) {
65080 void *subC = sub->context;
65081 void *monC = mon->context;
65082 UA_UInt32 subId = sub->subscriptionId;
65083 UA_UInt32 monId = mon->monitoredItemId;
65084 mon->deleteCallback(client, subId, subC, monId, monC);
65085 }
65086 UA_free(ptr: mon);
65087}
65088
65089typedef struct {
65090 void **contexts;
65091 UA_Client_DeleteMonitoredItemCallback *deleteCallbacks;
65092 void **handlingCallbacks;
65093 UA_CreateMonitoredItemsRequest request;
65094
65095 /* Notify the user that the async callback was processed */
65096 UA_ClientAsyncServiceCallback userCallback;
65097 void *userData;
65098} MonitoredItems_CreateData;
65099
65100static void
65101MonitoredItems_CreateData_clear(UA_Client *client, MonitoredItems_CreateData *data) {
65102 UA_free(ptr: data->contexts);
65103 UA_free(ptr: data->deleteCallbacks);
65104 UA_free(ptr: data->handlingCallbacks);
65105 UA_CreateMonitoredItemsRequest_clear(p: &data->request);
65106}
65107
65108static void
65109ua_MonitoredItems_create(UA_Client *client, MonitoredItems_CreateData *data,
65110 UA_CreateMonitoredItemsResponse *response) {
65111 UA_CreateMonitoredItemsRequest *request = &data->request;
65112 UA_Client_DeleteMonitoredItemCallback *deleteCallbacks = data->deleteCallbacks;
65113
65114 UA_Client_Subscription *sub = findSubscription(client, subscriptionId: data->request.subscriptionId);
65115 if(!sub)
65116 goto cleanup;
65117
65118 if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
65119 goto cleanup;
65120
65121 if(response->resultsSize != request->itemsToCreateSize) {
65122 response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR;
65123 goto cleanup;
65124 }
65125
65126 /* Add internally */
65127 for(size_t i = 0; i < request->itemsToCreateSize; i++) {
65128 if(response->results[i].statusCode != UA_STATUSCODE_GOOD) {
65129 void *subC = sub->context;
65130 UA_UInt32 subId = sub->subscriptionId;
65131 if(deleteCallbacks[i])
65132 deleteCallbacks[i](client, subId, subC, 0, data->contexts[i]);
65133 continue;
65134 }
65135
65136 UA_Client_MonitoredItem *newMon = (UA_Client_MonitoredItem *)
65137 UA_malloc(size: sizeof(UA_Client_MonitoredItem));
65138 if(!newMon) {
65139 void *subC = sub->context;
65140 UA_UInt32 subId = sub->subscriptionId;
65141 if(deleteCallbacks[i])
65142 deleteCallbacks[i](client, subId, subC, 0, data->contexts[i]);
65143 continue;
65144 }
65145
65146 newMon->monitoredItemId = response->results[i].monitoredItemId;
65147 newMon->clientHandle = request->itemsToCreate[i].requestedParameters.clientHandle;
65148 newMon->context = data->contexts[i];
65149 newMon->deleteCallback = deleteCallbacks[i];
65150 newMon->handler.dataChangeCallback =
65151 (UA_Client_DataChangeNotificationCallback)(uintptr_t)
65152 data->handlingCallbacks[i];
65153 newMon->isEventMonitoredItem =
65154 (request->itemsToCreate[i].itemToMonitor.attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER);
65155 ZIP_INSERT(MonitorItemsTree, &sub->monitoredItems, newMon);
65156
65157 UA_LOG_DEBUG(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65158 msg: "Subscription %" PRIu32 " | Added a MonitoredItem with handle %" PRIu32,
65159 sub->subscriptionId, newMon->clientHandle);
65160 }
65161 return;
65162
65163 /* Adding failed */
65164 cleanup:
65165 for(size_t i = 0; i < request->itemsToCreateSize; i++) {
65166 void *subC = sub ? sub->context : NULL;
65167 if(deleteCallbacks[i])
65168 deleteCallbacks[i](client, data->request.subscriptionId,
65169 subC, 0, data->contexts[i]);
65170 }
65171}
65172
65173static void
65174ua_MonitoredItems_create_async_handler(UA_Client *client, void *d, UA_UInt32 requestId,
65175 void *r) {
65176 UA_CreateMonitoredItemsResponse *response = (UA_CreateMonitoredItemsResponse *)r;
65177 MonitoredItems_CreateData *data = (MonitoredItems_CreateData *)d;
65178
65179 lockClient(client);
65180
65181 ua_MonitoredItems_create(client, data, response);
65182 MonitoredItems_CreateData_clear(client, data);
65183
65184 if(data->userCallback)
65185 data->userCallback(client, data->userData, requestId, response);
65186
65187 UA_free(ptr: data);
65188
65189 unlockClient(client);
65190}
65191
65192static UA_StatusCode
65193MonitoredItems_CreateData_prepare(UA_Client *client,
65194 const UA_CreateMonitoredItemsRequest *request,
65195 void **contexts, void **handlingCallbacks,
65196 UA_Client_DeleteMonitoredItemCallback *deleteCallbacks,
65197 MonitoredItems_CreateData *data) {
65198 /* Align arrays and copy over */
65199 UA_StatusCode retval = UA_STATUSCODE_BADOUTOFMEMORY;
65200 data->contexts = (void **)UA_calloc(nmemb: request->itemsToCreateSize, size: sizeof(void *));
65201 if(!data->contexts)
65202 goto cleanup;
65203 if(contexts)
65204 memcpy(dest: data->contexts, src: contexts, n: request->itemsToCreateSize * sizeof(void *));
65205
65206 data->deleteCallbacks = (UA_Client_DeleteMonitoredItemCallback *)
65207 UA_calloc(nmemb: request->itemsToCreateSize, size: sizeof(UA_Client_DeleteMonitoredItemCallback));
65208 if(!data->deleteCallbacks)
65209 goto cleanup;
65210 if(deleteCallbacks)
65211 memcpy(dest: data->deleteCallbacks, src: deleteCallbacks,
65212 n: request->itemsToCreateSize * sizeof(UA_Client_DeleteMonitoredItemCallback));
65213
65214 data->handlingCallbacks = (void **)
65215 UA_calloc(nmemb: request->itemsToCreateSize, size: sizeof(void *));
65216 if(!data->handlingCallbacks)
65217 goto cleanup;
65218 if(handlingCallbacks)
65219 memcpy(dest: data->handlingCallbacks, src: handlingCallbacks,
65220 n: request->itemsToCreateSize * sizeof(void *));
65221
65222 retval = UA_CreateMonitoredItemsRequest_copy(src: request, dst: &data->request);
65223 if(retval != UA_STATUSCODE_GOOD)
65224 goto cleanup;
65225
65226 /* Set the clientHandle */
65227 for(size_t i = 0; i < data->request.itemsToCreateSize; i++)
65228 data->request.itemsToCreate[i].requestedParameters.clientHandle =
65229 ++client->monitoredItemHandles;
65230
65231 return UA_STATUSCODE_GOOD;
65232
65233cleanup:
65234 MonitoredItems_CreateData_clear(client, data);
65235 return retval;
65236}
65237
65238static void
65239ua_Client_MonitoredItems_create(UA_Client *client,
65240 const UA_CreateMonitoredItemsRequest *request,
65241 void **contexts, void **handlingCallbacks,
65242 UA_Client_DeleteMonitoredItemCallback *deleteCallbacks,
65243 UA_CreateMonitoredItemsResponse *response) {
65244 UA_CreateMonitoredItemsResponse_init(p: response);
65245
65246 if(!request->itemsToCreateSize) {
65247 response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR;
65248 return;
65249 }
65250
65251 /* Test if the subscription is valid */
65252 UA_Client_Subscription *sub = findSubscription(client, subscriptionId: request->subscriptionId);
65253 if(!sub) {
65254 response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
65255 return;
65256 }
65257
65258 MonitoredItems_CreateData data;
65259 memset(s: &data, c: 0, n: sizeof(MonitoredItems_CreateData));
65260
65261 UA_StatusCode res =
65262 MonitoredItems_CreateData_prepare(client, request, contexts, handlingCallbacks,
65263 deleteCallbacks, data: &data);
65264 if(res != UA_STATUSCODE_GOOD) {
65265 response->responseHeader.serviceResult = res;
65266 return;
65267 }
65268
65269 /* Call the service. Use data->request as it contains the client handle
65270 * information. */
65271 __Client_Service(client, request: &data.request,
65272 requestType: &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST],
65273 response, responseType: &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE]);
65274
65275 /* Add internal representation */
65276 ua_MonitoredItems_create(client, data: &data, response);
65277
65278 MonitoredItems_CreateData_clear(client, data: &data);
65279}
65280
65281static UA_StatusCode
65282createDataChanges_async(UA_Client *client, const UA_CreateMonitoredItemsRequest request,
65283 void **contexts, void **callbacks,
65284 UA_Client_DeleteMonitoredItemCallback *deleteCallbacks,
65285 UA_ClientAsyncServiceCallback createCallback, void *userdata,
65286 UA_UInt32 *requestId) {
65287 UA_LOCK_ASSERT(&client->clientMutex, 1);
65288
65289 UA_Client_Subscription *sub = findSubscription(client, subscriptionId: request.subscriptionId);
65290 if(!sub)
65291 return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
65292
65293 MonitoredItems_CreateData *data = (MonitoredItems_CreateData *)
65294 UA_calloc(nmemb: 1, size: sizeof(MonitoredItems_CreateData));
65295 if(!data)
65296 return UA_STATUSCODE_BADOUTOFMEMORY;
65297
65298 data->userCallback = createCallback;
65299 data->userData = userdata;
65300
65301 UA_StatusCode res =
65302 MonitoredItems_CreateData_prepare(client, request: &request, contexts,
65303 handlingCallbacks: callbacks, deleteCallbacks, data);
65304 if(res != UA_STATUSCODE_GOOD) {
65305 UA_free(ptr: data);
65306 return res;
65307 }
65308
65309 return __Client_AsyncService(client, request: &data->request,
65310 requestType: &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST],
65311 callback: ua_MonitoredItems_create_async_handler,
65312 responseType: &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE],
65313 userdata: data, requestId);
65314}
65315
65316UA_CreateMonitoredItemsResponse
65317UA_Client_MonitoredItems_createDataChanges(UA_Client *client,
65318 const UA_CreateMonitoredItemsRequest request,
65319 void **contexts,
65320 UA_Client_DataChangeNotificationCallback *callbacks,
65321 UA_Client_DeleteMonitoredItemCallback *deleteCallbacks) {
65322 UA_CreateMonitoredItemsResponse response;
65323 lockClient(client);
65324 ua_Client_MonitoredItems_create(client, request: &request, contexts, handlingCallbacks: (void **)callbacks,
65325 deleteCallbacks, response: &response);
65326 unlockClient(client);
65327 return response;
65328}
65329
65330UA_StatusCode
65331UA_Client_MonitoredItems_createDataChanges_async(UA_Client *client,
65332 const UA_CreateMonitoredItemsRequest request,
65333 void **contexts,
65334 UA_Client_DataChangeNotificationCallback *callbacks,
65335 UA_Client_DeleteMonitoredItemCallback *deleteCallbacks,
65336 UA_ClientAsyncServiceCallback createCallback,
65337 void *userdata, UA_UInt32 *requestId) {
65338 lockClient(client);
65339 UA_StatusCode res =
65340 createDataChanges_async(client, request, contexts, callbacks: (void **)callbacks,
65341 deleteCallbacks, createCallback, userdata, requestId);
65342 unlockClient(client);
65343 return res;
65344}
65345
65346UA_MonitoredItemCreateResult
65347UA_Client_MonitoredItems_createDataChange(UA_Client *client, UA_UInt32 subscriptionId,
65348 UA_TimestampsToReturn timestampsToReturn,
65349 const UA_MonitoredItemCreateRequest item,
65350 void *context,
65351 UA_Client_DataChangeNotificationCallback callback,
65352 UA_Client_DeleteMonitoredItemCallback deleteCallback) {
65353 UA_CreateMonitoredItemsRequest request;
65354 UA_CreateMonitoredItemsRequest_init(p: &request);
65355 request.subscriptionId = subscriptionId;
65356 request.timestampsToReturn = timestampsToReturn;
65357 request.itemsToCreate = (UA_MonitoredItemCreateRequest*)(uintptr_t)&item;
65358 request.itemsToCreateSize = 1;
65359 UA_CreateMonitoredItemsResponse response =
65360 UA_Client_MonitoredItems_createDataChanges(client, request, contexts: &context,
65361 callbacks: &callback, deleteCallbacks: &deleteCallback);
65362 UA_MonitoredItemCreateResult result;
65363 UA_MonitoredItemCreateResult_init(p: &result);
65364 if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD)
65365 result.statusCode = response.responseHeader.serviceResult;
65366
65367 if(result.statusCode == UA_STATUSCODE_GOOD &&
65368 response.resultsSize != 1)
65369 result.statusCode = UA_STATUSCODE_BADINTERNALERROR;
65370
65371 if(result.statusCode == UA_STATUSCODE_GOOD)
65372 UA_MonitoredItemCreateResult_copy(src: &response.results[0] , dst: &result);
65373 UA_CreateMonitoredItemsResponse_clear(p: &response);
65374 return result;
65375}
65376
65377UA_CreateMonitoredItemsResponse
65378UA_Client_MonitoredItems_createEvents(UA_Client *client,
65379 const UA_CreateMonitoredItemsRequest request,
65380 void **contexts,
65381 UA_Client_EventNotificationCallback *callback,
65382 UA_Client_DeleteMonitoredItemCallback *deleteCallback) {
65383 UA_CreateMonitoredItemsResponse response;
65384 lockClient(client);
65385 ua_Client_MonitoredItems_create(client, request: &request, contexts, handlingCallbacks: (void **)callback,
65386 deleteCallbacks: deleteCallback, response: &response);
65387 unlockClient(client);
65388 return response;
65389}
65390
65391/* Monitor the EventNotifier attribute only */
65392UA_StatusCode
65393UA_Client_MonitoredItems_createEvents_async(UA_Client *client,
65394 const UA_CreateMonitoredItemsRequest request,
65395 void **contexts,
65396 UA_Client_EventNotificationCallback *callbacks,
65397 UA_Client_DeleteMonitoredItemCallback *deleteCallbacks,
65398 UA_ClientAsyncServiceCallback createCallback,
65399 void *userdata, UA_UInt32 *requestId) {
65400 lockClient(client);
65401 UA_StatusCode res =
65402 createDataChanges_async(client, request, contexts, callbacks: (void **)callbacks, deleteCallbacks,
65403 createCallback, userdata, requestId);
65404 unlockClient(client);
65405 return res;
65406}
65407
65408UA_MonitoredItemCreateResult
65409UA_Client_MonitoredItems_createEvent(UA_Client *client, UA_UInt32 subscriptionId,
65410 UA_TimestampsToReturn timestampsToReturn,
65411 const UA_MonitoredItemCreateRequest item, void *context,
65412 UA_Client_EventNotificationCallback callback,
65413 UA_Client_DeleteMonitoredItemCallback deleteCallback) {
65414 UA_CreateMonitoredItemsRequest request;
65415 UA_CreateMonitoredItemsRequest_init(p: &request);
65416 request.subscriptionId = subscriptionId;
65417 request.timestampsToReturn = timestampsToReturn;
65418 request.itemsToCreate = (UA_MonitoredItemCreateRequest*)(uintptr_t)&item;
65419 request.itemsToCreateSize = 1;
65420 UA_CreateMonitoredItemsResponse response =
65421 UA_Client_MonitoredItems_createEvents(client, request, contexts: &context,
65422 callback: &callback, deleteCallback: &deleteCallback);
65423 UA_StatusCode retval = response.responseHeader.serviceResult;
65424 UA_MonitoredItemCreateResult result;
65425 UA_MonitoredItemCreateResult_init(p: &result);
65426 if(retval != UA_STATUSCODE_GOOD) {
65427 UA_CreateMonitoredItemsResponse_clear(p: &response);
65428 result.statusCode = retval;
65429 return result;
65430 }
65431 UA_MonitoredItemCreateResult_copy(src: response.results , dst: &result);
65432 UA_CreateMonitoredItemsResponse_clear(p: &response);
65433 return result;
65434}
65435
65436static void
65437ua_MonitoredItems_delete(UA_Client *client, UA_Client_Subscription *sub,
65438 const UA_DeleteMonitoredItemsRequest *request,
65439 const UA_DeleteMonitoredItemsResponse *response) {
65440#ifdef __clang_analyzer__
65441 return;
65442#endif
65443
65444 /* Loop over deleted MonitoredItems */
65445 struct UA_Client_MonitoredItem_ForDelete deleteMonitoredItem;
65446 memset(s: &deleteMonitoredItem, c: 0, n: sizeof(struct UA_Client_MonitoredItem_ForDelete));
65447 deleteMonitoredItem.client = client;
65448 deleteMonitoredItem.sub = sub;
65449
65450 for(size_t i = 0; i < response->resultsSize; i++) {
65451 if(response->results[i] != UA_STATUSCODE_GOOD &&
65452 response->results[i] != UA_STATUSCODE_BADMONITOREDITEMIDINVALID) {
65453 continue;
65454 }
65455 deleteMonitoredItem.monitoredItemId = &request->monitoredItemIds[i];
65456 /* Delete the internal representation */
65457 ZIP_ITER(MonitorItemsTree,&sub->monitoredItems,
65458 UA_MonitoredItem_delete_wrapper, &deleteMonitoredItem);
65459 }
65460}
65461
65462static void
65463ua_MonitoredItems_delete_handler(UA_Client *client, void *d, UA_UInt32 requestId, void *r) {
65464 UA_Client_Subscription *sub = NULL;
65465 CustomCallback *cc = (CustomCallback *)d;
65466 UA_DeleteMonitoredItemsResponse *response = (UA_DeleteMonitoredItemsResponse *)r;
65467 UA_DeleteMonitoredItemsRequest *request =
65468 (UA_DeleteMonitoredItemsRequest *)cc->clientData;
65469
65470 lockClient(client);
65471
65472 if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
65473 goto cleanup;
65474
65475 sub = findSubscription(client, subscriptionId: request->subscriptionId);
65476 if(!sub) {
65477 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65478 msg: "No internal representation of subscription %" PRIu32,
65479 request->subscriptionId);
65480 goto cleanup;
65481 }
65482
65483 /* Delete MonitoredItems from the internal representation */
65484 ua_MonitoredItems_delete(client, sub, request, response);
65485
65486cleanup:
65487 if(cc->userCallback)
65488 cc->userCallback(client, cc->userData, requestId, response);
65489 UA_DeleteMonitoredItemsRequest_delete(p: request);
65490 UA_free(ptr: cc);
65491
65492 unlockClient(client);
65493}
65494
65495UA_DeleteMonitoredItemsResponse
65496UA_Client_MonitoredItems_delete(UA_Client *client,
65497 const UA_DeleteMonitoredItemsRequest request) {
65498 /* Send the request */
65499 UA_DeleteMonitoredItemsResponse response;
65500 __UA_Client_Service(client, request: &request, requestType: &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST],
65501 response: &response, responseType: &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE]);
65502
65503 /* A problem occured remote? */
65504 if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD)
65505 return response;
65506
65507 lockClient(client);
65508
65509 /* Find the internal subscription representation */
65510 UA_Client_Subscription *sub = findSubscription(client, subscriptionId: request.subscriptionId);
65511 if(!sub) {
65512 UA_LOG_INFO(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65513 msg: "No internal representation of subscription %" PRIu32,
65514 request.subscriptionId);
65515 unlockClient(client);
65516 return response;
65517 }
65518
65519 /* Remove MonitoredItems in the internal representation */
65520 ua_MonitoredItems_delete(client, sub, request: &request, response: &response);
65521
65522 unlockClient(client);
65523
65524 return response;
65525}
65526
65527UA_StatusCode
65528UA_Client_MonitoredItems_delete_async(UA_Client *client,
65529 const UA_DeleteMonitoredItemsRequest request,
65530 UA_ClientAsyncServiceCallback callback,
65531 void *userdata, UA_UInt32 *requestId) {
65532 /* Send the request */
65533 CustomCallback *cc = (CustomCallback *)UA_calloc(nmemb: 1, size: sizeof(CustomCallback));
65534 if(!cc)
65535 return UA_STATUSCODE_BADOUTOFMEMORY;
65536
65537 UA_DeleteMonitoredItemsRequest *req_copy = UA_DeleteMonitoredItemsRequest_new();
65538 if(!req_copy) {
65539 UA_free(ptr: cc);
65540 return UA_STATUSCODE_BADOUTOFMEMORY;
65541 }
65542
65543 UA_DeleteMonitoredItemsRequest_copy(src: &request, dst: req_copy);
65544 cc->clientData = req_copy;
65545 cc->userCallback = callback;
65546 cc->userData = userdata;
65547
65548 return __UA_Client_AsyncService(client, request: &request, requestType: &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST],
65549 callback: ua_MonitoredItems_delete_handler,
65550 responseType: &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE], userdata: cc, requestId);
65551}
65552
65553UA_StatusCode
65554UA_Client_MonitoredItems_deleteSingle(UA_Client *client, UA_UInt32 subscriptionId,
65555 UA_UInt32 monitoredItemId) {
65556 UA_DeleteMonitoredItemsRequest request;
65557 UA_DeleteMonitoredItemsRequest_init(p: &request);
65558 request.subscriptionId = subscriptionId;
65559 request.monitoredItemIds = &monitoredItemId;
65560 request.monitoredItemIdsSize = 1;
65561
65562 UA_DeleteMonitoredItemsResponse response =
65563 UA_Client_MonitoredItems_delete(client, request);
65564
65565 UA_StatusCode retval = response.responseHeader.serviceResult;
65566 if(retval != UA_STATUSCODE_GOOD) {
65567 UA_DeleteMonitoredItemsResponse_clear(p: &response);
65568 return retval;
65569 }
65570
65571 if(response.resultsSize != 1) {
65572 UA_DeleteMonitoredItemsResponse_clear(p: &response);
65573 return UA_STATUSCODE_BADINTERNALERROR;
65574 }
65575
65576 retval = response.results[0];
65577 UA_DeleteMonitoredItemsResponse_clear(p: &response);
65578 return retval;
65579}
65580
65581static void *
65582UA_MonitoredItem_change_clientHandle_wrapper(void *data, UA_Client_MonitoredItem *mon) {
65583 UA_MonitoredItemModifyRequest *monitoredItemModifyRequest =
65584 (UA_MonitoredItemModifyRequest *)data;
65585 if(monitoredItemModifyRequest &&
65586 mon->monitoredItemId == monitoredItemModifyRequest->monitoredItemId)
65587 monitoredItemModifyRequest->requestedParameters.clientHandle = mon->clientHandle;
65588 return NULL;
65589}
65590
65591static void
65592UA_MonitoredItem_change_clientHandle(UA_Client_Subscription *sub,
65593 UA_ModifyMonitoredItemsRequest *request) {
65594 for(size_t i = 0; i < request->itemsToModifySize; ++i) {
65595 ZIP_ITER(MonitorItemsTree, &sub->monitoredItems,
65596 UA_MonitoredItem_change_clientHandle_wrapper,
65597 &request->itemsToModify[i]);
65598 }
65599}
65600
65601UA_ModifyMonitoredItemsResponse
65602UA_Client_MonitoredItems_modify(UA_Client *client,
65603 const UA_ModifyMonitoredItemsRequest request) {
65604 UA_ModifyMonitoredItemsResponse response;
65605 UA_ModifyMonitoredItemsResponse_init(p: &response);
65606
65607 lockClient(client);
65608 UA_Client_Subscription *sub = findSubscription(client, subscriptionId: request.subscriptionId);
65609 if(!sub) {
65610 unlockClient(client);
65611 response.responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
65612 return response;
65613 }
65614
65615 UA_ModifyMonitoredItemsRequest modifiedRequest;
65616 UA_ModifyMonitoredItemsRequest_copy(src: &request, dst: &modifiedRequest);
65617 UA_MonitoredItem_change_clientHandle(sub, request: &modifiedRequest);
65618
65619 __Client_Service(client, request: &modifiedRequest,
65620 requestType: &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST], response: &response,
65621 responseType: &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE]);
65622
65623 unlockClient(client);
65624 UA_ModifyMonitoredItemsRequest_clear(p: &modifiedRequest);
65625 return response;
65626}
65627
65628UA_StatusCode
65629UA_Client_MonitoredItems_modify_async(UA_Client *client,
65630 const UA_ModifyMonitoredItemsRequest request,
65631 UA_ClientAsyncServiceCallback callback,
65632 void *userdata, UA_UInt32 *requestId) {
65633 lockClient(client);
65634 UA_Client_Subscription *sub = findSubscription(client, subscriptionId: request.subscriptionId);
65635 if(!sub) {
65636 unlockClient(client);
65637 return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID;
65638 }
65639
65640 UA_ModifyMonitoredItemsRequest modifiedRequest;
65641 UA_ModifyMonitoredItemsRequest_copy(src: &request, dst: &modifiedRequest);
65642 UA_MonitoredItem_change_clientHandle(sub, request: &modifiedRequest);
65643
65644 UA_StatusCode statusCode = __Client_AsyncService(
65645 client, request: &modifiedRequest, requestType: &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST],
65646 callback, responseType: &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE], userdata, requestId);
65647
65648 unlockClient(client);
65649 UA_ModifyMonitoredItemsRequest_clear(p: &modifiedRequest);
65650 return statusCode;
65651}
65652
65653/*************************************/
65654/* Async Processing of Notifications */
65655/*************************************/
65656
65657/* Assume the request is already initialized */
65658UA_StatusCode
65659__Client_preparePublishRequest(UA_Client *client, UA_PublishRequest *request) {
65660 UA_LOCK_ASSERT(&client->clientMutex, 1);
65661
65662 /* Count acks */
65663 UA_Client_NotificationsAckNumber *ack;
65664 LIST_FOREACH(ack, &client->pendingNotificationsAcks, listEntry)
65665 ++request->subscriptionAcknowledgementsSize;
65666
65667 /* Create the array. Returns a sentinel pointer if the length is zero. */
65668 request->subscriptionAcknowledgements = (UA_SubscriptionAcknowledgement*)
65669 UA_Array_new(size: request->subscriptionAcknowledgementsSize,
65670 type: &UA_TYPES[UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT]);
65671 if(!request->subscriptionAcknowledgements) {
65672 request->subscriptionAcknowledgementsSize = 0;
65673 return UA_STATUSCODE_BADOUTOFMEMORY;
65674 }
65675
65676 size_t i = 0;
65677 UA_Client_NotificationsAckNumber *ack_tmp;
65678 LIST_FOREACH_SAFE(ack, &client->pendingNotificationsAcks, listEntry, ack_tmp) {
65679 request->subscriptionAcknowledgements[i].sequenceNumber = ack->subAck.sequenceNumber;
65680 request->subscriptionAcknowledgements[i].subscriptionId = ack->subAck.subscriptionId;
65681 ++i;
65682 LIST_REMOVE(ack, listEntry);
65683 UA_free(ptr: ack);
65684 }
65685 return UA_STATUSCODE_GOOD;
65686}
65687
65688/* According to OPC Unified Architecture, Part 4 5.13.1.1 i) */
65689/* The value 0 is never used for the sequence number */
65690static UA_UInt32
65691__nextSequenceNumber(UA_UInt32 sequenceNumber) {
65692 UA_UInt32 nextSequenceNumber = sequenceNumber + 1;
65693 if(nextSequenceNumber == 0)
65694 nextSequenceNumber = 1;
65695 return nextSequenceNumber;
65696}
65697
65698static void
65699processDataChangeNotification(UA_Client *client, UA_Client_Subscription *sub,
65700 UA_DataChangeNotification *dataChangeNotification) {
65701 UA_LOCK_ASSERT(&client->clientMutex, 1);
65702
65703 for(size_t j = 0; j < dataChangeNotification->monitoredItemsSize; ++j) {
65704 UA_MonitoredItemNotification *min = &dataChangeNotification->monitoredItems[j];
65705
65706 /* Find the MonitoredItem */
65707 UA_Client_MonitoredItem *mon;
65708 UA_Client_MonitoredItem dummy;
65709 dummy.clientHandle = min->clientHandle;
65710 mon = ZIP_FIND(MonitorItemsTree, &sub->monitoredItems, &dummy);
65711
65712 if(!mon) {
65713 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65714 msg: "Could not process a notification with clienthandle %" PRIu32
65715 " on subscription %" PRIu32, min->clientHandle, sub->subscriptionId);
65716 continue;
65717 }
65718
65719 if(mon->isEventMonitoredItem) {
65720 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65721 msg: "MonitoredItem is configured for Events. But received a "
65722 "DataChangeNotification.");
65723 continue;
65724 }
65725
65726 if(mon->handler.dataChangeCallback) {
65727 void *subC = sub->context;
65728 void *monC = mon->context;
65729 UA_UInt32 subId = sub->subscriptionId;
65730 UA_UInt32 monId = mon->monitoredItemId;
65731 mon->handler.dataChangeCallback(client, subId, subC, monId, monC, &min->value);
65732 }
65733 }
65734}
65735
65736static void
65737processEventNotification(UA_Client *client, UA_Client_Subscription *sub,
65738 UA_EventNotificationList *eventNotificationList) {
65739 UA_LOCK_ASSERT(&client->clientMutex, 1);
65740
65741 for(size_t j = 0; j < eventNotificationList->eventsSize; ++j) {
65742 UA_EventFieldList *eventFieldList = &eventNotificationList->events[j];
65743
65744 /* Find the MonitoredItem */
65745 UA_Client_MonitoredItem *mon;
65746 UA_Client_MonitoredItem dummy;
65747 dummy.clientHandle = eventFieldList->clientHandle;
65748 mon = ZIP_FIND(MonitorItemsTree, &sub->monitoredItems, &dummy);
65749
65750 if(!mon) {
65751 UA_LOG_DEBUG(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65752 msg: "Could not process a notification with clienthandle %" PRIu32
65753 " on subscription %" PRIu32, eventFieldList->clientHandle,
65754 sub->subscriptionId);
65755 continue;
65756 }
65757
65758 if(!mon->isEventMonitoredItem) {
65759 UA_LOG_DEBUG(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65760 msg: "MonitoredItem is configured for DataChanges. But received a "
65761 "EventNotification.");
65762 continue;
65763 }
65764
65765 void *subC = sub->context;
65766 void *monC = mon->context;
65767 UA_UInt32 subId = sub->subscriptionId;
65768 UA_UInt32 monId = mon->monitoredItemId;
65769 mon->handler.eventCallback(client, subId, subC, monId, monC,
65770 eventFieldList->eventFieldsSize,
65771 eventFieldList->eventFields);
65772 }
65773}
65774
65775static void
65776processNotificationMessage(UA_Client *client, UA_Client_Subscription *sub,
65777 UA_ExtensionObject *msg) {
65778 UA_LOCK_ASSERT(&client->clientMutex, 1);
65779
65780 if(msg->encoding != UA_EXTENSIONOBJECT_DECODED)
65781 return;
65782
65783 /* Handle DataChangeNotification */
65784 if(msg->content.decoded.type == &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION]) {
65785 UA_DataChangeNotification *dataChangeNotification =
65786 (UA_DataChangeNotification *)msg->content.decoded.data;
65787 processDataChangeNotification(client, sub, dataChangeNotification);
65788 return;
65789 }
65790
65791 /* Handle EventNotification */
65792 if(msg->content.decoded.type == &UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST]) {
65793 UA_EventNotificationList *eventNotificationList =
65794 (UA_EventNotificationList *)msg->content.decoded.data;
65795 processEventNotification(client, sub, eventNotificationList);
65796 return;
65797 }
65798
65799 /* Handle StatusChangeNotification */
65800 if(msg->content.decoded.type == &UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION]) {
65801 if(sub->statusChangeCallback) {
65802 void *subC = sub->context;
65803 UA_UInt32 subId = sub->subscriptionId;
65804 sub->statusChangeCallback(client, subId, subC,
65805 (UA_StatusChangeNotification*)msg->content.decoded.data);
65806 } else {
65807 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65808 msg: "Dropped a StatusChangeNotification since no "
65809 "callback is registered");
65810 }
65811 return;
65812 }
65813
65814 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65815 msg: "Unknown notification message type");
65816}
65817
65818static void
65819__Client_Subscriptions_processPublishResponse(UA_Client *client, UA_PublishRequest *request,
65820 UA_PublishResponse *response) {
65821 UA_LOCK_ASSERT(&client->clientMutex, 1);
65822
65823 UA_NotificationMessage *msg = &response->notificationMessage;
65824
65825 client->currentlyOutStandingPublishRequests--;
65826
65827 if(response->responseHeader.serviceResult == UA_STATUSCODE_BADTOOMANYPUBLISHREQUESTS) {
65828 if(client->config.outStandingPublishRequests > 1) {
65829 client->config.outStandingPublishRequests--;
65830 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65831 msg: "Too many publishrequest, reduce outStandingPublishRequests "
65832 "to %" PRId16, client->config.outStandingPublishRequests);
65833 } else {
65834 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65835 msg: "Too many publishrequest when outStandingPublishRequests = 1");
65836 UA_Client_Subscriptions_deleteSingle(client, subscriptionId: response->subscriptionId);
65837 }
65838 return;
65839 }
65840
65841 if(response->responseHeader.serviceResult == UA_STATUSCODE_BADSHUTDOWN)
65842 return;
65843
65844 if(response->responseHeader.serviceResult == UA_STATUSCODE_BADNOSUBSCRIPTION)
65845 {
65846 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65847 msg: "Received BadNoSubscription, delete internal information about subscription");
65848 UA_Client_Subscription *sub = findSubscription(client, subscriptionId: response->subscriptionId);
65849 if(sub != NULL)
65850 __Client_Subscription_deleteInternal(client, sub);
65851 return;
65852 }
65853
65854 if(!LIST_FIRST(&client->subscriptions)) {
65855 response->responseHeader.serviceResult = UA_STATUSCODE_BADNOSUBSCRIPTION;
65856 return;
65857 }
65858
65859 UA_Client_Subscription *sub = findSubscription(client, subscriptionId: response->subscriptionId);
65860 if(!sub) {
65861 response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR;
65862 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65863 msg: "Received Publish Response for a non-existant subscription");
65864 return;
65865 }
65866
65867 if(response->responseHeader.serviceResult == UA_STATUSCODE_BADSESSIONCLOSED) {
65868 if(client->sessionState != UA_SESSIONSTATE_ACTIVATED) {
65869 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65870 msg: "Received Publish Response with code %s",
65871 UA_StatusCode_name(code: response->responseHeader.serviceResult));
65872 __Client_Subscription_deleteInternal(client, sub);
65873 }
65874 return;
65875 }
65876
65877 if(response->responseHeader.serviceResult == UA_STATUSCODE_BADTIMEOUT) {
65878 if(client->config.subscriptionInactivityCallback) {
65879 void *subC = sub->context;
65880 UA_UInt32 subId = sub->subscriptionId;
65881 client->config.subscriptionInactivityCallback(client, subId, subC);
65882 }
65883 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65884 msg: "Received Timeout for Publish Response");
65885 return;
65886 }
65887
65888 if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
65889 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65890 msg: "Received Publish Response with code %s",
65891 UA_StatusCode_name(code: response->responseHeader.serviceResult));
65892 return;
65893 }
65894
65895 sub->lastActivity = UA_DateTime_nowMonotonic();
65896
65897 /* Detect missing message - OPC Unified Architecture, Part 4 5.13.1.1 e) */
65898 if(__nextSequenceNumber(sequenceNumber: sub->sequenceNumber) != msg->sequenceNumber) {
65899 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65900 msg: "Invalid subscription sequence number: expected %" PRIu32
65901 " but got %" PRIu32, __nextSequenceNumber(sequenceNumber: sub->sequenceNumber),
65902 msg->sequenceNumber);
65903 /* This is an error. But we do not abort the connection. Some server
65904 * SDKs misbehave from time to time and send out-of-order sequence
65905 * numbers. (Probably some multi-threading synchronization issue.) */
65906 /* UA_Client_disconnect(client);
65907 return; */
65908 }
65909 /* According to f), a keep-alive message contains no notifications and has
65910 * the sequence number of the next NotificationMessage that is to be sent =>
65911 * More than one consecutive keep-alive message or a NotificationMessage
65912 * following a keep-alive message will share the same sequence number. */
65913 if (msg->notificationDataSize)
65914 sub->sequenceNumber = msg->sequenceNumber;
65915
65916 /* Process the notification messages */
65917 for(size_t k = 0; k < msg->notificationDataSize; ++k)
65918 processNotificationMessage(client, sub, msg: &msg->notificationData[k]);
65919
65920 /* Add to the list of pending acks */
65921 for(size_t i = 0; i < response->availableSequenceNumbersSize; i++) {
65922 if(response->availableSequenceNumbers[i] != msg->sequenceNumber)
65923 continue;
65924 UA_Client_NotificationsAckNumber *tmpAck = (UA_Client_NotificationsAckNumber*)
65925 UA_malloc(size: sizeof(UA_Client_NotificationsAckNumber));
65926 if(!tmpAck) {
65927 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
65928 msg: "Not enough memory to store the acknowledgement for a publish "
65929 "message on subscription %" PRIu32, sub->subscriptionId);
65930 break;
65931 }
65932 tmpAck->subAck.sequenceNumber = msg->sequenceNumber;
65933 tmpAck->subAck.subscriptionId = sub->subscriptionId;
65934 LIST_INSERT_HEAD(&client->pendingNotificationsAcks, tmpAck, listEntry);
65935 break;
65936 }
65937}
65938
65939static void
65940processPublishResponseAsync(UA_Client *client, void *userdata,
65941 UA_UInt32 requestId, void *response) {
65942 UA_PublishRequest *req = (UA_PublishRequest*)userdata;
65943 UA_PublishResponse *res = (UA_PublishResponse*)response;
65944
65945 lockClient(client);
65946
65947 /* Process the response */
65948 __Client_Subscriptions_processPublishResponse(client, request: req, response: res);
65949
65950 /* Delete the cached request */
65951 UA_PublishRequest_delete(p: req);
65952
65953 /* Fill up the outstanding publish requests */
65954 __Client_Subscriptions_backgroundPublish(client);
65955
65956 unlockClient(client);
65957}
65958
65959void
65960__Client_Subscriptions_clean(UA_Client *client) {
65961 UA_Client_NotificationsAckNumber *n;
65962 UA_Client_NotificationsAckNumber *tmp;
65963 LIST_FOREACH_SAFE(n, &client->pendingNotificationsAcks, listEntry, tmp) {
65964 LIST_REMOVE(n, listEntry);
65965 UA_free(ptr: n);
65966 }
65967
65968 UA_Client_Subscription *sub;
65969 UA_Client_Subscription *tmps;
65970 LIST_FOREACH_SAFE(sub, &client->subscriptions, listEntry, tmps)
65971 __Client_Subscription_deleteInternal(client, sub); /* force local removal */
65972
65973 client->monitoredItemHandles = 0;
65974}
65975
65976void
65977__Client_Subscriptions_backgroundPublishInactivityCheck(UA_Client *client) {
65978 UA_LOCK_ASSERT(&client->clientMutex, 1);
65979
65980 if(client->sessionState < UA_SESSIONSTATE_ACTIVATED)
65981 return;
65982
65983 /* Is the lack of responses the client's fault? */
65984 if(client->currentlyOutStandingPublishRequests == 0)
65985 return;
65986
65987 UA_Client_Subscription *sub;
65988 LIST_FOREACH(sub, &client->subscriptions, listEntry) {
65989 UA_DateTime maxSilence = (UA_DateTime)
65990 ((sub->publishingInterval * sub->maxKeepAliveCount) +
65991 client->config.timeout) * UA_DATETIME_MSEC;
65992 if(maxSilence + sub->lastActivity < UA_DateTime_nowMonotonic()) {
65993 /* Reset activity */
65994 sub->lastActivity = UA_DateTime_nowMonotonic();
65995
65996 if(client->config.subscriptionInactivityCallback) {
65997 void *subC = sub->context;
65998 UA_UInt32 subId = sub->subscriptionId;
65999 client->config.subscriptionInactivityCallback(client, subId, subC);
66000 }
66001 UA_LOG_WARNING(logger: client->config.logging, category: UA_LOGCATEGORY_CLIENT,
66002 msg: "Inactivity for Subscription %" PRIu32 ".", sub->subscriptionId);
66003 }
66004 }
66005}
66006
66007void
66008__Client_Subscriptions_backgroundPublish(UA_Client *client) {
66009 UA_LOCK_ASSERT(&client->clientMutex, 1);
66010
66011 if(client->sessionState != UA_SESSIONSTATE_ACTIVATED)
66012 return;
66013
66014 /* The session must have at least one subscription */
66015 if(!LIST_FIRST(&client->subscriptions))
66016 return;
66017
66018 while(client->currentlyOutStandingPublishRequests < client->config.outStandingPublishRequests) {
66019 UA_PublishRequest *request = UA_PublishRequest_new();
66020 if(!request)
66021 return;
66022
66023 /* Publish requests are valid for 10 minutes */
66024 request->requestHeader.timeoutHint = 10 * 60 * 1000;
66025
66026 UA_StatusCode retval = __Client_preparePublishRequest(client, request);
66027 if(retval != UA_STATUSCODE_GOOD) {
66028 UA_PublishRequest_delete(p: request);
66029 return;
66030 }
66031
66032 retval = __Client_AsyncService(client, request,
66033 requestType: &UA_TYPES[UA_TYPES_PUBLISHREQUEST],
66034 callback: processPublishResponseAsync,
66035 responseType: &UA_TYPES[UA_TYPES_PUBLISHRESPONSE],
66036 userdata: (void*)request, NULL);
66037 if(retval != UA_STATUSCODE_GOOD) {
66038 UA_PublishRequest_delete(p: request);
66039 return;
66040 }
66041
66042 client->currentlyOutStandingPublishRequests++;
66043 }
66044}
66045
66046/**** amalgamated original file "/deps/libc_time.c" ****/
66047
66048/* Originally released by the musl project (http://www.musl-libc.org/) under the
66049 * MIT license. Taken from the file /src/time/__secs_to_tm.c */
66050
66051#include <limits.h>
66052
66053/* 2000-03-01 (mod 400 year, immediately after feb29 */
66054#define LEAPOCH (946684800LL + 86400*(31+29))
66055
66056#define DAYS_PER_400Y (365*400 + 97)
66057#define DAYS_PER_100Y (365*100 + 24)
66058#define DAYS_PER_4Y (365*4 + 1)
66059
66060int
66061musl_secs_to_tm(long long t, struct musl_tm *tm) {
66062 long long days, secs, years;
66063 int remdays, remsecs, remyears;
66064 int qc_cycles, c_cycles, q_cycles;
66065 int months;
66066 int wday, yday, leap;
66067 static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
66068
66069 /* Reject time_t values whose year would overflow int */
66070 if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL)
66071 return -1;
66072
66073 secs = t - LEAPOCH;
66074 days = secs / 86400LL;
66075 remsecs = (int)(secs % 86400);
66076 if (remsecs < 0) {
66077 remsecs += 86400;
66078 --days;
66079 }
66080
66081 wday = (3+days)%7;
66082 if (wday < 0) wday += 7;
66083
66084 qc_cycles = (int)(days / DAYS_PER_400Y);
66085 remdays = (int)(days % DAYS_PER_400Y);
66086 if (remdays < 0) {
66087 remdays += DAYS_PER_400Y;
66088 --qc_cycles;
66089 }
66090
66091 c_cycles = remdays / DAYS_PER_100Y;
66092 if (c_cycles == 4) --c_cycles;
66093 remdays -= c_cycles * DAYS_PER_100Y;
66094
66095 q_cycles = remdays / DAYS_PER_4Y;
66096 if (q_cycles == 25) --q_cycles;
66097 remdays -= q_cycles * DAYS_PER_4Y;
66098
66099 remyears = remdays / 365;
66100 if (remyears == 4) --remyears;
66101 remdays -= remyears * 365;
66102
66103 leap = !remyears && (q_cycles || !c_cycles);
66104 yday = remdays + 31 + 28 + leap;
66105 if (yday >= 365+leap) yday -= 365+leap;
66106
66107 years = remyears + 4*q_cycles + 100*c_cycles + 400LL*qc_cycles;
66108
66109 for (months=0; days_in_month[months] <= remdays; months++)
66110 remdays -= days_in_month[months];
66111
66112 if (months >= 10) {
66113 months -= 12;
66114 years++;
66115 }
66116
66117 if (years+100 > INT_MAX || years+100 < INT_MIN)
66118 return -1;
66119
66120 tm->tm_year = (int)(years + 100);
66121 tm->tm_mon = months + 2;
66122 tm->tm_mday = remdays + 1;
66123 tm->tm_wday = wday;
66124 tm->tm_yday = yday;
66125
66126 tm->tm_hour = remsecs / 3600;
66127 tm->tm_min = remsecs / 60 % 60;
66128 tm->tm_sec = remsecs % 60;
66129
66130 return 0;
66131}
66132
66133static const int secs_through_month[] =
66134 {0, 31*86400, 59*86400, 90*86400,
66135 120*86400, 151*86400, 181*86400, 212*86400,
66136 243*86400, 273*86400, 304*86400, 334*86400 };
66137
66138static int
66139musl_month_to_secs(int month, int is_leap) {
66140 int t = secs_through_month[month];
66141 if (is_leap && month >= 2)
66142 t+=86400;
66143 return t;
66144}
66145
66146static long long
66147musl_year_to_secs(const long long year, int *is_leap) {
66148 if (year-2ULL <= 136) {
66149 int y = (int)year;
66150 int leaps = (y-68)>>2;
66151 if (!((y-68)&3)) {
66152 leaps--;
66153 if (is_leap) *is_leap = 1;
66154 } else if (is_leap) *is_leap = 0;
66155 return 31536000*(y-70) + 86400*leaps;
66156 }
66157
66158 int cycles, centuries, leaps, rem, dummy;
66159
66160 if (!is_leap) is_leap = &dummy;
66161 cycles = (int)((year-100) / 400);
66162 rem = (year-100) % 400;
66163 if (rem < 0) {
66164 cycles--;
66165 rem += 400;
66166 }
66167 if (!rem) {
66168 *is_leap = 1;
66169 centuries = 0;
66170 leaps = 0;
66171 } else {
66172 if (rem >= 200) {
66173 if (rem >= 300) centuries = 3, rem -= 300;
66174 else centuries = 2, rem -= 200;
66175 } else {
66176 if (rem >= 100) centuries = 1, rem -= 100;
66177 else centuries = 0;
66178 }
66179 if (!rem) {
66180 *is_leap = 0;
66181 leaps = 0;
66182 } else {
66183 leaps = rem / 4U;
66184 rem %= 4U;
66185 *is_leap = !rem;
66186 }
66187 }
66188
66189 leaps += 97*cycles + 24*centuries - *is_leap;
66190
66191 return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
66192}
66193
66194long long
66195musl_tm_to_secs(const struct musl_tm *tm) {
66196 int is_leap;
66197 long long year = tm->tm_year;
66198 int month = tm->tm_mon;
66199 if (month >= 12 || month < 0) {
66200 int adj = month / 12;
66201 month %= 12;
66202 if (month < 0) {
66203 adj--;
66204 month += 12;
66205 }
66206 year += adj;
66207 }
66208 long long t = musl_year_to_secs(year, is_leap: &is_leap);
66209 t += musl_month_to_secs(month, is_leap);
66210 t += 86400LL * (tm->tm_mday-1);
66211 t += 3600LL * tm->tm_hour;
66212 t += 60LL * tm->tm_min;
66213 t += tm->tm_sec;
66214 return t;
66215}
66216
66217/**** amalgamated original file "/deps/pcg_basic.c" ****/
66218
66219/*
66220 * PCG Random Number Generation for C.
66221 *
66222 * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
66223 *
66224 * Licensed under the Apache License, Version 2.0 (the "License");
66225 * you may not use this file except in compliance with the License.
66226 * You may obtain a copy of the License at
66227 *
66228 * http://www.apache.org/licenses/LICENSE-2.0
66229 *
66230 * Unless required by applicable law or agreed to in writing, software
66231 * distributed under the License is distributed on an "AS IS" BASIS,
66232 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66233 * See the License for the specific language governing permissions and
66234 * limitations under the License.
66235 *
66236 * For additional information about the PCG random number generation scheme,
66237 * including its license and other licensing options, visit
66238 *
66239 * http://www.pcg-random.org
66240 */
66241
66242
66243void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initial_state, uint64_t initseq) {
66244 rng->state = 0U;
66245 rng->inc = (initseq << 1u) | 1u;
66246 pcg32_random_r(rng);
66247 rng->state += initial_state;
66248 pcg32_random_r(rng);
66249}
66250
66251uint32_t pcg32_random_r(pcg32_random_t* rng) {
66252 uint64_t oldstate = rng->state;
66253 rng->state = oldstate * 6364136223846793005ULL + rng->inc;
66254 uint32_t xorshifted = (uint32_t)(((oldstate >> 18u) ^ oldstate) >> 27u);
66255 uint32_t rot = (uint32_t)(oldstate >> 59u);
66256 return (xorshifted >> rot) | (xorshifted << ((~rot + 1u) & 31)); /* was (xorshifted >> rot) | (xorshifted << ((-rot) & 31)) */
66257}
66258
66259/**** amalgamated original file "/deps/base64.c" ****/
66260
66261/*
66262 * Base64 encoding/decoding (RFC1341)
66263 * Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
66264 *
66265 * This software may be distributed under the terms of the BSD license.
66266 * See README for more details.
66267 */
66268
66269
66270static const unsigned char base64_table[65] =
66271 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
66272
66273unsigned char *
66274UA_base64(const unsigned char *src, size_t len, size_t *out_len) {
66275 if(len == 0) {
66276 *out_len = 0;
66277 return (unsigned char*)UA_EMPTY_ARRAY_SENTINEL;
66278 }
66279
66280 size_t olen = 4*((len + 2) / 3); /* 3-byte blocks to 4-byte */
66281 if(olen < len)
66282 return NULL; /* integer overflow */
66283
66284 unsigned char *out = (unsigned char*)UA_malloc(size: olen);
66285 if(!out)
66286 return NULL;
66287
66288 *out_len = UA_base64_buf(src, len, out);
66289 return out;
66290}
66291
66292size_t
66293UA_base64_buf(const unsigned char *src, size_t len, unsigned char *out) {
66294 const unsigned char *end = src + len;
66295 const unsigned char *in = src;
66296 unsigned char *pos = out;
66297 while(end - in >= 3) {
66298 *pos++ = base64_table[in[0] >> 2];
66299 *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
66300 *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
66301 *pos++ = base64_table[in[2] & 0x3f];
66302 in += 3;
66303 }
66304
66305 if(end - in) {
66306 *pos++ = base64_table[in[0] >> 2];
66307 if(end - in == 1) {
66308 *pos++ = base64_table[(in[0] & 0x03) << 4];
66309 *pos++ = '=';
66310 } else {
66311 *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
66312 *pos++ = base64_table[(in[1] & 0x0f) << 2];
66313 }
66314 *pos++ = '=';
66315 }
66316
66317 return (size_t)(pos - out);
66318}
66319
66320static unsigned char dtable[256] = {
66321 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
66322 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
66323 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 62 , 0x80, 62 , 0x80, 63 ,
66324 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 0x80, 0x80, 0x80, 0, 0x80, 0x80,
66325 0x80, 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 ,
66326 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 0x80, 0x80, 0x80, 0x80, 63 ,
66327 0x80, 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 ,
66328 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 0x80, 0x80, 0x80, 0x80, 0x80,
66329 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
66330 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
66331 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
66332 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
66333 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
66334 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
66335 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
66336 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
66337};
66338
66339unsigned char *
66340UA_unbase64(const unsigned char *src, size_t len, size_t *out_len) {
66341 /* Empty base64 results in an empty byte-string */
66342 if(len == 0) {
66343 *out_len = 0;
66344 return (unsigned char*)UA_EMPTY_ARRAY_SENTINEL;
66345 }
66346
66347 /* The input length must be a multiple of four */
66348 if(len % 4 != 0)
66349 return NULL;
66350
66351 /* Allocate the output string */
66352 size_t olen = len / 4 * 3;
66353 unsigned char *out = (unsigned char*)UA_malloc(size: olen);
66354 if(!out)
66355 return NULL;
66356
66357 /* Iterate over the input */
66358 size_t pad = 0;
66359 unsigned char count = 0;
66360 unsigned char block[4];
66361 unsigned char *pos = out;
66362 for(size_t i = 0; i < len; i++) {
66363 unsigned char tmp = dtable[src[i]];
66364 if(tmp == 0x80)
66365 goto error; /* Invalid input */
66366
66367 if(src[i] == '=')
66368 pad++;
66369
66370 block[count] = tmp;
66371 count++;
66372 if(count == 4) {
66373 *pos++ = (unsigned char)((block[0] << 2) | (block[1] >> 4));
66374 *pos++ = (unsigned char)((block[1] << 4) | (block[2] >> 2));
66375 *pos++ = (unsigned char)((block[2] << 6) | block[3]);
66376 if(pad) {
66377 if(pad == 1)
66378 pos--;
66379 else if(pad == 2)
66380 pos -= 2;
66381 else
66382 goto error; /* Invalid padding */
66383 break;
66384 }
66385 count = 0;
66386 }
66387 }
66388
66389 *out_len = (size_t)(pos - out);
66390 return out;
66391
66392 error:
66393 UA_free(ptr: out);
66394 return NULL;
66395}
66396
66397/**** amalgamated original file "/deps/dtoa.c" ****/
66398
66399// Copyright 2013, Andreas Samoljuk
66400// Copyright 2023, Julius Pfrommer
66401//
66402// Boost Software License - Version 1.0 - August 17th, 2003
66403//
66404// Permission is hereby granted, free of charge, to any person or organization
66405// obtaining a copy of the software and accompanying documentation covered by
66406// this license (the "Software") to use, reproduce, display, distribute,
66407// execute, and transmit the Software, and to prepare derivative works of the
66408// Software, and to permit third-parties to whom the Software is furnished to
66409// do so, all subject to the following:
66410//
66411// The copyright notices in the Software and this entire statement, including
66412// the above license grant, this restriction and the following disclaimer,
66413// must be included in all copies of the Software, in whole or in part, and
66414// all derivative works of the Software, unless such copies or derivative
66415// works are solely in the form of machine-executable object code generated by
66416// a source language processor.
66417//
66418// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
66419// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
66420// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
66421// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
66422// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
66423// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
66424// DEALINGS IN THE SOFTWARE.
66425
66426#include <stdint.h>
66427#include <stdbool.h>
66428#include <string.h>
66429
66430#define mantissa_bits 52
66431#define exponent_bits 11
66432#define fracmask 0x000FFFFFFFFFFFFFU
66433#define expmask 0x7FF0000000000000U
66434#define hiddenbit 0x0010000000000000U
66435#define signmask 0x8000000000000000U
66436#define expbias (1023 + 52)
66437
66438#define absv(n) ((n) < 0 ? -(n) : (n))
66439#define minv(a, b) ((a) < (b) ? (a) : (b))
66440
66441static uint64_t tens[] = {
66442 10000000000000000000U, 1000000000000000000U, 100000000000000000U,
66443 10000000000000000U, 1000000000000000U, 100000000000000U,
66444 10000000000000U, 1000000000000U, 100000000000U,
66445 10000000000U, 1000000000U, 100000000U,
66446 10000000U, 1000000U, 100000U,
66447 10000U, 1000U, 100U,
66448 10U, 1U
66449};
66450
66451#define npowers 87
66452#define steppowers 8
66453#define firstpower -348 /* 10 ^ -348 */
66454#define expmax -32
66455#define expmin -60
66456
66457typedef struct Fp {
66458 uint64_t frac;
66459 int exp;
66460} Fp;
66461
66462static Fp powers_ten[] = {
66463 { 18054884314459144840U, -1220 }, { 13451937075301367670U, -1193 },
66464 { 10022474136428063862U, -1166 }, { 14934650266808366570U, -1140 },
66465 { 11127181549972568877U, -1113 }, { 16580792590934885855U, -1087 },
66466 { 12353653155963782858U, -1060 }, { 18408377700990114895U, -1034 },
66467 { 13715310171984221708U, -1007 }, { 10218702384817765436U, -980 },
66468 { 15227053142812498563U, -954 }, { 11345038669416679861U, -927 },
66469 { 16905424996341287883U, -901 }, { 12595523146049147757U, -874 },
66470 { 9384396036005875287U, -847 }, { 13983839803942852151U, -821 },
66471 { 10418772551374772303U, -794 }, { 15525180923007089351U, -768 },
66472 { 11567161174868858868U, -741 }, { 17236413322193710309U, -715 },
66473 { 12842128665889583758U, -688 }, { 9568131466127621947U, -661 },
66474 { 14257626930069360058U, -635 }, { 10622759856335341974U, -608 },
66475 { 15829145694278690180U, -582 }, { 11793632577567316726U, -555 },
66476 { 17573882009934360870U, -529 }, { 13093562431584567480U, -502 },
66477 { 9755464219737475723U, -475 }, { 14536774485912137811U, -449 },
66478 { 10830740992659433045U, -422 }, { 16139061738043178685U, -396 },
66479 { 12024538023802026127U, -369 }, { 17917957937422433684U, -343 },
66480 { 13349918974505688015U, -316 }, { 9946464728195732843U, -289 },
66481 { 14821387422376473014U, -263 }, { 11042794154864902060U, -236 },
66482 { 16455045573212060422U, -210 }, { 12259964326927110867U, -183 },
66483 { 18268770466636286478U, -157 }, { 13611294676837538539U, -130 },
66484 { 10141204801825835212U, -103 }, { 15111572745182864684U, -77 },
66485 { 11258999068426240000U, -50 }, { 16777216000000000000U, -24 },
66486 { 12500000000000000000U, 3 }, { 9313225746154785156U, 30 },
66487 { 13877787807814456755U, 56 }, { 10339757656912845936U, 83 },
66488 { 15407439555097886824U, 109 }, { 11479437019748901445U, 136 },
66489 { 17105694144590052135U, 162 }, { 12744735289059618216U, 189 },
66490 { 9495567745759798747U, 216 }, { 14149498560666738074U, 242 },
66491 { 10542197943230523224U, 269 }, { 15709099088952724970U, 295 },
66492 { 11704190886730495818U, 322 }, { 17440603504673385349U, 348 },
66493 { 12994262207056124023U, 375 }, { 9681479787123295682U, 402 },
66494 { 14426529090290212157U, 428 }, { 10748601772107342003U, 455 },
66495 { 16016664761464807395U, 481 }, { 11933345169920330789U, 508 },
66496 { 17782069995880619868U, 534 }, { 13248674568444952270U, 561 },
66497 { 9871031767461413346U, 588 }, { 14708983551653345445U, 614 },
66498 { 10959046745042015199U, 641 }, { 16330252207878254650U, 667 },
66499 { 12166986024289022870U, 694 }, { 18130221999122236476U, 720 },
66500 { 13508068024458167312U, 747 }, { 10064294952495520794U, 774 },
66501 { 14996968138956309548U, 800 }, { 11173611982879273257U, 827 },
66502 { 16649979327439178909U, 853 }, { 12405201291620119593U, 880 },
66503 { 9242595204427927429U, 907 }, { 13772540099066387757U, 933 },
66504 { 10261342003245940623U, 960 }, { 15290591125556738113U, 986 },
66505 { 11392378155556871081U, 1013 }, { 16975966327722178521U, 1039 },
66506 { 12648080533535911531U, 1066 }
66507};
66508
66509static Fp
66510find_cachedpow10(int exp, int* k) {
66511 const double one_log_ten = 0.30102999566398114;
66512 int approx = (int)(-(exp + npowers) * one_log_ten);
66513 int idx = (approx - firstpower) / steppowers;
66514 while(1) {
66515 int current = exp + powers_ten[idx].exp + 64;
66516 if(current < expmin) {
66517 idx++;
66518 continue;
66519 }
66520 if(current > expmax) {
66521 idx--;
66522 continue;
66523 }
66524 *k = (firstpower + idx * steppowers);
66525 return powers_ten[idx];
66526 }
66527}
66528
66529static Fp build_fp(uint64_t bits) {
66530 Fp fp;
66531 fp.frac = bits & fracmask;
66532 fp.exp = (bits & expmask) >> 52;
66533 if(fp.exp) {
66534 fp.frac += hiddenbit;
66535 fp.exp -= expbias;
66536 } else {
66537 fp.exp = -expbias + 1;
66538 }
66539 return fp;
66540}
66541
66542static void normalize(Fp* fp) {
66543 while((fp->frac & hiddenbit) == 0) {
66544 fp->frac <<= 1;
66545 fp->exp--;
66546 }
66547 int shift = 64 - 52 - 1;
66548 fp->frac <<= shift;
66549 fp->exp -= shift;
66550}
66551
66552static void get_normalized_boundaries(Fp* fp, Fp* lower, Fp* upper) {
66553 upper->frac = (fp->frac << 1) + 1;
66554 upper->exp = fp->exp - 1;
66555 while ((upper->frac & (hiddenbit << 1)) == 0) {
66556 upper->frac <<= 1;
66557 upper->exp--;
66558 }
66559
66560 int u_shift = 64 - 52 - 2;
66561 upper->frac <<= u_shift;
66562 upper->exp = upper->exp - u_shift;
66563
66564 int l_shift = fp->frac == hiddenbit ? 2 : 1;
66565 lower->frac = (fp->frac << l_shift) - 1;
66566 lower->exp = fp->exp - l_shift;
66567 lower->frac <<= lower->exp - upper->exp;
66568 lower->exp = upper->exp;
66569}
66570
66571static Fp multiply(Fp* a, Fp* b) {
66572 const uint64_t lomask = 0x00000000FFFFFFFF;
66573 uint64_t ah_bl = (a->frac >> 32) * (b->frac & lomask);
66574 uint64_t al_bh = (a->frac & lomask) * (b->frac >> 32);
66575 uint64_t al_bl = (a->frac & lomask) * (b->frac & lomask);
66576 uint64_t ah_bh = (a->frac >> 32) * (b->frac >> 32);
66577 uint64_t tmp = (ah_bl & lomask) + (al_bh & lomask) + (al_bl >> 32);
66578 /* round up */
66579 tmp += 1U << 31;
66580 Fp fp;
66581 fp.frac = ah_bh + (ah_bl >> 32) + (al_bh >> 32) + (tmp >> 32);
66582 fp.exp = a->exp + b->exp + 64;
66583 return fp;
66584}
66585
66586static void round_digit(char* digits, unsigned ndigits, uint64_t delta,
66587 uint64_t rem, uint64_t kappa, uint64_t frac) {
66588 while(rem < frac && delta - rem >= kappa &&
66589 (rem + kappa < frac || frac - rem > rem + kappa - frac)) {
66590 digits[ndigits - 1]--;
66591 rem += kappa;
66592 }
66593}
66594
66595static unsigned generate_digits(Fp* fp, Fp* upper, Fp* lower, char* digits, int* K) {
66596 uint64_t wfrac = upper->frac - fp->frac;
66597 uint64_t delta = upper->frac - lower->frac;
66598
66599 Fp one;
66600 one.frac = 1ULL << -upper->exp;
66601 one.exp = upper->exp;
66602
66603 uint64_t part1 = upper->frac >> -one.exp;
66604 uint64_t part2 = upper->frac & (one.frac - 1);
66605
66606 unsigned idx = 0;
66607 int kappa = 10;
66608 uint64_t* divp;
66609
66610 /* 1000000000 */
66611 for(divp = tens + 10; kappa > 0; divp++) {
66612 uint64_t div = *divp;
66613 uint64_t digit = part1 / div;
66614 if(digit || idx) {
66615 digits[idx++] = (char)(digit + '0');
66616 }
66617
66618 part1 -= digit * div;
66619 kappa--;
66620
66621 uint64_t tmp = (part1 <<-one.exp) + part2;
66622 if(tmp <= delta) {
66623 *K += kappa;
66624 round_digit(digits, ndigits: idx, delta, rem: tmp, kappa: div << -one.exp, frac: wfrac);
66625 return idx;
66626 }
66627 }
66628
66629 /* 10 */
66630 uint64_t* unit = tens + 18;
66631 while(true) {
66632 part2 *= 10;
66633 delta *= 10;
66634 kappa--;
66635
66636 uint64_t digit = part2 >> -one.exp;
66637 if(digit || idx) {
66638 digits[idx++] = (char)(digit + '0');
66639 }
66640
66641 part2 &= one.frac - 1;
66642 if(part2 < delta) {
66643 *K += kappa;
66644 round_digit(digits, ndigits: idx, delta, rem: part2, kappa: one.frac, frac: wfrac * *unit);
66645 break;
66646 }
66647 unit--;
66648 }
66649 return idx;
66650}
66651
66652static unsigned grisu2(uint64_t bits, char* digits, int* K) {
66653 Fp w = build_fp(bits);
66654 Fp lower, upper;
66655 get_normalized_boundaries(fp: &w, lower: &lower, upper: &upper);
66656 normalize(fp: &w);
66657 int k;
66658 Fp cp = find_cachedpow10(exp: upper.exp, k: &k);
66659 w = multiply(a: &w, b: &cp);
66660 upper = multiply(a: &upper, b: &cp);
66661 lower = multiply(a: &lower, b: &cp);
66662 lower.frac++;
66663 upper.frac--;
66664 *K = -k;
66665 return generate_digits(fp: &w, upper: &upper, lower: &lower, digits, K);
66666}
66667
66668static unsigned
66669emit_digits(char* digits, unsigned ndigits, char* dest, int K, bool neg) {
66670 int exp = absv(K + (int)ndigits - 1);
66671
66672 /* write plain integer */
66673 if(K >= 0 && (exp < (int)ndigits + 7)) {
66674 memcpy(dest: dest, src: digits, n: ndigits);
66675 memset(s: dest + ndigits, c: '0', n: (unsigned)K);
66676 memcpy(dest: dest + ndigits + (unsigned)K, src: ".0", n: 2); /* always append .0 for naked integers */
66677 return (unsigned)(ndigits + (unsigned)K + 2);
66678 }
66679
66680 /* write decimal w/o scientific notation */
66681 if(K < 0 && (K > -7 || exp < 4)) {
66682 int offset = (int)ndigits - absv(K);
66683 if(offset <= 0) {
66684 /* fp < 1.0 -> write leading zero */
66685 offset = -offset;
66686 dest[0] = '0';
66687 dest[1] = '.';
66688 memset(s: dest + 2, c: '0', n: (size_t)offset);
66689 memcpy(dest: dest + offset + 2, src: digits, n: ndigits);
66690 return ndigits + 2 + (unsigned)offset;
66691 } else {
66692 /* fp > 1.0 */
66693 memcpy(dest: dest, src: digits, n: (size_t)offset);
66694 dest[offset] = '.';
66695 memcpy(dest: dest + offset + 1, src: digits + offset, n: ndigits - (unsigned)offset);
66696 return ndigits + 1;
66697 }
66698 }
66699
66700 /* write decimal w/ scientific notation */
66701 ndigits = minv(ndigits, (unsigned)(18 - neg));
66702 unsigned idx = 0;
66703 dest[idx++] = digits[0];
66704 if(ndigits > 1) {
66705 dest[idx++] = '.';
66706 memcpy(dest: dest + idx, src: digits + 1, n: ndigits - 1);
66707 idx += ndigits - 1;
66708 }
66709
66710 dest[idx++] = 'e';
66711
66712 char sign = K + (int)ndigits - 1 < 0 ? '-' : '+';
66713 dest[idx++] = sign;
66714
66715 int cent = 0;
66716 if(exp > 99) {
66717 cent = exp / 100;
66718 dest[idx++] = (char)(cent + '0');
66719 exp -= cent * 100;
66720 }
66721 if(exp > 9) {
66722 int dec = exp / 10;
66723 dest[idx++] = (char)(dec + '0');
66724 exp -= dec * 10;
66725
66726 } else if(cent) {
66727 dest[idx++] = '0';
66728 }
66729 dest[idx++] = (char)(exp % 10 + '0');
66730 return idx;
66731}
66732
66733unsigned dtoa(double d, char* buffer) {
66734 uint64_t bits = 0;
66735 memcpy(dest: &bits, src: &d, n: sizeof(double));
66736
66737 uint64_t mantissa = bits & ((1ull << mantissa_bits) - 1);
66738 uint32_t exponent = (uint32_t)
66739 ((bits >> mantissa_bits) & ((1u << exponent_bits) - 1));
66740
66741 if(exponent == 0 && mantissa == 0) {
66742 memcpy(dest: buffer, src: "0.0", n: 3);
66743 return 3;
66744 }
66745
66746 bool sign = ((bits >> (mantissa_bits + exponent_bits)) & 1) != 0;
66747 unsigned pos = 0;
66748 if(sign) {
66749 buffer[0] = '-';
66750 pos++;
66751 buffer++;
66752 }
66753
66754 if(exponent == ((1u << exponent_bits) - 1u)) {
66755 if(mantissa != 0) {
66756 memcpy(dest: buffer, src: "nan", n: 3);
66757 return 3;
66758 } else {
66759 memcpy(dest: &buffer[pos], src: "inf", n: 3);
66760 return pos + 3;
66761 }
66762 }
66763
66764 int K = 0;
66765 char digits[18];
66766 memset(s: digits, c: 0, n: 18);
66767 unsigned ndigits = grisu2(bits, digits, K: &K);
66768 return pos + emit_digits(digits, ndigits, dest: buffer, K, neg: sign);
66769}
66770
66771/**** amalgamated original file "/deps/mp_printf.c" ****/
66772
66773/**
66774 * @author (c) Julius Pfrommer
66775 * 2023, Fraunhofer IOSB, Germany
66776 * @author (c) Eyal Rozenberg <eyalroz1@gmx.com>
66777 * 2021-2023, Haifa, Palestine/Israel
66778 * @author (c) Marco Paland (info@paland.com)
66779 * 2014-2019, PALANDesign Hannover, Germany
66780 *
66781 * @note Others have made smaller contributions to this file: see the
66782 * contributors page at https://github.com/eyalroz/printf/graphs/contributors
66783 * or ask one of the authors. The original code for exponential specifiers was
66784 * contributed by Martijn Jasperse <m.jasperse@gmail.com>.
66785 *
66786 * @brief Small stand-alone implementation of the printf family of functions
66787 * (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems with
66788 * limited resources.
66789 *
66790 * @note the implementations are thread-safe; re-entrant; use no functions from
66791 * the standard library; and do not dynamically allocate any memory.
66792 *
66793 * @license The MIT License (MIT)
66794 *
66795 * Permission is hereby granted, free of charge, to any person obtaining a copy
66796 * of this software and associated documentation files (the "Software"), to deal
66797 * in the Software without restriction, including without limitation the rights
66798 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
66799 * copies of the Software, and to permit persons to whom the Software is
66800 * furnished to do so, subject to the following conditions:
66801 *
66802 * The above copyright notice and this permission notice shall be included in
66803 * all copies or substantial portions of the Software.
66804 *
66805 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
66806 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
66807 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
66808 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
66809 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
66810 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
66811 * THE SOFTWARE.
66812 */
66813
66814
66815#include <stdint.h>
66816#include <stdbool.h>
66817
66818// 'ntoa' conversion buffer size, this must be big enough to hold one converted
66819// numeric number including padded zeros (dynamically created on stack)
66820#define PRINTF_INTEGER_BUFFER_SIZE 32
66821
66822// size of the fixed (on-stack) buffer for printing individual decimal numbers.
66823// this must be big enough to hold one converted floating-point value including
66824// padded zeros.
66825#define PRINTF_DECIMAL_BUFFER_SIZE 32
66826
66827// Default precision for the floating point conversion specifiers (the C
66828// standard sets this at 6)
66829#define PRINTF_DEFAULT_FLOAT_PRECISION 6
66830
66831// internal flag definitions
66832#define FLAGS_ZEROPAD (1U << 0U)
66833#define FLAGS_LEFT (1U << 1U)
66834#define FLAGS_PLUS (1U << 2U)
66835#define FLAGS_SPACE (1U << 3U)
66836#define FLAGS_HASH (1U << 4U)
66837#define FLAGS_UPPERCASE (1U << 5U)
66838#define FLAGS_CHAR (1U << 6U)
66839#define FLAGS_SHORT (1U << 7U)
66840 // Only used with PRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS
66841#define FLAGS_LONG (1U << 9U)
66842#define FLAGS_LONG_LONG (1U << 10U)
66843#define FLAGS_PRECISION (1U << 11U)
66844#define FLAGS_ADAPT_EXP (1U << 12U)
66845#define FLAGS_POINTER (1U << 13U)
66846 // Note: Similar, but not identical, effect as FLAGS_HASH
66847#define FLAGS_SIGNED (1U << 14U)
66848
66849#define BASE_BINARY 2
66850#define BASE_OCTAL 8
66851#define BASE_DECIMAL 10
66852#define BASE_HEX 16
66853
66854typedef unsigned int printf_flags_t;
66855typedef uint8_t numeric_base_t;
66856typedef unsigned long long printf_unsigned_value_t;
66857typedef long long printf_signed_value_t;
66858
66859// Note in particular the behavior here on LONG_MIN or LLONG_MIN; it is valid
66860// and well-defined, but if you're not careful you can easily trigger undefined
66861// behavior with -LONG_MIN or -LLONG_MIN
66862#define ABS_FOR_PRINTING(_x) \
66863 ((printf_unsigned_value_t)((_x) > 0 ? (_x) : -((printf_signed_value_t)_x)))
66864
66865// internal secure strlen @return The length of the string (excluding the
66866// terminating 0) limited by 'maxsize' @note strlen uses size_t, but wes only
66867// use this function with size_t variables - hence the signature.
66868static size_t
66869strnlen_s_(const char *str, size_t maxsize) {
66870 for(size_t i = 0; i < maxsize; i++) {
66871 if(!str[i])
66872 return i;
66873 }
66874 return maxsize;
66875}
66876
66877// internal test if char is a digit (0-9)
66878// @return true if char is a digit
66879static bool is_digit_(char ch) { return (ch >= '0') && (ch <= '9'); }
66880
66881// internal ASCII string to size_t conversion
66882static size_t
66883atou_(const char **str) {
66884 size_t i = 0U;
66885 while(is_digit_(ch: **str)) {
66886 i = i * 10U + (size_t)(*((*str)++) - '0');
66887 }
66888 return i;
66889}
66890
66891// Output buffer
66892typedef struct {
66893 char *buffer;
66894 size_t pos;
66895 size_t max_chars;
66896} output_t;
66897
66898static void
66899putchar_(output_t *out, char c) {
66900 size_t write_pos = out->pos++;
66901 // We're _always_ increasing pos, so as to count how may characters
66902 // _would_ have been written if not for the max_chars limitation
66903 if(write_pos >= out->max_chars)
66904 return;
66905 // it must be the case that out->buffer != NULL , due to the constraint
66906 // on output_t ; and note we're relying on write_pos being non-negative.
66907 out->buffer[write_pos] = c;
66908}
66909
66910static void
66911out_(output_t *out, const char *buf, size_t len) {
66912 if(out->pos < out->max_chars) {
66913 size_t write_len = len;
66914 if(out->pos + len > out->max_chars)
66915 write_len = out->max_chars - out->pos;
66916 for(size_t i = 0; i < write_len; i++)
66917 out->buffer[out->pos + i] = buf[i];
66918 }
66919 out->pos += len; // Always increase pos by len
66920}
66921
66922// output the specified string in reverse, taking care of any zero-padding
66923static void
66924out_rev_(output_t *output, const char *buf, size_t len, size_t width,
66925 printf_flags_t flags) {
66926 const size_t start_pos = output->pos;
66927
66928 // pad spaces up to given width
66929 if(!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) {
66930 for(size_t i = len; i < width; i++) {
66931 putchar_(out: output, c: ' ');
66932 }
66933 }
66934
66935 // reverse string
66936 while(len) {
66937 putchar_(out: output, c: buf[--len]);
66938 }
66939
66940 // append pad spaces up to given width
66941 if(flags & FLAGS_LEFT) {
66942 while(output->pos - start_pos < width) {
66943 putchar_(out: output, c: ' ');
66944 }
66945 }
66946}
66947
66948// Invoked by print_integer after the actual number has been printed, performing
66949// necessary work on the number's prefix (as the number is initially printed in
66950// reverse order)
66951static void
66952print_integer_finalization(output_t *output, char *buf, size_t len, bool negative,
66953 numeric_base_t base, size_t precision, size_t width,
66954 printf_flags_t flags) {
66955 size_t unpadded_len = len;
66956
66957 // pad with leading zeros
66958 if(!(flags & FLAGS_LEFT)) {
66959 if(width && (flags & FLAGS_ZEROPAD) &&
66960 (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
66961 width--;
66962 }
66963 while((flags & FLAGS_ZEROPAD) && (len < width) &&
66964 (len < PRINTF_INTEGER_BUFFER_SIZE)) {
66965 buf[len++] = '0';
66966 }
66967 }
66968
66969 while((len < precision) && (len < PRINTF_INTEGER_BUFFER_SIZE)) {
66970 buf[len++] = '0';
66971 }
66972
66973 if(base == BASE_OCTAL && (len > unpadded_len)) {
66974 // Since we've written some zeros, we've satisfied the alternative format
66975 // leading space requirement
66976 flags &= ~FLAGS_HASH;
66977 }
66978
66979 // handle hash
66980 if(flags & (FLAGS_HASH | FLAGS_POINTER)) {
66981 if(!(flags & FLAGS_PRECISION) && len && ((len == precision) || (len == width))) {
66982 // Let's take back some padding digits to fit in what will eventually be
66983 // the format-specific prefix
66984 if(unpadded_len < len) {
66985 len--; // This should suffice for BASE_OCTAL
66986 }
66987 if(len && (base == BASE_HEX || base == BASE_BINARY) && (unpadded_len < len)) {
66988 len--; // ... and an extra one for 0x or 0b
66989 }
66990 }
66991 if((base == BASE_HEX) && !(flags & FLAGS_UPPERCASE) &&
66992 (len < PRINTF_INTEGER_BUFFER_SIZE)) {
66993 buf[len++] = 'x';
66994 } else if((base == BASE_HEX) && (flags & FLAGS_UPPERCASE) &&
66995 (len < PRINTF_INTEGER_BUFFER_SIZE)) {
66996 buf[len++] = 'X';
66997 } else if((base == BASE_BINARY) && (len < PRINTF_INTEGER_BUFFER_SIZE)) {
66998 buf[len++] = 'b';
66999 }
67000 if(len < PRINTF_INTEGER_BUFFER_SIZE) {
67001 buf[len++] = '0';
67002 }
67003 }
67004
67005 if(len < PRINTF_INTEGER_BUFFER_SIZE) {
67006 if(negative) {
67007 buf[len++] = '-';
67008 } else if(flags & FLAGS_PLUS) {
67009 buf[len++] = '+'; // ignore the space if the '+' exists
67010 } else if(flags & FLAGS_SPACE) {
67011 buf[len++] = ' ';
67012 }
67013 }
67014
67015 out_rev_(output, buf, len, width, flags);
67016}
67017
67018// An internal itoa-like function
67019static void
67020print_integer(output_t *output, printf_unsigned_value_t value, bool negative,
67021 numeric_base_t base, size_t precision, size_t width, printf_flags_t flags) {
67022 char buf[PRINTF_INTEGER_BUFFER_SIZE];
67023 size_t len = 0U;
67024
67025 if(!value) {
67026 if(!(flags & FLAGS_PRECISION)) {
67027 buf[len++] = '0';
67028 flags &= ~FLAGS_HASH;
67029 // We drop this flag this since either the alternative and regular modes
67030 // of the specifier don't differ on 0 values, or (in the case of octal)
67031 // we've already provided the special handling for this mode.
67032 } else if(base == BASE_HEX) {
67033 flags &= ~FLAGS_HASH;
67034 // We drop this flag this since either the alternative and regular modes
67035 // of the specifier don't differ on 0 values
67036 }
67037 } else {
67038 do {
67039 const char digit = (char)(value % base);
67040 buf[len++] =
67041 (char)(digit < 10 ? '0' + digit
67042 : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10);
67043 value /= base;
67044 } while(value && (len < PRINTF_INTEGER_BUFFER_SIZE));
67045 }
67046
67047 print_integer_finalization(output, buf, len, negative, base, precision, width, flags);
67048}
67049
67050static void
67051print_floating_point(output_t *output, double value, size_t precision,
67052 size_t width, printf_flags_t flags) {
67053 if((flags & FLAGS_PLUS) && value > 0.0)
67054 putchar_(out: output, c: '+');
67055
67056 // set default precision, if not set explicitly
67057 //if(!(flags & FLAGS_PRECISION) || precision > PRINTF_DECIMAL_BUFFER_SIZE - 5)
67058 // precision = PRINTF_DEFAULT_FLOAT_PRECISION;
67059
67060 char buf[PRINTF_DECIMAL_BUFFER_SIZE];
67061 unsigned len = dtoa(d: value, buffer: buf); // Fill the buffer (TODO: Consider precision)
67062 out_(out: output, buf, len); // Print the buffer
67063}
67064
67065// Advances the format pointer past the flags, and returns the parsed flags
67066// due to the characters passed
67067static printf_flags_t
67068parse_flags(const char **format) {
67069 printf_flags_t flags = 0U;
67070 do {
67071 switch(**format) {
67072 case '0': flags |= FLAGS_ZEROPAD; break;
67073 case '-': flags |= FLAGS_LEFT; break;
67074 case '+': flags |= FLAGS_PLUS; break;
67075 case ' ': flags |= FLAGS_SPACE; break;
67076 case '#': flags |= FLAGS_HASH; break;
67077 default: return flags;
67078 }
67079 (*format)++;
67080 } while(true);
67081}
67082
67083#define ADVANCE_IN_FORMAT_STRING(cptr_) \
67084 do { \
67085 (cptr_)++; \
67086 if(!*(cptr_)) \
67087 return; \
67088 } while(0)
67089
67090static void
67091format_string_loop(output_t *output, const char *format, va_list args) {
67092 while(*format) {
67093 if(*format != '%') {
67094 // A regular content character
67095 putchar_(out: output, c: *format);
67096 format++;
67097 continue;
67098 }
67099 // We're parsing a format specifier: %[flags][width][.precision][length]
67100 ADVANCE_IN_FORMAT_STRING(format);
67101
67102 printf_flags_t flags = parse_flags(format: &format);
67103
67104 // evaluate width field
67105 size_t width = 0U;
67106 if(is_digit_(ch: *format)) {
67107 width = atou_(str: &format);
67108 } else if(*format == '*') {
67109 const int w = va_arg(args, int);
67110 if(w < 0) {
67111 flags |= FLAGS_LEFT; // reverse padding
67112 width = (size_t)-w;
67113 } else {
67114 width = (size_t)w;
67115 }
67116 ADVANCE_IN_FORMAT_STRING(format);
67117 }
67118
67119 // evaluate precision field
67120 size_t precision = 0U;
67121 if(*format == '.') {
67122 flags |= FLAGS_PRECISION;
67123 ADVANCE_IN_FORMAT_STRING(format);
67124 if(is_digit_(ch: *format)) {
67125 precision = atou_(str: &format);
67126 } else if(*format == '*') {
67127 const int precision_ = va_arg(args, int);
67128 precision = precision_ > 0 ? (size_t)precision_ : 0U;
67129 ADVANCE_IN_FORMAT_STRING(format);
67130 }
67131 }
67132
67133 // evaluate length field
67134 switch(*format) {
67135 case 'l':
67136 flags |= FLAGS_LONG;
67137 ADVANCE_IN_FORMAT_STRING(format);
67138 if(*format == 'l') {
67139 flags |= FLAGS_LONG_LONG;
67140 ADVANCE_IN_FORMAT_STRING(format);
67141 }
67142 break;
67143 case 'h':
67144 flags |= FLAGS_SHORT;
67145 ADVANCE_IN_FORMAT_STRING(format);
67146 if(*format == 'h') {
67147 flags |= FLAGS_CHAR;
67148 ADVANCE_IN_FORMAT_STRING(format);
67149 }
67150 break;
67151 case 't':
67152 flags |=
67153 (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
67154 ADVANCE_IN_FORMAT_STRING(format);
67155 break;
67156 case 'j':
67157 flags |=
67158 (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
67159 ADVANCE_IN_FORMAT_STRING(format);
67160 break;
67161 case 'z':
67162 flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
67163 ADVANCE_IN_FORMAT_STRING(format);
67164 break;
67165 default:
67166 break;
67167 }
67168
67169 // evaluate specifier
67170 switch(*format) {
67171 case 'd':
67172 case 'i':
67173 case 'u':
67174 case 'x':
67175 case 'X':
67176 case 'o':
67177 case 'b': {
67178 if(*format == 'd' || *format == 'i') {
67179 flags |= FLAGS_SIGNED;
67180 }
67181
67182 numeric_base_t base;
67183 if(*format == 'x' || *format == 'X') {
67184 base = BASE_HEX;
67185 } else if(*format == 'o') {
67186 base = BASE_OCTAL;
67187 } else if(*format == 'b') {
67188 base = BASE_BINARY;
67189 } else {
67190 base = BASE_DECIMAL;
67191 flags &=
67192 ~FLAGS_HASH; // decimal integers have no alternative presentation
67193 }
67194
67195 if(*format == 'X') {
67196 flags |= FLAGS_UPPERCASE;
67197 }
67198
67199 format++;
67200 // ignore '0' flag when precision is given
67201 if(flags & FLAGS_PRECISION) {
67202 flags &= ~FLAGS_ZEROPAD;
67203 }
67204
67205 if(flags & FLAGS_SIGNED) {
67206 // A signed specifier: d, i or possibly I + bit size if enabled
67207 if(flags & FLAGS_LONG_LONG) {
67208 const long long value = va_arg(args, long long);
67209 print_integer(output, ABS_FOR_PRINTING(value), negative: value < 0, base,
67210 precision, width, flags);
67211 } else if(flags & FLAGS_LONG) {
67212 const long value = va_arg(args, long);
67213 print_integer(output, ABS_FOR_PRINTING(value), negative: value < 0, base,
67214 precision, width, flags);
67215 } else {
67216 // We never try to interpret the argument as something
67217 // potentially-smaller than int, due to integer promotion rules:
67218 // Even if the user passed a short int, short unsigned etc. -
67219 // these will come in after promotion, as int's (or unsigned for
67220 // the case of short unsigned when it has the same size as int)
67221 const int value =
67222 (flags & FLAGS_CHAR) ? (signed char)va_arg(args, int)
67223 : (flags & FLAGS_SHORT) ? (short int)va_arg(args, int)
67224 : va_arg(args, int);
67225 print_integer(output, ABS_FOR_PRINTING(value), negative: value < 0, base,
67226 precision, width, flags);
67227 }
67228 } else {
67229 // An unsigned specifier: u, x, X, o, b
67230 flags &= ~(FLAGS_PLUS | FLAGS_SPACE);
67231
67232 if(flags & FLAGS_LONG_LONG) {
67233 print_integer(output, value: (printf_unsigned_value_t)
67234 va_arg(args, unsigned long long),
67235 false, base, precision, width, flags);
67236 } else if(flags & FLAGS_LONG) {
67237 print_integer(output, value: (printf_unsigned_value_t)
67238 va_arg(args, unsigned long),
67239 false, base, precision, width, flags);
67240 } else {
67241 const unsigned int value = (flags & FLAGS_CHAR)
67242 ? (unsigned char)va_arg(args, unsigned int)
67243 : (flags & FLAGS_SHORT)
67244 ? (unsigned short int)va_arg(args, unsigned int)
67245 : va_arg(args, unsigned int);
67246 print_integer(output, value: (printf_unsigned_value_t)value, false, base,
67247 precision, width, flags);
67248 }
67249 }
67250 break;
67251 }
67252
67253 case 'f':
67254 case 'F':
67255 if(*format == 'F')
67256 flags |= FLAGS_UPPERCASE;
67257 print_floating_point(output, value: (double)va_arg(args, double),
67258 precision, width, flags);
67259 format++;
67260 break;
67261
67262 case 'c': {
67263 size_t l = 1U;
67264 // pre padding
67265 if(!(flags & FLAGS_LEFT)) {
67266 while(l++ < width) {
67267 putchar_(out: output, c: ' ');
67268 }
67269 }
67270 // char output
67271 putchar_(out: output, c: (char)va_arg(args, int));
67272 // post padding
67273 if(flags & FLAGS_LEFT) {
67274 while(l++ < width) {
67275 putchar_(out: output, c: ' ');
67276 }
67277 }
67278 format++;
67279 break;
67280 }
67281
67282 case 's': {
67283 const char *p = va_arg(args, char *);
67284 if(p == NULL) {
67285 out_rev_(output, buf: ")llun(", len: 6, width, flags);
67286 } else {
67287 // string length
67288 size_t l = strnlen_s_(str: p, maxsize: precision ? precision : INT32_MAX);
67289 if(flags & FLAGS_PRECISION) {
67290 l = (l < precision ? l : precision);
67291 }
67292
67293 // pre padding
67294 if(!(flags & FLAGS_LEFT)) {
67295 for(size_t i = 0; l + i < width; i++) {
67296 putchar_(out: output, c: ' ');
67297 }
67298 }
67299
67300 // string output
67301 out_(out: output, buf: p, len: l);
67302
67303 // post padding
67304 if(flags & FLAGS_LEFT) {
67305 for(size_t i = 0; l + i < width; i++) {
67306 putchar_(out: output, c: ' ');
67307 }
67308 }
67309 }
67310 format++;
67311 break;
67312 }
67313
67314 case 'p': {
67315 width =
67316 sizeof(void *) * 2U + 2; // 2 hex chars per byte + the "0x" prefix
67317 flags |= FLAGS_ZEROPAD | FLAGS_POINTER;
67318 uintptr_t value = (uintptr_t)va_arg(args, void *);
67319 (value == (uintptr_t)NULL)
67320 ? out_rev_(output, buf: ")lin(", len: 5, width, flags)
67321 : print_integer(output, value: (printf_unsigned_value_t)value, false,
67322 BASE_HEX, precision, width, flags);
67323 format++;
67324 break;
67325 }
67326
67327 case '%':
67328 putchar_(out: output, c: '%');
67329 format++;
67330 break;
67331
67332 default:
67333 putchar_(out: output, c: *format);
67334 format++;
67335 break;
67336 }
67337 }
67338}
67339
67340int
67341mp_vsnprintf(char *s, size_t n, const char *format, va_list arg) {
67342 // Check that the inputs are sane
67343 if(!s || n < 1)
67344 return -1;
67345
67346 // Format the string
67347 output_t out = {s, 0, n};
67348 format_string_loop(output: &out, format, args: arg);
67349
67350 // Write the string-terminating '\0' character
67351 size_t null_char_pos = out.pos < out.max_chars ? out.pos : out.max_chars - 1;
67352 out.buffer[null_char_pos] = '\0';
67353
67354 // Return written chars without terminating \0
67355 return (int)out.pos;
67356}
67357
67358int
67359mp_snprintf(char *s, size_t n, const char *format, ...) {
67360 va_list args;
67361 va_start(args, format);
67362 const int ret = mp_vsnprintf(s, n, format, arg: args);
67363 va_end(args);
67364 return ret;
67365}
67366
67367/**** amalgamated original file "/deps/itoa.c" ****/
67368
67369/*
67370 * Copyright 2017 Techie Delight
67371 * Permission is hereby granted, free of charge, to any person obtaining a copy
67372 * of this software and associated documentation files (the "Software"), to deal
67373 * in the Software without restriction, including without limitation the rights
67374 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
67375 * copies of the Software, and to permit persons to whom the Software is
67376 * furnished to do so, subject to the following conditions:
67377 *
67378 * The above copyright notice and this permission notice shall be included
67379 * in all copies or substantial portions of the Software.
67380 *
67381 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
67382 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
67383 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
67384 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
67385 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
67386 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
67387 */
67388
67389/* Originally released by techiedelight.com
67390 * (http://www.techiedelight.com/implement-itoa-function-in-c/) under the
67391 * MIT license. */
67392
67393
67394static void swap(char *x, char *y) {
67395 char t = *x;
67396 *x = *y;
67397 *y = t;
67398}
67399
67400/* function to reverse buffer */
67401static char* reverse(char *buffer, UA_UInt16 i, UA_UInt16 j) {
67402 while (i < j)
67403 swap(x: &buffer[i++], y: &buffer[j--]);
67404
67405 return buffer;
67406}
67407
67408/* adapted from http://www.techiedelight.com/implement-itoa-function-in-c/ to use UA_... types */
67409UA_UInt16 itoaUnsigned(UA_UInt64 value, char* buffer, UA_Byte base) {
67410 /* consider absolute value of number */
67411 UA_UInt64 n = value;
67412
67413 UA_UInt16 i = 0;
67414 while (n) {
67415 UA_UInt64 r = n % base;
67416
67417 if (r >= 10)
67418 buffer[i++] = (char)(65 + (r - 10));
67419 else
67420 buffer[i++] = (char)(48 + r);
67421
67422 n = n / base;
67423 }
67424 /* if number is 0 */
67425 if (i == 0)
67426 buffer[i++] = '0';
67427
67428 buffer[i] = '\0'; /* null terminate string */
67429 i--;
67430 /* reverse the string */
67431 reverse(buffer, i: 0, j: i);
67432 i++;
67433 return i;
67434}
67435
67436/* adapted from http://www.techiedelight.com/implement-itoa-function-in-c/ */
67437UA_UInt16 itoaSigned(UA_Int64 value, char* buffer) {
67438 /* Special case for UA_INT64_MIN which can not simply be negated */
67439 /* it will cause a signed integer overflow */
67440 UA_UInt64 n;
67441 if(value == UA_INT64_MIN) {
67442 n = (UA_UInt64)UA_INT64_MAX + 1;
67443 } else {
67444 n = (UA_UInt64)value;
67445 if(value < 0){
67446 n = (UA_UInt64)-value;
67447 }
67448 }
67449
67450 UA_UInt16 i = 0;
67451 while(n) {
67452 UA_UInt64 r = n % 10;
67453 buffer[i++] = (char)('0' + r);
67454 n = n / 10;
67455 }
67456
67457 if(i == 0)
67458 buffer[i++] = '0'; /* if number is 0 */
67459 if(value < 0)
67460 buffer[i++] = '-';
67461 buffer[i] = '\0'; /* null terminate string */
67462 i--;
67463 reverse(buffer, i: 0, j: i); /* reverse the string and return it */
67464 i++;
67465 return i;
67466}
67467
67468
67469/**** amalgamated original file "/deps/ziptree.c" ****/
67470
67471/* This Source Code Form is subject to the terms of the Mozilla Public
67472 * License, v. 2.0. If a copy of the MPL was not distributed with this
67473 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
67474 *
67475 * Copyright 2021-2022 (c) Julius Pfrommer
67476 */
67477
67478
67479/* Dummy types */
67480struct zip_elem;
67481typedef struct zip_elem zip_elem;
67482typedef ZIP_ENTRY(zip_elem) zip_entry;
67483typedef ZIP_HEAD(, zip_elem) zip_head;
67484
67485/* Access macros */
67486#define ZIP_ENTRY_PTR(x) ((zip_entry*)((char*)x + fieldoffset))
67487#define ZIP_KEY_PTR(x) (const void*)((const char*)x + keyoffset)
67488
67489/* Hash pointers to keep the tie-breeaking of equal keys (mostly) uncorrelated
67490 * from the rank (pointer order). Hashing code taken from sdbm-hash
67491 * (http://www.cse.yorku.ca/~oz/hash.html). */
67492static unsigned int
67493__ZIP_PTR_HASH(const void *p) {
67494 unsigned int h = 0;
67495 const unsigned char *data = (const unsigned char*)&p;
67496 for(size_t i = 0; i < (sizeof(void*) / sizeof(char)); i++)
67497 h = data[i] + (h << 6) + (h << 16) - h;
67498 return h;
67499}
67500
67501static ZIP_INLINE enum ZIP_CMP
67502__ZIP_RANK_CMP(const void *p1, const void *p2) {
67503 /* assert(p1 != p2); */
67504 unsigned int h1 = __ZIP_PTR_HASH(p: p1);
67505 unsigned int h2 = __ZIP_PTR_HASH(p: p2);
67506 if(h1 == h2)
67507 return (p1 < p2) ? ZIP_CMP_LESS : ZIP_CMP_MORE;
67508 return (h1 < h2) ? ZIP_CMP_LESS : ZIP_CMP_MORE;
67509}
67510
67511static ZIP_INLINE enum ZIP_CMP
67512__ZIP_UNIQUE_CMP(zip_cmp_cb cmp, const void *p1, const void *p2) {
67513 if(p1 == p2)
67514 return ZIP_CMP_EQ;
67515 enum ZIP_CMP order = cmp(p1, p2);
67516 if(order == ZIP_CMP_EQ)
67517 return (p1 < p2) ? ZIP_CMP_LESS : ZIP_CMP_MORE;
67518 return order;
67519}
67520
67521#if 0
67522#include <assert.h>
67523ZIP_UNUSED static ZIP_INLINE void
67524__ZIP_VALIDATE(zip_cmp_cb cmp, unsigned short fieldoffset,
67525 unsigned short keyoffset, void *elm,
67526 void *min_elm, void *max_elm) {
67527 if(!elm)
67528 return;
67529 enum ZIP_CMP c1 = __ZIP_UNIQUE_CMP(cmp, ZIP_KEY_PTR(min_elm), ZIP_KEY_PTR(elm));
67530 assert((elm == min_elm && c1 == ZIP_CMP_EQ) || c1 == ZIP_CMP_LESS);
67531
67532 enum ZIP_CMP c2 = __ZIP_UNIQUE_CMP(cmp, ZIP_KEY_PTR(max_elm), ZIP_KEY_PTR(elm));
67533 assert((elm == max_elm && c2 == ZIP_CMP_EQ) || c2 == ZIP_CMP_MORE);
67534
67535 assert(!ZIP_ENTRY_PTR(elm)->right ||
67536 __ZIP_RANK_CMP(elm, ZIP_ENTRY_PTR(elm)->right) == ZIP_CMP_MORE);
67537 assert(!ZIP_ENTRY_PTR(elm)->left ||
67538 __ZIP_RANK_CMP(elm, ZIP_ENTRY_PTR(elm)->left) == ZIP_CMP_MORE);
67539
67540 __ZIP_VALIDATE(cmp, fieldoffset, keyoffset, ZIP_ENTRY_PTR(elm)->right, elm, max_elm);
67541 __ZIP_VALIDATE(cmp, fieldoffset, keyoffset, ZIP_ENTRY_PTR(elm)->left, min_elm, elm);
67542}
67543#endif
67544
67545/* Walk down the right-side spine of cur. Elements that are larger than x_key
67546 * are moved under x->right. */
67547static void
67548__ZIP_INSERT_MOVE_RIGHT(zip_cmp_cb cmp, unsigned short fieldoffset,
67549 unsigned short keyoffset, const void *x_key,
67550 zip_elem **fix_edge, zip_elem *cur) {
67551 while(ZIP_ENTRY_PTR(cur)->right) {
67552 zip_elem *move_candidate = ZIP_ENTRY_PTR(cur)->right;
67553 if(__ZIP_UNIQUE_CMP(cmp, p1: x_key, ZIP_KEY_PTR(move_candidate)) == ZIP_CMP_MORE) {
67554 cur = ZIP_ENTRY_PTR(cur)->right;
67555 continue;
67556 }
67557 ZIP_ENTRY_PTR(cur)->right = ZIP_ENTRY_PTR(move_candidate)->left;
67558 ZIP_ENTRY_PTR(move_candidate)->left = NULL;
67559 *fix_edge = move_candidate;
67560 fix_edge = &ZIP_ENTRY_PTR(move_candidate)->left;
67561 }
67562}
67563
67564static void
67565__ZIP_INSERT_MOVE_LEFT(zip_cmp_cb cmp, unsigned short fieldoffset,
67566 unsigned short keyoffset, const void *x_key,
67567 zip_elem **fix_edge, zip_elem *cur) {
67568 while(ZIP_ENTRY_PTR(cur)->left) {
67569 zip_elem *move_candidate = ZIP_ENTRY_PTR(cur)->left;
67570 if(__ZIP_UNIQUE_CMP(cmp, p1: x_key, ZIP_KEY_PTR(move_candidate)) == ZIP_CMP_LESS) {
67571 cur = ZIP_ENTRY_PTR(cur)->left;
67572 continue;
67573 }
67574 ZIP_ENTRY_PTR(cur)->left = ZIP_ENTRY_PTR(move_candidate)->right;
67575 ZIP_ENTRY_PTR(move_candidate)->right = NULL;
67576 *fix_edge = move_candidate;
67577 fix_edge = &ZIP_ENTRY_PTR(move_candidate)->right;
67578 }
67579}
67580
67581void
67582__ZIP_INSERT(void *h, zip_cmp_cb cmp, unsigned short fieldoffset,
67583 unsigned short keyoffset, void *elm) {
67584 zip_elem *x = (zip_elem*)elm;
67585 ZIP_ENTRY_PTR(x)->left = NULL;
67586 ZIP_ENTRY_PTR(x)->right = NULL;
67587
67588 const void *x_key = ZIP_KEY_PTR(x);
67589 zip_head *head = (zip_head*)h;
67590 if(!head->root) {
67591 head->root = x;
67592 return;
67593 }
67594
67595 /* Go down the tree to find the top element "cur" that has a rank smaller
67596 * than "x" */
67597 zip_elem *prev = NULL;
67598 zip_elem *cur = head->root;
67599 enum ZIP_CMP cur_order, prev_order;
67600 do {
67601 cur_order = __ZIP_UNIQUE_CMP(cmp, p1: x_key, ZIP_KEY_PTR(cur));
67602 if(cur_order == ZIP_CMP_EQ)
67603 return; /* x is already inserted */
67604 if(__ZIP_RANK_CMP(p1: cur, p2: x) == ZIP_CMP_LESS)
67605 break;
67606 prev = cur;
67607 prev_order = cur_order;
67608 cur = (cur_order == ZIP_CMP_MORE) ?
67609 ZIP_ENTRY_PTR(cur)->right : ZIP_ENTRY_PTR(cur)->left;
67610 } while(cur);
67611
67612 /* Insert "x" instead of "cur" under its parent "prev" */
67613 if(cur == head->root) {
67614 head->root = x;
67615 } else {
67616 if(prev_order == ZIP_CMP_MORE)
67617 ZIP_ENTRY_PTR(prev)->right = x;
67618 else
67619 ZIP_ENTRY_PTR(prev)->left = x;
67620 }
67621
67622 if(!cur)
67623 return;
67624
67625 /* Re-insert "cur" under "x". Repair by moving elements that ended up on the
67626 * wrong side of "x". */
67627 if(cur_order == ZIP_CMP_MORE) {
67628 ZIP_ENTRY_PTR(x)->left = cur;
67629 __ZIP_INSERT_MOVE_RIGHT(cmp, fieldoffset, keyoffset,
67630 x_key, fix_edge: &ZIP_ENTRY_PTR(x)->right, cur);
67631 } else {
67632 ZIP_ENTRY_PTR(x)->right = cur;
67633 __ZIP_INSERT_MOVE_LEFT(cmp, fieldoffset, keyoffset,
67634 x_key, fix_edge: &ZIP_ENTRY_PTR(x)->left, cur);
67635 }
67636}
67637
67638void *
67639__ZIP_REMOVE(void *h, zip_cmp_cb cmp, unsigned short fieldoffset,
67640 unsigned short keyoffset, void *elm) {
67641 zip_head *head = (zip_head*)h;
67642 zip_elem *x = (zip_elem*)elm;
67643 zip_elem *cur = head->root;
67644 if(!cur)
67645 return NULL;
67646
67647 const void *x_key = ZIP_KEY_PTR(x);
67648 zip_elem **prev_edge = &head->root;
67649 enum ZIP_CMP cur_order = __ZIP_UNIQUE_CMP(cmp, p1: x_key, ZIP_KEY_PTR(cur));
67650 while(cur_order != ZIP_CMP_EQ) {
67651 prev_edge = (cur_order == ZIP_CMP_LESS) ?
67652 &ZIP_ENTRY_PTR(cur)->left : &ZIP_ENTRY_PTR(cur)->right;
67653 cur = *prev_edge;
67654 if(!cur)
67655 return NULL;
67656 cur_order = __ZIP_UNIQUE_CMP(cmp, p1: x_key, ZIP_KEY_PTR(cur));
67657 }
67658 *prev_edge = (zip_elem*)__ZIP_ZIP(fieldoffset,
67659 ZIP_ENTRY_PTR(cur)->left,
67660 ZIP_ENTRY_PTR(cur)->right);
67661 return cur;
67662}
67663
67664void *
67665__ZIP_ITER(unsigned short fieldoffset, zip_iter_cb cb,
67666 void *context, void *elm) {
67667 if(!elm)
67668 return NULL;
67669 zip_elem *left = ZIP_ENTRY_PTR(elm)->left;
67670 zip_elem *right = ZIP_ENTRY_PTR(elm)->right;
67671 void *res = __ZIP_ITER(fieldoffset, cb, context, elm: left);
67672 if(res)
67673 return res;
67674 res = cb(context, elm);
67675 if(res)
67676 return res;
67677 return __ZIP_ITER(fieldoffset, cb, context, elm: right);
67678}
67679
67680void *
67681__ZIP_ITER_KEY(zip_cmp_cb cmp, unsigned short fieldoffset,
67682 unsigned short keyoffset, const void *key,
67683 zip_iter_cb cb, void *context, void *elm) {
67684 if(!elm)
67685 return NULL;
67686
67687 void *res;
67688 enum ZIP_CMP eq = cmp(key, ZIP_KEY_PTR(elm));
67689 if(eq != ZIP_CMP_MORE) {
67690 res = __ZIP_ITER_KEY(cmp, fieldoffset, keyoffset, key,
67691 cb, context, ZIP_ENTRY_PTR(elm)->left);
67692 if(res)
67693 return res;
67694 }
67695
67696 if(eq == ZIP_CMP_EQ) {
67697 res = cb(context, elm);
67698 if(res)
67699 return res;
67700 }
67701
67702 if(eq != ZIP_CMP_LESS) {
67703 res = __ZIP_ITER_KEY(cmp, fieldoffset, keyoffset, key,
67704 cb, context, ZIP_ENTRY_PTR(elm)->right);
67705 if(res)
67706 return res;
67707 }
67708
67709 return NULL;
67710}
67711
67712void *
67713__ZIP_ZIP(unsigned short fieldoffset, void *left, void *right) {
67714 if(!left)
67715 return right;
67716 if(!right)
67717 return left;
67718 zip_elem *l = (zip_elem*)left;
67719 zip_elem *r = (zip_elem*)right;
67720 zip_elem *root = NULL;
67721 zip_elem **prev_edge = &root;
67722 while(l && r) {
67723 if(__ZIP_RANK_CMP(p1: l, p2: r) == ZIP_CMP_LESS) {
67724 *prev_edge = r;
67725 prev_edge = &ZIP_ENTRY_PTR(r)->left;
67726 r = ZIP_ENTRY_PTR(r)->left;
67727 } else {
67728 *prev_edge = l;
67729 prev_edge = &ZIP_ENTRY_PTR(l)->right;
67730 l = ZIP_ENTRY_PTR(l)->right;
67731 }
67732 }
67733 *prev_edge = (l) ? l : r;
67734 return root;
67735}
67736
67737/* Walk down from cur and move all elements <= split-key to the left side. All
67738 * elements that are moved over have to be below left_rightmost. Returns the
67739 * hierarchy of elements that remain on the right side. */
67740static void
67741__ZIP_UNZIP_MOVE_LEFT(zip_cmp_cb cmp, unsigned short fieldoffset,
67742 unsigned short keyoffset, const void *key,
67743 zip_elem **fix_edge, zip_elem *cur) {
67744 while(ZIP_ENTRY_PTR(cur)->left) {
67745 zip_elem *next = ZIP_ENTRY_PTR(cur)->left;
67746 if(cmp(key, ZIP_KEY_PTR(next)) == ZIP_CMP_LESS) {
67747 cur = next;
67748 continue;
67749 }
67750 *fix_edge = next;
67751 ZIP_ENTRY_PTR(cur)->left = ZIP_ENTRY_PTR(next)->right;
67752 ZIP_ENTRY_PTR(next)->right = NULL;
67753 fix_edge = &ZIP_ENTRY_PTR(next)->right;
67754 }
67755}
67756
67757static void
67758__ZIP_UNZIP_MOVE_RIGHT(zip_cmp_cb cmp, unsigned short fieldoffset,
67759 unsigned short keyoffset, const void *key,
67760 zip_elem **fix_edge, zip_elem *cur) {
67761 while(ZIP_ENTRY_PTR(cur)->right) {
67762 zip_elem *next = ZIP_ENTRY_PTR(cur)->right;
67763 if(cmp(key, ZIP_KEY_PTR(next)) != ZIP_CMP_LESS) {
67764 cur = next;
67765 continue;
67766 }
67767 *fix_edge = next;
67768 ZIP_ENTRY_PTR(cur)->right = ZIP_ENTRY_PTR(next)->left;
67769 ZIP_ENTRY_PTR(next)->left = NULL;
67770 fix_edge = &ZIP_ENTRY_PTR(next)->left;
67771 }
67772}
67773
67774/* Split the tree into a left side with keys <= split-key and a right side with
67775 * key > split-key. */
67776void
67777__ZIP_UNZIP(zip_cmp_cb cmp, unsigned short fieldoffset,
67778 unsigned short keyoffset, const void *key,
67779 void *h, void *l, void *r) {
67780 zip_elem *prev;
67781 zip_head *head = (zip_head*)h;
67782 zip_head *left = (zip_head*)l;
67783 zip_head *right = (zip_head*)r;
67784 if(!head->root) {
67785 left->root = NULL;
67786 right->root = NULL;
67787 return;
67788 }
67789 zip_elem *cur = head->root;
67790 if(cmp(key, ZIP_KEY_PTR(cur)) != ZIP_CMP_LESS) {
67791 left->root = cur;
67792 do {
67793 prev = cur;
67794 cur = ZIP_ENTRY_PTR(cur)->right;
67795 if(!cur) {
67796 right->root = NULL;
67797 return;
67798 }
67799 } while(cmp(key, ZIP_KEY_PTR(cur)) != ZIP_CMP_LESS);
67800 ZIP_ENTRY_PTR(prev)->right = NULL;
67801 right->root = cur;
67802 __ZIP_UNZIP_MOVE_LEFT(cmp, fieldoffset, keyoffset, key,
67803 fix_edge: &ZIP_ENTRY_PTR(prev)->right, cur);
67804 } else {
67805 right->root = cur;
67806 do {
67807 prev = cur;
67808 cur = ZIP_ENTRY_PTR(cur)->left;
67809 if(!cur) {
67810 left->root = NULL;
67811 return;
67812 }
67813 } while(cmp(key, ZIP_KEY_PTR(cur)) == ZIP_CMP_LESS);
67814 ZIP_ENTRY_PTR(prev)->left = NULL;
67815 left->root = cur;
67816 __ZIP_UNZIP_MOVE_RIGHT(cmp, fieldoffset, keyoffset, key,
67817 fix_edge: &ZIP_ENTRY_PTR(prev)->left, cur);
67818 }
67819}
67820
67821/**** amalgamated original file "/build/src_generated/open62541/namespace0_generated.c" ****/
67822
67823/* WARNING: This is a generated file.
67824 * Any manual changes will be overwritten. */
67825
67826
67827
67828/* HasDataSetReader - ns=0;i=15297 */
67829
67830static UA_StatusCode function_namespace0_generated_0_begin(UA_Server *server, UA_UInt16* ns) {
67831UA_StatusCode retVal = UA_STATUSCODE_GOOD;
67832UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default;
67833attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "IsReaderInGroup");
67834attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HasDataSetReader");
67835retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_REFERENCETYPE,
67836requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15297LU),
67837parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
67838referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
67839browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HasDataSetReader"),
67840 typeDefinition: UA_NODEID_NULL,
67841attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL);
67842if (retVal != UA_STATUSCODE_GOOD) return retVal;
67843return retVal;
67844}
67845
67846static UA_StatusCode function_namespace0_generated_0_finish(UA_Server *server, UA_UInt16* ns) {
67847return UA_Server_addNode_finish(server,
67848nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15297LU)
67849);
67850}
67851
67852/* HasDataSetWriter - ns=0;i=15296 */
67853
67854static UA_StatusCode function_namespace0_generated_1_begin(UA_Server *server, UA_UInt16* ns) {
67855UA_StatusCode retVal = UA_STATUSCODE_GOOD;
67856UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default;
67857attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "IsWriterInGroup");
67858attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HasDataSetWriter");
67859retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_REFERENCETYPE,
67860requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15296LU),
67861parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
67862referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
67863browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HasDataSetWriter"),
67864 typeDefinition: UA_NODEID_NULL,
67865attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL);
67866if (retVal != UA_STATUSCODE_GOOD) return retVal;
67867return retVal;
67868}
67869
67870static UA_StatusCode function_namespace0_generated_1_finish(UA_Server *server, UA_UInt16* ns) {
67871return UA_Server_addNode_finish(server,
67872nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15296LU)
67873);
67874}
67875
67876/* HasPubSubConnection - ns=0;i=14476 */
67877
67878static UA_StatusCode function_namespace0_generated_2_begin(UA_Server *server, UA_UInt16* ns) {
67879UA_StatusCode retVal = UA_STATUSCODE_GOOD;
67880UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default;
67881attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "PubSubConnectionOf");
67882attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HasPubSubConnection");
67883retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_REFERENCETYPE,
67884requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14476LU),
67885parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
67886referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
67887browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HasPubSubConnection"),
67888 typeDefinition: UA_NODEID_NULL,
67889attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL);
67890if (retVal != UA_STATUSCODE_GOOD) return retVal;
67891return retVal;
67892}
67893
67894static UA_StatusCode function_namespace0_generated_2_finish(UA_Server *server, UA_UInt16* ns) {
67895return UA_Server_addNode_finish(server,
67896nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14476LU)
67897);
67898}
67899
67900/* DataSetToWriter - ns=0;i=14936 */
67901
67902static UA_StatusCode function_namespace0_generated_3_begin(UA_Server *server, UA_UInt16* ns) {
67903UA_StatusCode retVal = UA_STATUSCODE_GOOD;
67904UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default;
67905attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "WriterToDataSet");
67906attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetToWriter");
67907retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_REFERENCETYPE,
67908requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14936LU),
67909parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 33LU),
67910referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
67911browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetToWriter"),
67912 typeDefinition: UA_NODEID_NULL,
67913attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL);
67914if (retVal != UA_STATUSCODE_GOOD) return retVal;
67915return retVal;
67916}
67917
67918static UA_StatusCode function_namespace0_generated_3_finish(UA_Server *server, UA_UInt16* ns) {
67919return UA_Server_addNode_finish(server,
67920nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14936LU)
67921);
67922}
67923
67924/* AlwaysGeneratesEvent - ns=0;i=3065 */
67925
67926static UA_StatusCode function_namespace0_generated_4_begin(UA_Server *server, UA_UInt16* ns) {
67927UA_StatusCode retVal = UA_STATUSCODE_GOOD;
67928UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default;
67929attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "AlwaysGeneratedBy");
67930attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AlwaysGeneratesEvent");
67931retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_REFERENCETYPE,
67932requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3065LU),
67933parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 41LU),
67934referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
67935browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AlwaysGeneratesEvent"),
67936 typeDefinition: UA_NODEID_NULL,
67937attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL);
67938if (retVal != UA_STATUSCODE_GOOD) return retVal;
67939return retVal;
67940}
67941
67942static UA_StatusCode function_namespace0_generated_4_finish(UA_Server *server, UA_UInt16* ns) {
67943return UA_Server_addNode_finish(server,
67944nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3065LU)
67945);
67946}
67947
67948/* HasAddIn - ns=0;i=17604 */
67949
67950static UA_StatusCode function_namespace0_generated_5_begin(UA_Server *server, UA_UInt16* ns) {
67951UA_StatusCode retVal = UA_STATUSCODE_GOOD;
67952UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default;
67953attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "AddInOf");
67954attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HasAddIn");
67955retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_REFERENCETYPE,
67956requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17604LU),
67957parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 32LU),
67958referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
67959browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HasAddIn"),
67960 typeDefinition: UA_NODEID_NULL,
67961attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL);
67962if (retVal != UA_STATUSCODE_GOOD) return retVal;
67963return retVal;
67964}
67965
67966static UA_StatusCode function_namespace0_generated_5_finish(UA_Server *server, UA_UInt16* ns) {
67967return UA_Server_addNode_finish(server,
67968nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17604LU)
67969);
67970}
67971
67972/* HasHistoricalConfiguration - ns=0;i=56 */
67973
67974static UA_StatusCode function_namespace0_generated_6_begin(UA_Server *server, UA_UInt16* ns) {
67975UA_StatusCode retVal = UA_STATUSCODE_GOOD;
67976UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default;
67977attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "HistoricalConfigurationOf");
67978attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HasHistoricalConfiguration");
67979retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_REFERENCETYPE,
67980requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 56LU),
67981parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 44LU),
67982referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
67983browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HasHistoricalConfiguration"),
67984 typeDefinition: UA_NODEID_NULL,
67985attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL);
67986if (retVal != UA_STATUSCODE_GOOD) return retVal;
67987return retVal;
67988}
67989
67990static UA_StatusCode function_namespace0_generated_6_finish(UA_Server *server, UA_UInt16* ns) {
67991return UA_Server_addNode_finish(server,
67992nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 56LU)
67993);
67994}
67995
67996/* HasEffect - ns=0;i=54 */
67997
67998static UA_StatusCode function_namespace0_generated_7_begin(UA_Server *server, UA_UInt16* ns) {
67999UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68000UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default;
68001attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "MayBeEffectedBy");
68002attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HasEffect");
68003retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_REFERENCETYPE,
68004requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 54LU),
68005parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 32LU),
68006referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68007browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HasEffect"),
68008 typeDefinition: UA_NODEID_NULL,
68009attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL);
68010if (retVal != UA_STATUSCODE_GOOD) return retVal;
68011return retVal;
68012}
68013
68014static UA_StatusCode function_namespace0_generated_7_finish(UA_Server *server, UA_UInt16* ns) {
68015return UA_Server_addNode_finish(server,
68016nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 54LU)
68017);
68018}
68019
68020/* HasCause - ns=0;i=53 */
68021
68022static UA_StatusCode function_namespace0_generated_8_begin(UA_Server *server, UA_UInt16* ns) {
68023UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68024UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default;
68025attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "MayBeCausedBy");
68026attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HasCause");
68027retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_REFERENCETYPE,
68028requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 53LU),
68029parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 32LU),
68030referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68031browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HasCause"),
68032 typeDefinition: UA_NODEID_NULL,
68033attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL);
68034if (retVal != UA_STATUSCODE_GOOD) return retVal;
68035return retVal;
68036}
68037
68038static UA_StatusCode function_namespace0_generated_8_finish(UA_Server *server, UA_UInt16* ns) {
68039return UA_Server_addNode_finish(server,
68040nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 53LU)
68041);
68042}
68043
68044/* ToState - ns=0;i=52 */
68045
68046static UA_StatusCode function_namespace0_generated_9_begin(UA_Server *server, UA_UInt16* ns) {
68047UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68048UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default;
68049attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "FromTransition");
68050attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ToState");
68051retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_REFERENCETYPE,
68052requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 52LU),
68053parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 32LU),
68054referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68055browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ToState"),
68056 typeDefinition: UA_NODEID_NULL,
68057attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL);
68058if (retVal != UA_STATUSCODE_GOOD) return retVal;
68059return retVal;
68060}
68061
68062static UA_StatusCode function_namespace0_generated_9_finish(UA_Server *server, UA_UInt16* ns) {
68063return UA_Server_addNode_finish(server,
68064nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 52LU)
68065);
68066}
68067
68068/* FromState - ns=0;i=51 */
68069
68070static UA_StatusCode function_namespace0_generated_10_begin(UA_Server *server, UA_UInt16* ns) {
68071UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68072UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default;
68073attr.inverseName = UA_LOCALIZEDTEXT(locale: "", text: "ToTransition");
68074attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "FromState");
68075retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_REFERENCETYPE,
68076requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 51LU),
68077parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 32LU),
68078referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68079browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "FromState"),
68080 typeDefinition: UA_NODEID_NULL,
68081attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL);
68082if (retVal != UA_STATUSCODE_GOOD) return retVal;
68083return retVal;
68084}
68085
68086static UA_StatusCode function_namespace0_generated_10_finish(UA_Server *server, UA_UInt16* ns) {
68087return UA_Server_addNode_finish(server,
68088nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 51LU)
68089);
68090}
68091
68092/* DiagnosticInfo - ns=0;i=25 */
68093
68094static UA_StatusCode function_namespace0_generated_11_begin(UA_Server *server, UA_UInt16* ns) {
68095UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68096UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68097attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DiagnosticInfo");
68098retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68099requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25LU),
68100parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
68101referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68102browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DiagnosticInfo"),
68103 typeDefinition: UA_NODEID_NULL,
68104attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68105if (retVal != UA_STATUSCODE_GOOD) return retVal;
68106return retVal;
68107}
68108
68109static UA_StatusCode function_namespace0_generated_11_finish(UA_Server *server, UA_UInt16* ns) {
68110return UA_Server_addNode_finish(server,
68111nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25LU)
68112);
68113}
68114
68115/* DataValue - ns=0;i=23 */
68116
68117static UA_StatusCode function_namespace0_generated_12_begin(UA_Server *server, UA_UInt16* ns) {
68118UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68119UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68120attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataValue");
68121retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68122requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23LU),
68123parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
68124referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68125browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataValue"),
68126 typeDefinition: UA_NODEID_NULL,
68127attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68128if (retVal != UA_STATUSCODE_GOOD) return retVal;
68129return retVal;
68130}
68131
68132static UA_StatusCode function_namespace0_generated_12_finish(UA_Server *server, UA_UInt16* ns) {
68133return UA_Server_addNode_finish(server,
68134nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23LU)
68135);
68136}
68137
68138/* Structure - ns=0;i=22 */
68139
68140static UA_StatusCode function_namespace0_generated_13_begin(UA_Server *server, UA_UInt16* ns) {
68141UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68142UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68143attr.isAbstract = true;
68144attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Structure");
68145retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68146requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68147parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
68148referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68149browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Structure"),
68150 typeDefinition: UA_NODEID_NULL,
68151attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68152if (retVal != UA_STATUSCODE_GOOD) return retVal;
68153return retVal;
68154}
68155
68156static UA_StatusCode function_namespace0_generated_13_finish(UA_Server *server, UA_UInt16* ns) {
68157return UA_Server_addNode_finish(server,
68158nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU)
68159);
68160}
68161
68162/* TimeZoneDataType - ns=0;i=8912 */
68163
68164static UA_StatusCode function_namespace0_generated_14_begin(UA_Server *server, UA_UInt16* ns) {
68165UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68166UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68167attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TimeZoneDataType");
68168retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68169requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8912LU),
68170parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68171referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68172browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TimeZoneDataType"),
68173 typeDefinition: UA_NODEID_NULL,
68174attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68175if (retVal != UA_STATUSCODE_GOOD) return retVal;
68176return retVal;
68177}
68178
68179static UA_StatusCode function_namespace0_generated_14_finish(UA_Server *server, UA_UInt16* ns) {
68180return UA_Server_addNode_finish(server,
68181nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8912LU)
68182);
68183}
68184
68185/* EUInformation - ns=0;i=887 */
68186
68187static UA_StatusCode function_namespace0_generated_15_begin(UA_Server *server, UA_UInt16* ns) {
68188UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68189UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68190attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EUInformation");
68191retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68192requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 887LU),
68193parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68194referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68195browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EUInformation"),
68196 typeDefinition: UA_NODEID_NULL,
68197attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68198if (retVal != UA_STATUSCODE_GOOD) return retVal;
68199return retVal;
68200}
68201
68202static UA_StatusCode function_namespace0_generated_15_finish(UA_Server *server, UA_UInt16* ns) {
68203return UA_Server_addNode_finish(server,
68204nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 887LU)
68205);
68206}
68207
68208/* Range - ns=0;i=884 */
68209
68210static UA_StatusCode function_namespace0_generated_16_begin(UA_Server *server, UA_UInt16* ns) {
68211UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68212UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68213attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Range");
68214retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68215requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 884LU),
68216parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68217referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68218browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Range"),
68219 typeDefinition: UA_NODEID_NULL,
68220attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68221if (retVal != UA_STATUSCODE_GOOD) return retVal;
68222return retVal;
68223}
68224
68225static UA_StatusCode function_namespace0_generated_16_finish(UA_Server *server, UA_UInt16* ns) {
68226return UA_Server_addNode_finish(server,
68227nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 884LU)
68228);
68229}
68230
68231/* ModelChangeStructureDataType - ns=0;i=877 */
68232
68233static UA_StatusCode function_namespace0_generated_17_begin(UA_Server *server, UA_UInt16* ns) {
68234UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68235UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68236attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ModelChangeStructureDataType");
68237retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68238requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 877LU),
68239parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68240referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68241browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ModelChangeStructureDataType"),
68242 typeDefinition: UA_NODEID_NULL,
68243attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68244if (retVal != UA_STATUSCODE_GOOD) return retVal;
68245return retVal;
68246}
68247
68248static UA_StatusCode function_namespace0_generated_17_finish(UA_Server *server, UA_UInt16* ns) {
68249return UA_Server_addNode_finish(server,
68250nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 877LU)
68251);
68252}
68253
68254/* SubscriptionDiagnosticsDataType - ns=0;i=874 */
68255
68256static UA_StatusCode function_namespace0_generated_18_begin(UA_Server *server, UA_UInt16* ns) {
68257UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68258UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68259attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscriptionDiagnosticsDataType");
68260retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68261requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 874LU),
68262parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68263referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68264browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscriptionDiagnosticsDataType"),
68265 typeDefinition: UA_NODEID_NULL,
68266attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68267if (retVal != UA_STATUSCODE_GOOD) return retVal;
68268return retVal;
68269}
68270
68271static UA_StatusCode function_namespace0_generated_18_finish(UA_Server *server, UA_UInt16* ns) {
68272return UA_Server_addNode_finish(server,
68273nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 874LU)
68274);
68275}
68276
68277/* ServiceCounterDataType - ns=0;i=871 */
68278
68279static UA_StatusCode function_namespace0_generated_19_begin(UA_Server *server, UA_UInt16* ns) {
68280UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68281UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68282attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServiceCounterDataType");
68283retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68284requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU),
68285parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68286referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68287browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServiceCounterDataType"),
68288 typeDefinition: UA_NODEID_NULL,
68289attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68290if (retVal != UA_STATUSCODE_GOOD) return retVal;
68291return retVal;
68292}
68293
68294static UA_StatusCode function_namespace0_generated_19_finish(UA_Server *server, UA_UInt16* ns) {
68295return UA_Server_addNode_finish(server,
68296nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU)
68297);
68298}
68299
68300/* SessionSecurityDiagnosticsDataType - ns=0;i=868 */
68301
68302static UA_StatusCode function_namespace0_generated_20_begin(UA_Server *server, UA_UInt16* ns) {
68303UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68304UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68305attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionSecurityDiagnosticsDataType");
68306retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68307requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 868LU),
68308parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68309referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68310browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionSecurityDiagnosticsDataType"),
68311 typeDefinition: UA_NODEID_NULL,
68312attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68313if (retVal != UA_STATUSCODE_GOOD) return retVal;
68314return retVal;
68315}
68316
68317static UA_StatusCode function_namespace0_generated_20_finish(UA_Server *server, UA_UInt16* ns) {
68318return UA_Server_addNode_finish(server,
68319nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 868LU)
68320);
68321}
68322
68323/* SessionDiagnosticsDataType - ns=0;i=865 */
68324
68325static UA_StatusCode function_namespace0_generated_21_begin(UA_Server *server, UA_UInt16* ns) {
68326UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68327UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68328attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionDiagnosticsDataType");
68329retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68330requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 865LU),
68331parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68332referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68333browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionDiagnosticsDataType"),
68334 typeDefinition: UA_NODEID_NULL,
68335attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68336if (retVal != UA_STATUSCODE_GOOD) return retVal;
68337return retVal;
68338}
68339
68340static UA_StatusCode function_namespace0_generated_21_finish(UA_Server *server, UA_UInt16* ns) {
68341return UA_Server_addNode_finish(server,
68342nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 865LU)
68343);
68344}
68345
68346/* ServerStatusDataType - ns=0;i=862 */
68347
68348static UA_StatusCode function_namespace0_generated_22_begin(UA_Server *server, UA_UInt16* ns) {
68349UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68350UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68351attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerStatusDataType");
68352retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68353requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 862LU),
68354parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68355referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68356browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerStatusDataType"),
68357 typeDefinition: UA_NODEID_NULL,
68358attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68359if (retVal != UA_STATUSCODE_GOOD) return retVal;
68360return retVal;
68361}
68362
68363static UA_StatusCode function_namespace0_generated_22_finish(UA_Server *server, UA_UInt16* ns) {
68364return UA_Server_addNode_finish(server,
68365nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 862LU)
68366);
68367}
68368
68369/* ServerDiagnosticsSummaryDataType - ns=0;i=859 */
68370
68371static UA_StatusCode function_namespace0_generated_23_begin(UA_Server *server, UA_UInt16* ns) {
68372UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68373UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68374attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerDiagnosticsSummaryDataType");
68375retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68376requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 859LU),
68377parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68378referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68379browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerDiagnosticsSummaryDataType"),
68380 typeDefinition: UA_NODEID_NULL,
68381attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68382if (retVal != UA_STATUSCODE_GOOD) return retVal;
68383return retVal;
68384}
68385
68386static UA_StatusCode function_namespace0_generated_23_finish(UA_Server *server, UA_UInt16* ns) {
68387return UA_Server_addNode_finish(server,
68388nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 859LU)
68389);
68390}
68391
68392/* SamplingIntervalDiagnosticsDataType - ns=0;i=856 */
68393
68394static UA_StatusCode function_namespace0_generated_24_begin(UA_Server *server, UA_UInt16* ns) {
68395UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68396UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68397attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SamplingIntervalDiagnosticsDataType");
68398retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68399requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 856LU),
68400parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68401referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68402browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SamplingIntervalDiagnosticsDataType"),
68403 typeDefinition: UA_NODEID_NULL,
68404attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68405if (retVal != UA_STATUSCODE_GOOD) return retVal;
68406return retVal;
68407}
68408
68409static UA_StatusCode function_namespace0_generated_24_finish(UA_Server *server, UA_UInt16* ns) {
68410return UA_Server_addNode_finish(server,
68411nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 856LU)
68412);
68413}
68414
68415/* EnumValueType - ns=0;i=7594 */
68416
68417static UA_StatusCode function_namespace0_generated_25_begin(UA_Server *server, UA_UInt16* ns) {
68418UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68419UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68420attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnumValueType");
68421retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68422requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7594LU),
68423parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68424referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68425browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnumValueType"),
68426 typeDefinition: UA_NODEID_NULL,
68427attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68428if (retVal != UA_STATUSCODE_GOOD) return retVal;
68429return retVal;
68430}
68431
68432static UA_StatusCode function_namespace0_generated_25_finish(UA_Server *server, UA_UInt16* ns) {
68433return UA_Server_addNode_finish(server,
68434nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7594LU)
68435);
68436}
68437
68438/* SignedSoftwareCertificate - ns=0;i=344 */
68439
68440static UA_StatusCode function_namespace0_generated_26_begin(UA_Server *server, UA_UInt16* ns) {
68441UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68442UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68443attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SignedSoftwareCertificate");
68444retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68445requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 344LU),
68446parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68447referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68448browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SignedSoftwareCertificate"),
68449 typeDefinition: UA_NODEID_NULL,
68450attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68451if (retVal != UA_STATUSCODE_GOOD) return retVal;
68452return retVal;
68453}
68454
68455static UA_StatusCode function_namespace0_generated_26_finish(UA_Server *server, UA_UInt16* ns) {
68456return UA_Server_addNode_finish(server,
68457nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 344LU)
68458);
68459}
68460
68461/* BuildInfo - ns=0;i=338 */
68462
68463static UA_StatusCode function_namespace0_generated_27_begin(UA_Server *server, UA_UInt16* ns) {
68464UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68465UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68466attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BuildInfo");
68467retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68468requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 338LU),
68469parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68470referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68471browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BuildInfo"),
68472 typeDefinition: UA_NODEID_NULL,
68473attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68474if (retVal != UA_STATUSCODE_GOOD) return retVal;
68475return retVal;
68476}
68477
68478static UA_StatusCode function_namespace0_generated_27_finish(UA_Server *server, UA_UInt16* ns) {
68479return UA_Server_addNode_finish(server,
68480nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 338LU)
68481);
68482}
68483
68484/* ApplicationDescription - ns=0;i=308 */
68485
68486static UA_StatusCode function_namespace0_generated_28_begin(UA_Server *server, UA_UInt16* ns) {
68487UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68488UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68489attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ApplicationDescription");
68490retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68491requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 308LU),
68492parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68493referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68494browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ApplicationDescription"),
68495 typeDefinition: UA_NODEID_NULL,
68496attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68497if (retVal != UA_STATUSCODE_GOOD) return retVal;
68498return retVal;
68499}
68500
68501static UA_StatusCode function_namespace0_generated_28_finish(UA_Server *server, UA_UInt16* ns) {
68502return UA_Server_addNode_finish(server,
68503nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 308LU)
68504);
68505}
68506
68507/* Argument - ns=0;i=296 */
68508
68509static UA_StatusCode function_namespace0_generated_29_begin(UA_Server *server, UA_UInt16* ns) {
68510UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68511UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68512attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Argument");
68513retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68514requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU),
68515parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68516referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68517browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Argument"),
68518 typeDefinition: UA_NODEID_NULL,
68519attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68520if (retVal != UA_STATUSCODE_GOOD) return retVal;
68521return retVal;
68522}
68523
68524static UA_StatusCode function_namespace0_generated_29_finish(UA_Server *server, UA_UInt16* ns) {
68525return UA_Server_addNode_finish(server,
68526nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU)
68527);
68528}
68529
68530/* AdditionalParametersType - ns=0;i=16313 */
68531
68532static UA_StatusCode function_namespace0_generated_30_begin(UA_Server *server, UA_UInt16* ns) {
68533UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68534UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68535attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AdditionalParametersType");
68536retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68537requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16313LU),
68538parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68539referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68540browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AdditionalParametersType"),
68541 typeDefinition: UA_NODEID_NULL,
68542attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68543if (retVal != UA_STATUSCODE_GOOD) return retVal;
68544return retVal;
68545}
68546
68547static UA_StatusCode function_namespace0_generated_30_finish(UA_Server *server, UA_UInt16* ns) {
68548return UA_Server_addNode_finish(server,
68549nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16313LU)
68550);
68551}
68552
68553/* PubSubConnectionDataType - ns=0;i=15617 */
68554
68555static UA_StatusCode function_namespace0_generated_31_begin(UA_Server *server, UA_UInt16* ns) {
68556UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68557UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68558attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PubSubConnectionDataType");
68559retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68560requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15617LU),
68561parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68562referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68563browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PubSubConnectionDataType"),
68564 typeDefinition: UA_NODEID_NULL,
68565attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68566if (retVal != UA_STATUSCODE_GOOD) return retVal;
68567return retVal;
68568}
68569
68570static UA_StatusCode function_namespace0_generated_31_finish(UA_Server *server, UA_UInt16* ns) {
68571return UA_Server_addNode_finish(server,
68572nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15617LU)
68573);
68574}
68575
68576/* PublishedDataSetSourceDataType - ns=0;i=15580 */
68577
68578static UA_StatusCode function_namespace0_generated_32_begin(UA_Server *server, UA_UInt16* ns) {
68579UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68580UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68581attr.isAbstract = true;
68582attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishedDataSetSourceDataType");
68583retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68584requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15580LU),
68585parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68586referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68587browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishedDataSetSourceDataType"),
68588 typeDefinition: UA_NODEID_NULL,
68589attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68590if (retVal != UA_STATUSCODE_GOOD) return retVal;
68591return retVal;
68592}
68593
68594static UA_StatusCode function_namespace0_generated_32_finish(UA_Server *server, UA_UInt16* ns) {
68595return UA_Server_addNode_finish(server,
68596nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15580LU)
68597);
68598}
68599
68600/* PublishedDataItemsDataType - ns=0;i=15581 */
68601
68602static UA_StatusCode function_namespace0_generated_33_begin(UA_Server *server, UA_UInt16* ns) {
68603UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68604UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68605attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishedDataItemsDataType");
68606retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68607requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15581LU),
68608parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15580LU),
68609referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68610browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishedDataItemsDataType"),
68611 typeDefinition: UA_NODEID_NULL,
68612attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68613if (retVal != UA_STATUSCODE_GOOD) return retVal;
68614return retVal;
68615}
68616
68617static UA_StatusCode function_namespace0_generated_33_finish(UA_Server *server, UA_UInt16* ns) {
68618return UA_Server_addNode_finish(server,
68619nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15581LU)
68620);
68621}
68622
68623/* PublishedDataSetDataType - ns=0;i=15578 */
68624
68625static UA_StatusCode function_namespace0_generated_34_begin(UA_Server *server, UA_UInt16* ns) {
68626UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68627UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68628attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishedDataSetDataType");
68629retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68630requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15578LU),
68631parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68632referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68633browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishedDataSetDataType"),
68634 typeDefinition: UA_NODEID_NULL,
68635attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68636if (retVal != UA_STATUSCODE_GOOD) return retVal;
68637return retVal;
68638}
68639
68640static UA_StatusCode function_namespace0_generated_34_finish(UA_Server *server, UA_UInt16* ns) {
68641return UA_Server_addNode_finish(server,
68642nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15578LU)
68643);
68644}
68645
68646/* DataTypeSchemaHeader - ns=0;i=15534 */
68647
68648static UA_StatusCode function_namespace0_generated_35_begin(UA_Server *server, UA_UInt16* ns) {
68649UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68650UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68651attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataTypeSchemaHeader");
68652retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68653requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15534LU),
68654parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68655referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68656browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataTypeSchemaHeader"),
68657 typeDefinition: UA_NODEID_NULL,
68658attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68659if (retVal != UA_STATUSCODE_GOOD) return retVal;
68660return retVal;
68661}
68662
68663static UA_StatusCode function_namespace0_generated_35_finish(UA_Server *server, UA_UInt16* ns) {
68664return UA_Server_addNode_finish(server,
68665nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15534LU)
68666);
68667}
68668
68669/* DataSetMetaDataType - ns=0;i=14523 */
68670
68671static UA_StatusCode function_namespace0_generated_36_begin(UA_Server *server, UA_UInt16* ns) {
68672UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68673UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68674attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetMetaDataType");
68675retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68676requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14523LU),
68677parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15534LU),
68678referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68679browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetMetaDataType"),
68680 typeDefinition: UA_NODEID_NULL,
68681attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68682if (retVal != UA_STATUSCODE_GOOD) return retVal;
68683return retVal;
68684}
68685
68686static UA_StatusCode function_namespace0_generated_36_finish(UA_Server *server, UA_UInt16* ns) {
68687return UA_Server_addNode_finish(server,
68688nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14523LU)
68689);
68690}
68691
68692/* ConfigurationVersionDataType - ns=0;i=14593 */
68693
68694static UA_StatusCode function_namespace0_generated_37_begin(UA_Server *server, UA_UInt16* ns) {
68695UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68696UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68697attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ConfigurationVersionDataType");
68698retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68699requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14593LU),
68700parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68701referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68702browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ConfigurationVersionDataType"),
68703 typeDefinition: UA_NODEID_NULL,
68704attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68705if (retVal != UA_STATUSCODE_GOOD) return retVal;
68706return retVal;
68707}
68708
68709static UA_StatusCode function_namespace0_generated_37_finish(UA_Server *server, UA_UInt16* ns) {
68710return UA_Server_addNode_finish(server,
68711nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14593LU)
68712);
68713}
68714
68715/* KeyValuePair - ns=0;i=14533 */
68716
68717static UA_StatusCode function_namespace0_generated_38_begin(UA_Server *server, UA_UInt16* ns) {
68718UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68719UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68720attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "KeyValuePair");
68721retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68722requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14533LU),
68723parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68724referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68725browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "KeyValuePair"),
68726 typeDefinition: UA_NODEID_NULL,
68727attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68728if (retVal != UA_STATUSCODE_GOOD) return retVal;
68729return retVal;
68730}
68731
68732static UA_StatusCode function_namespace0_generated_38_finish(UA_Server *server, UA_UInt16* ns) {
68733return UA_Server_addNode_finish(server,
68734nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14533LU)
68735);
68736}
68737
68738/* FieldMetaData - ns=0;i=14524 */
68739
68740static UA_StatusCode function_namespace0_generated_39_begin(UA_Server *server, UA_UInt16* ns) {
68741UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68742UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68743attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "FieldMetaData");
68744retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68745requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14524LU),
68746parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68747referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68748browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "FieldMetaData"),
68749 typeDefinition: UA_NODEID_NULL,
68750attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68751if (retVal != UA_STATUSCODE_GOOD) return retVal;
68752return retVal;
68753}
68754
68755static UA_StatusCode function_namespace0_generated_39_finish(UA_Server *server, UA_UInt16* ns) {
68756return UA_Server_addNode_finish(server,
68757nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14524LU)
68758);
68759}
68760
68761/* PublishedVariableDataType - ns=0;i=14273 */
68762
68763static UA_StatusCode function_namespace0_generated_40_begin(UA_Server *server, UA_UInt16* ns) {
68764UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68765UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68766attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishedVariableDataType");
68767retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68768requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14273LU),
68769parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68770referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68771browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishedVariableDataType"),
68772 typeDefinition: UA_NODEID_NULL,
68773attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68774if (retVal != UA_STATUSCODE_GOOD) return retVal;
68775return retVal;
68776}
68777
68778static UA_StatusCode function_namespace0_generated_40_finish(UA_Server *server, UA_UInt16* ns) {
68779return UA_Server_addNode_finish(server,
68780nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14273LU)
68781);
68782}
68783
68784/* Union - ns=0;i=12756 */
68785
68786static UA_StatusCode function_namespace0_generated_41_begin(UA_Server *server, UA_UInt16* ns) {
68787UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68788UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68789attr.isAbstract = true;
68790attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Union");
68791retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68792requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12756LU),
68793parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 22LU),
68794referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68795browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Union"),
68796 typeDefinition: UA_NODEID_NULL,
68797attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68798if (retVal != UA_STATUSCODE_GOOD) return retVal;
68799return retVal;
68800}
68801
68802static UA_StatusCode function_namespace0_generated_41_finish(UA_Server *server, UA_UInt16* ns) {
68803return UA_Server_addNode_finish(server,
68804nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12756LU)
68805);
68806}
68807
68808/* LocalizedText - ns=0;i=21 */
68809
68810static UA_StatusCode function_namespace0_generated_42_begin(UA_Server *server, UA_UInt16* ns) {
68811UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68812UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68813attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "LocalizedText");
68814retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68815requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU),
68816parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
68817referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68818browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "LocalizedText"),
68819 typeDefinition: UA_NODEID_NULL,
68820attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68821if (retVal != UA_STATUSCODE_GOOD) return retVal;
68822return retVal;
68823}
68824
68825static UA_StatusCode function_namespace0_generated_42_finish(UA_Server *server, UA_UInt16* ns) {
68826return UA_Server_addNode_finish(server,
68827nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU)
68828);
68829}
68830
68831/* QualifiedName - ns=0;i=20 */
68832
68833static UA_StatusCode function_namespace0_generated_43_begin(UA_Server *server, UA_UInt16* ns) {
68834UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68835UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68836attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "QualifiedName");
68837retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68838requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 20LU),
68839parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
68840referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68841browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "QualifiedName"),
68842 typeDefinition: UA_NODEID_NULL,
68843attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68844if (retVal != UA_STATUSCODE_GOOD) return retVal;
68845return retVal;
68846}
68847
68848static UA_StatusCode function_namespace0_generated_43_finish(UA_Server *server, UA_UInt16* ns) {
68849return UA_Server_addNode_finish(server,
68850nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 20LU)
68851);
68852}
68853
68854/* StatusCode - ns=0;i=19 */
68855
68856static UA_StatusCode function_namespace0_generated_44_begin(UA_Server *server, UA_UInt16* ns) {
68857UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68858UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68859attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "StatusCode");
68860retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68861requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 19LU),
68862parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
68863referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68864browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "StatusCode"),
68865 typeDefinition: UA_NODEID_NULL,
68866attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68867if (retVal != UA_STATUSCODE_GOOD) return retVal;
68868return retVal;
68869}
68870
68871static UA_StatusCode function_namespace0_generated_44_finish(UA_Server *server, UA_UInt16* ns) {
68872return UA_Server_addNode_finish(server,
68873nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 19LU)
68874);
68875}
68876
68877/* ExpandedNodeId - ns=0;i=18 */
68878
68879static UA_StatusCode function_namespace0_generated_45_begin(UA_Server *server, UA_UInt16* ns) {
68880UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68881UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68882attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ExpandedNodeId");
68883retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68884requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 18LU),
68885parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
68886referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68887browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ExpandedNodeId"),
68888 typeDefinition: UA_NODEID_NULL,
68889attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68890if (retVal != UA_STATUSCODE_GOOD) return retVal;
68891return retVal;
68892}
68893
68894static UA_StatusCode function_namespace0_generated_45_finish(UA_Server *server, UA_UInt16* ns) {
68895return UA_Server_addNode_finish(server,
68896nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 18LU)
68897);
68898}
68899
68900/* NodeId - ns=0;i=17 */
68901
68902static UA_StatusCode function_namespace0_generated_46_begin(UA_Server *server, UA_UInt16* ns) {
68903UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68904UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68905attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NodeId");
68906retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68907requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU),
68908parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
68909referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68910browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NodeId"),
68911 typeDefinition: UA_NODEID_NULL,
68912attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68913if (retVal != UA_STATUSCODE_GOOD) return retVal;
68914return retVal;
68915}
68916
68917static UA_StatusCode function_namespace0_generated_46_finish(UA_Server *server, UA_UInt16* ns) {
68918return UA_Server_addNode_finish(server,
68919nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU)
68920);
68921}
68922
68923/* XmlElement - ns=0;i=16 */
68924
68925static UA_StatusCode function_namespace0_generated_47_begin(UA_Server *server, UA_UInt16* ns) {
68926UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68927UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68928attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "XmlElement");
68929retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68930requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16LU),
68931parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
68932referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68933browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "XmlElement"),
68934 typeDefinition: UA_NODEID_NULL,
68935attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68936if (retVal != UA_STATUSCODE_GOOD) return retVal;
68937return retVal;
68938}
68939
68940static UA_StatusCode function_namespace0_generated_47_finish(UA_Server *server, UA_UInt16* ns) {
68941return UA_Server_addNode_finish(server,
68942nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16LU)
68943);
68944}
68945
68946/* ByteString - ns=0;i=15 */
68947
68948static UA_StatusCode function_namespace0_generated_48_begin(UA_Server *server, UA_UInt16* ns) {
68949UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68950UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68951attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ByteString");
68952retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68953requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15LU),
68954parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
68955referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68956browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ByteString"),
68957 typeDefinition: UA_NODEID_NULL,
68958attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68959if (retVal != UA_STATUSCODE_GOOD) return retVal;
68960return retVal;
68961}
68962
68963static UA_StatusCode function_namespace0_generated_48_finish(UA_Server *server, UA_UInt16* ns) {
68964return UA_Server_addNode_finish(server,
68965nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15LU)
68966);
68967}
68968
68969/* Image - ns=0;i=30 */
68970
68971static UA_StatusCode function_namespace0_generated_49_begin(UA_Server *server, UA_UInt16* ns) {
68972UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68973UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68974attr.isAbstract = true;
68975attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Image");
68976retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
68977requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 30LU),
68978parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15LU),
68979referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
68980browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Image"),
68981 typeDefinition: UA_NODEID_NULL,
68982attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
68983if (retVal != UA_STATUSCODE_GOOD) return retVal;
68984return retVal;
68985}
68986
68987static UA_StatusCode function_namespace0_generated_49_finish(UA_Server *server, UA_UInt16* ns) {
68988return UA_Server_addNode_finish(server,
68989nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 30LU)
68990);
68991}
68992
68993/* Guid - ns=0;i=14 */
68994
68995static UA_StatusCode function_namespace0_generated_50_begin(UA_Server *server, UA_UInt16* ns) {
68996UA_StatusCode retVal = UA_STATUSCODE_GOOD;
68997UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
68998attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Guid");
68999retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69000requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14LU),
69001parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
69002referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69003browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Guid"),
69004 typeDefinition: UA_NODEID_NULL,
69005attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69006if (retVal != UA_STATUSCODE_GOOD) return retVal;
69007return retVal;
69008}
69009
69010static UA_StatusCode function_namespace0_generated_50_finish(UA_Server *server, UA_UInt16* ns) {
69011return UA_Server_addNode_finish(server,
69012nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14LU)
69013);
69014}
69015
69016/* DateTime - ns=0;i=13 */
69017
69018static UA_StatusCode function_namespace0_generated_51_begin(UA_Server *server, UA_UInt16* ns) {
69019UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69020UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69021attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DateTime");
69022retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69023requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 13LU),
69024parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
69025referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69026browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DateTime"),
69027 typeDefinition: UA_NODEID_NULL,
69028attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69029if (retVal != UA_STATUSCODE_GOOD) return retVal;
69030return retVal;
69031}
69032
69033static UA_StatusCode function_namespace0_generated_51_finish(UA_Server *server, UA_UInt16* ns) {
69034return UA_Server_addNode_finish(server,
69035nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 13LU)
69036);
69037}
69038
69039/* UtcTime - ns=0;i=294 */
69040
69041static UA_StatusCode function_namespace0_generated_52_begin(UA_Server *server, UA_UInt16* ns) {
69042UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69043UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69044attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UtcTime");
69045retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69046requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU),
69047parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 13LU),
69048referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69049browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UtcTime"),
69050 typeDefinition: UA_NODEID_NULL,
69051attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69052if (retVal != UA_STATUSCODE_GOOD) return retVal;
69053return retVal;
69054}
69055
69056static UA_StatusCode function_namespace0_generated_52_finish(UA_Server *server, UA_UInt16* ns) {
69057return UA_Server_addNode_finish(server,
69058nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU)
69059);
69060}
69061
69062/* String - ns=0;i=12 */
69063
69064static UA_StatusCode function_namespace0_generated_53_begin(UA_Server *server, UA_UInt16* ns) {
69065UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69066UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69067attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "String");
69068retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69069requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU),
69070parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
69071referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69072browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "String"),
69073 typeDefinition: UA_NODEID_NULL,
69074attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69075if (retVal != UA_STATUSCODE_GOOD) return retVal;
69076return retVal;
69077}
69078
69079static UA_StatusCode function_namespace0_generated_53_finish(UA_Server *server, UA_UInt16* ns) {
69080return UA_Server_addNode_finish(server,
69081nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU)
69082);
69083}
69084
69085/* LocaleId - ns=0;i=295 */
69086
69087static UA_StatusCode function_namespace0_generated_54_begin(UA_Server *server, UA_UInt16* ns) {
69088UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69089UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69090attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "LocaleId");
69091retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69092requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 295LU),
69093parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU),
69094referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69095browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "LocaleId"),
69096 typeDefinition: UA_NODEID_NULL,
69097attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69098if (retVal != UA_STATUSCODE_GOOD) return retVal;
69099return retVal;
69100}
69101
69102static UA_StatusCode function_namespace0_generated_54_finish(UA_Server *server, UA_UInt16* ns) {
69103return UA_Server_addNode_finish(server,
69104nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 295LU)
69105);
69106}
69107
69108/* Boolean - ns=0;i=1 */
69109
69110static UA_StatusCode function_namespace0_generated_55_begin(UA_Server *server, UA_UInt16* ns) {
69111UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69112UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69113attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Boolean");
69114retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69115requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU),
69116parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
69117referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69118browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Boolean"),
69119 typeDefinition: UA_NODEID_NULL,
69120attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69121if (retVal != UA_STATUSCODE_GOOD) return retVal;
69122return retVal;
69123}
69124
69125static UA_StatusCode function_namespace0_generated_55_finish(UA_Server *server, UA_UInt16* ns) {
69126return UA_Server_addNode_finish(server,
69127nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU)
69128);
69129}
69130
69131/* Enumeration - ns=0;i=29 */
69132
69133static UA_StatusCode function_namespace0_generated_56_begin(UA_Server *server, UA_UInt16* ns) {
69134UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69135UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69136attr.isAbstract = true;
69137attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Enumeration");
69138retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69139requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 29LU),
69140parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
69141referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69142browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Enumeration"),
69143 typeDefinition: UA_NODEID_NULL,
69144attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69145if (retVal != UA_STATUSCODE_GOOD) return retVal;
69146return retVal;
69147}
69148
69149static UA_StatusCode function_namespace0_generated_56_finish(UA_Server *server, UA_UInt16* ns) {
69150return UA_Server_addNode_finish(server,
69151nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 29LU)
69152);
69153}
69154
69155/* ServerState - ns=0;i=852 */
69156
69157static UA_StatusCode function_namespace0_generated_57_begin(UA_Server *server, UA_UInt16* ns) {
69158UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69159UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69160attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerState");
69161retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69162requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 852LU),
69163parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 29LU),
69164referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69165browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerState"),
69166 typeDefinition: UA_NODEID_NULL,
69167attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69168if (retVal != UA_STATUSCODE_GOOD) return retVal;
69169return retVal;
69170}
69171
69172static UA_StatusCode function_namespace0_generated_57_finish(UA_Server *server, UA_UInt16* ns) {
69173return UA_Server_addNode_finish(server,
69174nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 852LU)
69175);
69176}
69177
69178/* RedundancySupport - ns=0;i=851 */
69179
69180static UA_StatusCode function_namespace0_generated_58_begin(UA_Server *server, UA_UInt16* ns) {
69181UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69182UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69183attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RedundancySupport");
69184retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69185requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 851LU),
69186parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 29LU),
69187referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69188browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RedundancySupport"),
69189 typeDefinition: UA_NODEID_NULL,
69190attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69191if (retVal != UA_STATUSCODE_GOOD) return retVal;
69192return retVal;
69193}
69194
69195static UA_StatusCode function_namespace0_generated_58_finish(UA_Server *server, UA_UInt16* ns) {
69196return UA_Server_addNode_finish(server,
69197nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 851LU)
69198);
69199}
69200
69201/* EnumStrings - ns=0;i=7611 */
69202
69203static UA_StatusCode function_namespace0_generated_59_begin(UA_Server *server, UA_UInt16* ns) {
69204UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69205UA_VariableAttributes attr = UA_VariableAttributes_default;
69206attr.minimumSamplingInterval = 0.000000;
69207attr.userAccessLevel = 1;
69208attr.accessLevel = 1;
69209attr.valueRank = 1;
69210attr.arrayDimensionsSize = 1;
69211UA_UInt32 arrayDimensions[1];
69212arrayDimensions[0] = 0;
69213attr.arrayDimensions = &arrayDimensions[0];
69214attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
69215UA_LocalizedText variablenode_ns_0_i_7611_variant_DataContents[6];
69216variablenode_ns_0_i_7611_variant_DataContents[0] = UA_LOCALIZEDTEXT(locale: "", text: "");
69217variablenode_ns_0_i_7611_variant_DataContents[1] = UA_LOCALIZEDTEXT(locale: "", text: "");
69218variablenode_ns_0_i_7611_variant_DataContents[2] = UA_LOCALIZEDTEXT(locale: "", text: "");
69219variablenode_ns_0_i_7611_variant_DataContents[3] = UA_LOCALIZEDTEXT(locale: "", text: "");
69220variablenode_ns_0_i_7611_variant_DataContents[4] = UA_LOCALIZEDTEXT(locale: "", text: "");
69221variablenode_ns_0_i_7611_variant_DataContents[5] = UA_LOCALIZEDTEXT(locale: "", text: "");
69222UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_7611_variant_DataContents, arraySize: (UA_Int32) 6, type: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
69223attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnumStrings");
69224retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
69225requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7611LU),
69226parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 851LU),
69227referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
69228browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnumStrings"),
69229typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
69230attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
69231if (retVal != UA_STATUSCODE_GOOD) return retVal;
69232return retVal;
69233}
69234
69235static UA_StatusCode function_namespace0_generated_59_finish(UA_Server *server, UA_UInt16* ns) {
69236return UA_Server_addNode_finish(server,
69237nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7611LU)
69238);
69239}
69240
69241/* ApplicationType - ns=0;i=307 */
69242
69243static UA_StatusCode function_namespace0_generated_60_begin(UA_Server *server, UA_UInt16* ns) {
69244UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69245UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69246attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ApplicationType");
69247retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69248requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 307LU),
69249parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 29LU),
69250referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69251browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ApplicationType"),
69252 typeDefinition: UA_NODEID_NULL,
69253attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69254if (retVal != UA_STATUSCODE_GOOD) return retVal;
69255return retVal;
69256}
69257
69258static UA_StatusCode function_namespace0_generated_60_finish(UA_Server *server, UA_UInt16* ns) {
69259return UA_Server_addNode_finish(server,
69260nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 307LU)
69261);
69262}
69263
69264/* EnumStrings - ns=0;i=7597 */
69265
69266static UA_StatusCode function_namespace0_generated_61_begin(UA_Server *server, UA_UInt16* ns) {
69267UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69268UA_VariableAttributes attr = UA_VariableAttributes_default;
69269attr.minimumSamplingInterval = 0.000000;
69270attr.userAccessLevel = 1;
69271attr.accessLevel = 1;
69272attr.valueRank = 1;
69273attr.arrayDimensionsSize = 1;
69274UA_UInt32 arrayDimensions[1];
69275arrayDimensions[0] = 0;
69276attr.arrayDimensions = &arrayDimensions[0];
69277attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
69278UA_LocalizedText variablenode_ns_0_i_7597_variant_DataContents[4];
69279variablenode_ns_0_i_7597_variant_DataContents[0] = UA_LOCALIZEDTEXT(locale: "", text: "");
69280variablenode_ns_0_i_7597_variant_DataContents[1] = UA_LOCALIZEDTEXT(locale: "", text: "");
69281variablenode_ns_0_i_7597_variant_DataContents[2] = UA_LOCALIZEDTEXT(locale: "", text: "");
69282variablenode_ns_0_i_7597_variant_DataContents[3] = UA_LOCALIZEDTEXT(locale: "", text: "");
69283UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_7597_variant_DataContents, arraySize: (UA_Int32) 4, type: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
69284attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnumStrings");
69285retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
69286requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7597LU),
69287parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 307LU),
69288referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
69289browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnumStrings"),
69290typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
69291attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
69292if (retVal != UA_STATUSCODE_GOOD) return retVal;
69293return retVal;
69294}
69295
69296static UA_StatusCode function_namespace0_generated_61_finish(UA_Server *server, UA_UInt16* ns) {
69297return UA_Server_addNode_finish(server,
69298nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7597LU)
69299);
69300}
69301
69302/* MessageSecurityMode - ns=0;i=302 */
69303
69304static UA_StatusCode function_namespace0_generated_62_begin(UA_Server *server, UA_UInt16* ns) {
69305UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69306UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69307attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MessageSecurityMode");
69308retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69309requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 302LU),
69310parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 29LU),
69311referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69312browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MessageSecurityMode"),
69313 typeDefinition: UA_NODEID_NULL,
69314attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69315if (retVal != UA_STATUSCODE_GOOD) return retVal;
69316return retVal;
69317}
69318
69319static UA_StatusCode function_namespace0_generated_62_finish(UA_Server *server, UA_UInt16* ns) {
69320return UA_Server_addNode_finish(server,
69321nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 302LU)
69322);
69323}
69324
69325/* EnumStrings - ns=0;i=7595 */
69326
69327static UA_StatusCode function_namespace0_generated_63_begin(UA_Server *server, UA_UInt16* ns) {
69328UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69329UA_VariableAttributes attr = UA_VariableAttributes_default;
69330attr.minimumSamplingInterval = 0.000000;
69331attr.userAccessLevel = 1;
69332attr.accessLevel = 1;
69333attr.valueRank = 1;
69334attr.arrayDimensionsSize = 1;
69335UA_UInt32 arrayDimensions[1];
69336arrayDimensions[0] = 0;
69337attr.arrayDimensions = &arrayDimensions[0];
69338attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
69339UA_LocalizedText variablenode_ns_0_i_7595_variant_DataContents[4];
69340variablenode_ns_0_i_7595_variant_DataContents[0] = UA_LOCALIZEDTEXT(locale: "", text: "");
69341variablenode_ns_0_i_7595_variant_DataContents[1] = UA_LOCALIZEDTEXT(locale: "", text: "");
69342variablenode_ns_0_i_7595_variant_DataContents[2] = UA_LOCALIZEDTEXT(locale: "", text: "");
69343variablenode_ns_0_i_7595_variant_DataContents[3] = UA_LOCALIZEDTEXT(locale: "", text: "");
69344UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_7595_variant_DataContents, arraySize: (UA_Int32) 4, type: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
69345attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnumStrings");
69346retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
69347requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7595LU),
69348parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 302LU),
69349referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
69350browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnumStrings"),
69351typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
69352attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
69353if (retVal != UA_STATUSCODE_GOOD) return retVal;
69354return retVal;
69355}
69356
69357static UA_StatusCode function_namespace0_generated_63_finish(UA_Server *server, UA_UInt16* ns) {
69358return UA_Server_addNode_finish(server,
69359nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7595LU)
69360);
69361}
69362
69363/* PubSubState - ns=0;i=14647 */
69364
69365static UA_StatusCode function_namespace0_generated_64_begin(UA_Server *server, UA_UInt16* ns) {
69366UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69367UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69368attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PubSubState");
69369retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69370requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14647LU),
69371parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 29LU),
69372referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69373browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PubSubState"),
69374 typeDefinition: UA_NODEID_NULL,
69375attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69376if (retVal != UA_STATUSCODE_GOOD) return retVal;
69377return retVal;
69378}
69379
69380static UA_StatusCode function_namespace0_generated_64_finish(UA_Server *server, UA_UInt16* ns) {
69381return UA_Server_addNode_finish(server,
69382nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14647LU)
69383);
69384}
69385
69386/* EnumStrings - ns=0;i=14648 */
69387
69388static UA_StatusCode function_namespace0_generated_65_begin(UA_Server *server, UA_UInt16* ns) {
69389UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69390UA_VariableAttributes attr = UA_VariableAttributes_default;
69391attr.minimumSamplingInterval = 0.000000;
69392attr.userAccessLevel = 1;
69393attr.accessLevel = 1;
69394attr.valueRank = 1;
69395attr.arrayDimensionsSize = 1;
69396UA_UInt32 arrayDimensions[1];
69397arrayDimensions[0] = 0;
69398attr.arrayDimensions = &arrayDimensions[0];
69399attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
69400UA_LocalizedText variablenode_ns_0_i_14648_variant_DataContents[4];
69401variablenode_ns_0_i_14648_variant_DataContents[0] = UA_LOCALIZEDTEXT(locale: "", text: "");
69402variablenode_ns_0_i_14648_variant_DataContents[1] = UA_LOCALIZEDTEXT(locale: "", text: "");
69403variablenode_ns_0_i_14648_variant_DataContents[2] = UA_LOCALIZEDTEXT(locale: "", text: "");
69404variablenode_ns_0_i_14648_variant_DataContents[3] = UA_LOCALIZEDTEXT(locale: "", text: "");
69405UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_14648_variant_DataContents, arraySize: (UA_Int32) 4, type: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
69406attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnumStrings");
69407retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
69408requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14648LU),
69409parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14647LU),
69410referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
69411browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnumStrings"),
69412typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
69413attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
69414if (retVal != UA_STATUSCODE_GOOD) return retVal;
69415return retVal;
69416}
69417
69418static UA_StatusCode function_namespace0_generated_65_finish(UA_Server *server, UA_UInt16* ns) {
69419return UA_Server_addNode_finish(server,
69420nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14648LU)
69421);
69422}
69423
69424/* AxisScaleEnumeration - ns=0;i=12077 */
69425
69426static UA_StatusCode function_namespace0_generated_66_begin(UA_Server *server, UA_UInt16* ns) {
69427UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69428UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69429attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AxisScaleEnumeration");
69430retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69431requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12077LU),
69432parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 29LU),
69433referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69434browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AxisScaleEnumeration"),
69435 typeDefinition: UA_NODEID_NULL,
69436attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69437if (retVal != UA_STATUSCODE_GOOD) return retVal;
69438return retVal;
69439}
69440
69441static UA_StatusCode function_namespace0_generated_66_finish(UA_Server *server, UA_UInt16* ns) {
69442return UA_Server_addNode_finish(server,
69443nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12077LU)
69444);
69445}
69446
69447/* EnumStrings - ns=0;i=12078 */
69448
69449static UA_StatusCode function_namespace0_generated_67_begin(UA_Server *server, UA_UInt16* ns) {
69450UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69451UA_VariableAttributes attr = UA_VariableAttributes_default;
69452attr.minimumSamplingInterval = 0.000000;
69453attr.userAccessLevel = 1;
69454attr.accessLevel = 1;
69455attr.valueRank = 1;
69456attr.arrayDimensionsSize = 1;
69457UA_UInt32 arrayDimensions[1];
69458arrayDimensions[0] = 0;
69459attr.arrayDimensions = &arrayDimensions[0];
69460attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
69461UA_LocalizedText variablenode_ns_0_i_12078_variant_DataContents[3];
69462variablenode_ns_0_i_12078_variant_DataContents[0] = UA_LOCALIZEDTEXT(locale: "", text: "");
69463variablenode_ns_0_i_12078_variant_DataContents[1] = UA_LOCALIZEDTEXT(locale: "", text: "");
69464variablenode_ns_0_i_12078_variant_DataContents[2] = UA_LOCALIZEDTEXT(locale: "", text: "");
69465UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_12078_variant_DataContents, arraySize: (UA_Int32) 3, type: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
69466attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnumStrings");
69467retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
69468requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12078LU),
69469parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12077LU),
69470referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
69471browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnumStrings"),
69472typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
69473attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
69474if (retVal != UA_STATUSCODE_GOOD) return retVal;
69475return retVal;
69476}
69477
69478static UA_StatusCode function_namespace0_generated_67_finish(UA_Server *server, UA_UInt16* ns) {
69479return UA_Server_addNode_finish(server,
69480nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12078LU)
69481);
69482}
69483
69484/* NamingRuleType - ns=0;i=120 */
69485
69486static UA_StatusCode function_namespace0_generated_68_begin(UA_Server *server, UA_UInt16* ns) {
69487UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69488UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69489attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NamingRuleType");
69490retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69491requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 120LU),
69492parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 29LU),
69493referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69494browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NamingRuleType"),
69495 typeDefinition: UA_NODEID_NULL,
69496attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69497if (retVal != UA_STATUSCODE_GOOD) return retVal;
69498return retVal;
69499}
69500
69501static UA_StatusCode function_namespace0_generated_68_finish(UA_Server *server, UA_UInt16* ns) {
69502return UA_Server_addNode_finish(server,
69503nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 120LU)
69504);
69505}
69506
69507/* EnumValues - ns=0;i=12169 */
69508
69509static UA_StatusCode function_namespace0_generated_69_begin(UA_Server *server, UA_UInt16* ns) {
69510UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69511UA_VariableAttributes attr = UA_VariableAttributes_default;
69512attr.minimumSamplingInterval = 0.000000;
69513attr.userAccessLevel = 1;
69514attr.accessLevel = 1;
69515attr.valueRank = 1;
69516attr.arrayDimensionsSize = 1;
69517UA_UInt32 arrayDimensions[1];
69518arrayDimensions[0] = 0;
69519attr.arrayDimensions = &arrayDimensions[0];
69520attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7594LU);
69521UA_EnumValueType variablenode_ns_0_i_12169_variant_DataContents[3];
69522
69523UA_init(p: &variablenode_ns_0_i_12169_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ENUMVALUETYPE]);
69524variablenode_ns_0_i_12169_variant_DataContents[0].value = (UA_Int64) 1;
69525variablenode_ns_0_i_12169_variant_DataContents[0].displayName = UA_LOCALIZEDTEXT(locale: "", text: "");
69526variablenode_ns_0_i_12169_variant_DataContents[0].description = UA_LOCALIZEDTEXT(locale: "", text: "");
69527
69528UA_init(p: &variablenode_ns_0_i_12169_variant_DataContents[1], type: &UA_TYPES[UA_TYPES_ENUMVALUETYPE]);
69529variablenode_ns_0_i_12169_variant_DataContents[1].value = (UA_Int64) 2;
69530variablenode_ns_0_i_12169_variant_DataContents[1].displayName = UA_LOCALIZEDTEXT(locale: "", text: "");
69531variablenode_ns_0_i_12169_variant_DataContents[1].description = UA_LOCALIZEDTEXT(locale: "", text: "");
69532
69533UA_init(p: &variablenode_ns_0_i_12169_variant_DataContents[2], type: &UA_TYPES[UA_TYPES_ENUMVALUETYPE]);
69534variablenode_ns_0_i_12169_variant_DataContents[2].value = (UA_Int64) 3;
69535variablenode_ns_0_i_12169_variant_DataContents[2].displayName = UA_LOCALIZEDTEXT(locale: "", text: "");
69536variablenode_ns_0_i_12169_variant_DataContents[2].description = UA_LOCALIZEDTEXT(locale: "", text: "");
69537UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_12169_variant_DataContents, arraySize: (UA_Int32) 3, type: &UA_TYPES[UA_TYPES_ENUMVALUETYPE]);
69538attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnumValues");
69539retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
69540requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12169LU),
69541parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 120LU),
69542referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
69543browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnumValues"),
69544typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
69545attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
69546if (retVal != UA_STATUSCODE_GOOD) return retVal;
69547
69548
69549
69550return retVal;
69551}
69552
69553static UA_StatusCode function_namespace0_generated_69_finish(UA_Server *server, UA_UInt16* ns) {
69554return UA_Server_addNode_finish(server,
69555nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12169LU)
69556);
69557}
69558
69559/* Number - ns=0;i=26 */
69560
69561static UA_StatusCode function_namespace0_generated_70_begin(UA_Server *server, UA_UInt16* ns) {
69562UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69563UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69564attr.isAbstract = true;
69565attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Number");
69566retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69567requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 26LU),
69568parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU),
69569referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69570browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Number"),
69571 typeDefinition: UA_NODEID_NULL,
69572attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69573if (retVal != UA_STATUSCODE_GOOD) return retVal;
69574return retVal;
69575}
69576
69577static UA_StatusCode function_namespace0_generated_70_finish(UA_Server *server, UA_UInt16* ns) {
69578return UA_Server_addNode_finish(server,
69579nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 26LU)
69580);
69581}
69582
69583/* Decimal - ns=0;i=50 */
69584
69585static UA_StatusCode function_namespace0_generated_71_begin(UA_Server *server, UA_UInt16* ns) {
69586UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69587UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69588attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Decimal");
69589retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69590requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 50LU),
69591parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 26LU),
69592referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69593browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Decimal"),
69594 typeDefinition: UA_NODEID_NULL,
69595attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69596if (retVal != UA_STATUSCODE_GOOD) return retVal;
69597return retVal;
69598}
69599
69600static UA_StatusCode function_namespace0_generated_71_finish(UA_Server *server, UA_UInt16* ns) {
69601return UA_Server_addNode_finish(server,
69602nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 50LU)
69603);
69604}
69605
69606/* UInteger - ns=0;i=28 */
69607
69608static UA_StatusCode function_namespace0_generated_72_begin(UA_Server *server, UA_UInt16* ns) {
69609UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69610UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69611attr.isAbstract = true;
69612attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UInteger");
69613retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69614requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 28LU),
69615parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 26LU),
69616referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69617browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UInteger"),
69618 typeDefinition: UA_NODEID_NULL,
69619attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69620if (retVal != UA_STATUSCODE_GOOD) return retVal;
69621return retVal;
69622}
69623
69624static UA_StatusCode function_namespace0_generated_72_finish(UA_Server *server, UA_UInt16* ns) {
69625return UA_Server_addNode_finish(server,
69626nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 28LU)
69627);
69628}
69629
69630/* UInt64 - ns=0;i=9 */
69631
69632static UA_StatusCode function_namespace0_generated_73_begin(UA_Server *server, UA_UInt16* ns) {
69633UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69634UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69635attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UInt64");
69636retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69637requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9LU),
69638parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 28LU),
69639referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69640browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UInt64"),
69641 typeDefinition: UA_NODEID_NULL,
69642attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69643if (retVal != UA_STATUSCODE_GOOD) return retVal;
69644return retVal;
69645}
69646
69647static UA_StatusCode function_namespace0_generated_73_finish(UA_Server *server, UA_UInt16* ns) {
69648return UA_Server_addNode_finish(server,
69649nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9LU)
69650);
69651}
69652
69653/* UInt32 - ns=0;i=7 */
69654
69655static UA_StatusCode function_namespace0_generated_74_begin(UA_Server *server, UA_UInt16* ns) {
69656UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69657UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69658attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UInt32");
69659retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69660requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU),
69661parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 28LU),
69662referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69663browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UInt32"),
69664 typeDefinition: UA_NODEID_NULL,
69665attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69666if (retVal != UA_STATUSCODE_GOOD) return retVal;
69667return retVal;
69668}
69669
69670static UA_StatusCode function_namespace0_generated_74_finish(UA_Server *server, UA_UInt16* ns) {
69671return UA_Server_addNode_finish(server,
69672nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU)
69673);
69674}
69675
69676/* VersionTime - ns=0;i=20998 */
69677
69678static UA_StatusCode function_namespace0_generated_75_begin(UA_Server *server, UA_UInt16* ns) {
69679UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69680UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69681attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "VersionTime");
69682retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69683requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 20998LU),
69684parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU),
69685referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69686browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "VersionTime"),
69687 typeDefinition: UA_NODEID_NULL,
69688attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69689if (retVal != UA_STATUSCODE_GOOD) return retVal;
69690return retVal;
69691}
69692
69693static UA_StatusCode function_namespace0_generated_75_finish(UA_Server *server, UA_UInt16* ns) {
69694return UA_Server_addNode_finish(server,
69695nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 20998LU)
69696);
69697}
69698
69699/* DataSetFieldContentMask - ns=0;i=15583 */
69700
69701static UA_StatusCode function_namespace0_generated_76_begin(UA_Server *server, UA_UInt16* ns) {
69702UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69703UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69704attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetFieldContentMask");
69705retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69706requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15583LU),
69707parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU),
69708referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69709browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetFieldContentMask"),
69710 typeDefinition: UA_NODEID_NULL,
69711attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69712if (retVal != UA_STATUSCODE_GOOD) return retVal;
69713return retVal;
69714}
69715
69716static UA_StatusCode function_namespace0_generated_76_finish(UA_Server *server, UA_UInt16* ns) {
69717return UA_Server_addNode_finish(server,
69718nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15583LU)
69719);
69720}
69721
69722/* OptionSetValues - ns=0;i=15584 */
69723
69724static UA_StatusCode function_namespace0_generated_77_begin(UA_Server *server, UA_UInt16* ns) {
69725UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69726UA_VariableAttributes attr = UA_VariableAttributes_default;
69727attr.minimumSamplingInterval = 0.000000;
69728attr.userAccessLevel = 1;
69729attr.accessLevel = 1;
69730attr.valueRank = 1;
69731attr.arrayDimensionsSize = 1;
69732UA_UInt32 arrayDimensions[1];
69733arrayDimensions[0] = 0;
69734attr.arrayDimensions = &arrayDimensions[0];
69735attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
69736UA_LocalizedText variablenode_ns_0_i_15584_variant_DataContents[6];
69737variablenode_ns_0_i_15584_variant_DataContents[0] = UA_LOCALIZEDTEXT(locale: "", text: "");
69738variablenode_ns_0_i_15584_variant_DataContents[1] = UA_LOCALIZEDTEXT(locale: "", text: "");
69739variablenode_ns_0_i_15584_variant_DataContents[2] = UA_LOCALIZEDTEXT(locale: "", text: "");
69740variablenode_ns_0_i_15584_variant_DataContents[3] = UA_LOCALIZEDTEXT(locale: "", text: "");
69741variablenode_ns_0_i_15584_variant_DataContents[4] = UA_LOCALIZEDTEXT(locale: "", text: "");
69742variablenode_ns_0_i_15584_variant_DataContents[5] = UA_LOCALIZEDTEXT(locale: "", text: "");
69743UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_15584_variant_DataContents, arraySize: (UA_Int32) 6, type: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
69744attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OptionSetValues");
69745retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
69746requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15584LU),
69747parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15583LU),
69748referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
69749browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OptionSetValues"),
69750typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
69751attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
69752if (retVal != UA_STATUSCODE_GOOD) return retVal;
69753return retVal;
69754}
69755
69756static UA_StatusCode function_namespace0_generated_77_finish(UA_Server *server, UA_UInt16* ns) {
69757return UA_Server_addNode_finish(server,
69758nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15584LU)
69759);
69760}
69761
69762/* UInt16 - ns=0;i=5 */
69763
69764static UA_StatusCode function_namespace0_generated_78_begin(UA_Server *server, UA_UInt16* ns) {
69765UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69766UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69767attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UInt16");
69768retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69769requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU),
69770parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 28LU),
69771referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69772browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UInt16"),
69773 typeDefinition: UA_NODEID_NULL,
69774attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69775if (retVal != UA_STATUSCODE_GOOD) return retVal;
69776return retVal;
69777}
69778
69779static UA_StatusCode function_namespace0_generated_78_finish(UA_Server *server, UA_UInt16* ns) {
69780return UA_Server_addNode_finish(server,
69781nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU)
69782);
69783}
69784
69785/* Byte - ns=0;i=3 */
69786
69787static UA_StatusCode function_namespace0_generated_79_begin(UA_Server *server, UA_UInt16* ns) {
69788UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69789UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69790attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Byte");
69791retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69792requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3LU),
69793parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 28LU),
69794referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69795browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Byte"),
69796 typeDefinition: UA_NODEID_NULL,
69797attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69798if (retVal != UA_STATUSCODE_GOOD) return retVal;
69799return retVal;
69800}
69801
69802static UA_StatusCode function_namespace0_generated_79_finish(UA_Server *server, UA_UInt16* ns) {
69803return UA_Server_addNode_finish(server,
69804nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3LU)
69805);
69806}
69807
69808/* Integer - ns=0;i=27 */
69809
69810static UA_StatusCode function_namespace0_generated_80_begin(UA_Server *server, UA_UInt16* ns) {
69811UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69812UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69813attr.isAbstract = true;
69814attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Integer");
69815retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69816requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 27LU),
69817parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 26LU),
69818referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69819browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Integer"),
69820 typeDefinition: UA_NODEID_NULL,
69821attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69822if (retVal != UA_STATUSCODE_GOOD) return retVal;
69823return retVal;
69824}
69825
69826static UA_StatusCode function_namespace0_generated_80_finish(UA_Server *server, UA_UInt16* ns) {
69827return UA_Server_addNode_finish(server,
69828nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 27LU)
69829);
69830}
69831
69832/* Int64 - ns=0;i=8 */
69833
69834static UA_StatusCode function_namespace0_generated_81_begin(UA_Server *server, UA_UInt16* ns) {
69835UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69836UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69837attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Int64");
69838retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69839requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8LU),
69840parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 27LU),
69841referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69842browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Int64"),
69843 typeDefinition: UA_NODEID_NULL,
69844attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69845if (retVal != UA_STATUSCODE_GOOD) return retVal;
69846return retVal;
69847}
69848
69849static UA_StatusCode function_namespace0_generated_81_finish(UA_Server *server, UA_UInt16* ns) {
69850return UA_Server_addNode_finish(server,
69851nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8LU)
69852);
69853}
69854
69855/* Int32 - ns=0;i=6 */
69856
69857static UA_StatusCode function_namespace0_generated_82_begin(UA_Server *server, UA_UInt16* ns) {
69858UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69859UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69860attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Int32");
69861retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69862requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 6LU),
69863parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 27LU),
69864referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69865browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Int32"),
69866 typeDefinition: UA_NODEID_NULL,
69867attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69868if (retVal != UA_STATUSCODE_GOOD) return retVal;
69869return retVal;
69870}
69871
69872static UA_StatusCode function_namespace0_generated_82_finish(UA_Server *server, UA_UInt16* ns) {
69873return UA_Server_addNode_finish(server,
69874nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 6LU)
69875);
69876}
69877
69878/* Int16 - ns=0;i=4 */
69879
69880static UA_StatusCode function_namespace0_generated_83_begin(UA_Server *server, UA_UInt16* ns) {
69881UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69882UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69883attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Int16");
69884retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69885requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 4LU),
69886parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 27LU),
69887referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69888browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Int16"),
69889 typeDefinition: UA_NODEID_NULL,
69890attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69891if (retVal != UA_STATUSCODE_GOOD) return retVal;
69892return retVal;
69893}
69894
69895static UA_StatusCode function_namespace0_generated_83_finish(UA_Server *server, UA_UInt16* ns) {
69896return UA_Server_addNode_finish(server,
69897nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 4LU)
69898);
69899}
69900
69901/* SByte - ns=0;i=2 */
69902
69903static UA_StatusCode function_namespace0_generated_84_begin(UA_Server *server, UA_UInt16* ns) {
69904UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69905UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69906attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SByte");
69907retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69908requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2LU),
69909parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 27LU),
69910referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69911browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SByte"),
69912 typeDefinition: UA_NODEID_NULL,
69913attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69914if (retVal != UA_STATUSCODE_GOOD) return retVal;
69915return retVal;
69916}
69917
69918static UA_StatusCode function_namespace0_generated_84_finish(UA_Server *server, UA_UInt16* ns) {
69919return UA_Server_addNode_finish(server,
69920nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2LU)
69921);
69922}
69923
69924/* Double - ns=0;i=11 */
69925
69926static UA_StatusCode function_namespace0_generated_85_begin(UA_Server *server, UA_UInt16* ns) {
69927UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69928UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69929attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Double");
69930retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69931requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11LU),
69932parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 26LU),
69933referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69934browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Double"),
69935 typeDefinition: UA_NODEID_NULL,
69936attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69937if (retVal != UA_STATUSCODE_GOOD) return retVal;
69938return retVal;
69939}
69940
69941static UA_StatusCode function_namespace0_generated_85_finish(UA_Server *server, UA_UInt16* ns) {
69942return UA_Server_addNode_finish(server,
69943nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11LU)
69944);
69945}
69946
69947/* Duration - ns=0;i=290 */
69948
69949static UA_StatusCode function_namespace0_generated_86_begin(UA_Server *server, UA_UInt16* ns) {
69950UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69951UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69952attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Duration");
69953retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69954requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU),
69955parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11LU),
69956referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69957browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Duration"),
69958 typeDefinition: UA_NODEID_NULL,
69959attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69960if (retVal != UA_STATUSCODE_GOOD) return retVal;
69961return retVal;
69962}
69963
69964static UA_StatusCode function_namespace0_generated_86_finish(UA_Server *server, UA_UInt16* ns) {
69965return UA_Server_addNode_finish(server,
69966nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU)
69967);
69968}
69969
69970/* Float - ns=0;i=10 */
69971
69972static UA_StatusCode function_namespace0_generated_87_begin(UA_Server *server, UA_UInt16* ns) {
69973UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69974UA_DataTypeAttributes attr = UA_DataTypeAttributes_default;
69975attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Float");
69976retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_DATATYPE,
69977requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 10LU),
69978parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 26LU),
69979referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
69980browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Float"),
69981 typeDefinition: UA_NODEID_NULL,
69982attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL);
69983if (retVal != UA_STATUSCODE_GOOD) return retVal;
69984return retVal;
69985}
69986
69987static UA_StatusCode function_namespace0_generated_87_finish(UA_Server *server, UA_UInt16* ns) {
69988return UA_Server_addNode_finish(server,
69989nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 10LU)
69990);
69991}
69992
69993/* DataItemType - ns=0;i=2365 */
69994
69995static UA_StatusCode function_namespace0_generated_88_begin(UA_Server *server, UA_UInt16* ns) {
69996UA_StatusCode retVal = UA_STATUSCODE_GOOD;
69997UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
69998attr.valueRank = -2;
69999/* DataType inherited */
70000attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
70001attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataItemType");
70002#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS
70003attr.description = UA_LOCALIZEDTEXT(locale: "", text: "A variable that contains live automation data.");
70004#endif
70005retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
70006requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2365LU),
70007parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
70008referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
70009browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataItemType"),
70010typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
70011attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
70012if (retVal != UA_STATUSCODE_GOOD) return retVal;
70013return retVal;
70014}
70015
70016static UA_StatusCode function_namespace0_generated_88_finish(UA_Server *server, UA_UInt16* ns) {
70017return UA_Server_addNode_finish(server,
70018nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2365LU)
70019);
70020}
70021
70022/* DiscreteItemType - ns=0;i=2372 */
70023
70024static UA_StatusCode function_namespace0_generated_89_begin(UA_Server *server, UA_UInt16* ns) {
70025UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70026UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
70027attr.isAbstract = true;
70028attr.valueRank = -2;
70029/* DataType inherited */
70030attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
70031attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DiscreteItemType");
70032retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
70033requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2372LU),
70034parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2365LU),
70035referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
70036browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DiscreteItemType"),
70037typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
70038attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
70039if (retVal != UA_STATUSCODE_GOOD) return retVal;
70040return retVal;
70041}
70042
70043static UA_StatusCode function_namespace0_generated_89_finish(UA_Server *server, UA_UInt16* ns) {
70044return UA_Server_addNode_finish(server,
70045nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2372LU)
70046);
70047}
70048
70049/* MultiStateDiscreteType - ns=0;i=2376 */
70050
70051static UA_StatusCode function_namespace0_generated_90_begin(UA_Server *server, UA_UInt16* ns) {
70052UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70053UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
70054attr.valueRank = -2;
70055attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 28LU);
70056attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MultiStateDiscreteType");
70057retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
70058requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2376LU),
70059parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2372LU),
70060referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
70061browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MultiStateDiscreteType"),
70062typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
70063attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
70064if (retVal != UA_STATUSCODE_GOOD) return retVal;
70065return retVal;
70066}
70067
70068static UA_StatusCode function_namespace0_generated_90_finish(UA_Server *server, UA_UInt16* ns) {
70069return UA_Server_addNode_finish(server,
70070nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2376LU)
70071);
70072}
70073
70074/* EnumStrings - ns=0;i=2377 */
70075
70076static UA_StatusCode function_namespace0_generated_91_begin(UA_Server *server, UA_UInt16* ns) {
70077UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70078UA_VariableAttributes attr = UA_VariableAttributes_default;
70079attr.minimumSamplingInterval = 0.000000;
70080attr.userAccessLevel = 1;
70081attr.accessLevel = 1;
70082attr.valueRank = 1;
70083attr.arrayDimensionsSize = 1;
70084UA_UInt32 arrayDimensions[1];
70085arrayDimensions[0] = 0;
70086attr.arrayDimensions = &arrayDimensions[0];
70087attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
70088attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnumStrings");
70089retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70090requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2377LU),
70091parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2376LU),
70092referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70093browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnumStrings"),
70094typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70095attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70096if (retVal != UA_STATUSCODE_GOOD) return retVal;
70097return retVal;
70098}
70099
70100static UA_StatusCode function_namespace0_generated_91_finish(UA_Server *server, UA_UInt16* ns) {
70101return UA_Server_addNode_finish(server,
70102nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2377LU)
70103);
70104}
70105
70106/* TwoStateDiscreteType - ns=0;i=2373 */
70107
70108static UA_StatusCode function_namespace0_generated_92_begin(UA_Server *server, UA_UInt16* ns) {
70109UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70110UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
70111attr.valueRank = -2;
70112attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
70113attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TwoStateDiscreteType");
70114retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
70115requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2373LU),
70116parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2372LU),
70117referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
70118browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TwoStateDiscreteType"),
70119typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
70120attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
70121if (retVal != UA_STATUSCODE_GOOD) return retVal;
70122return retVal;
70123}
70124
70125static UA_StatusCode function_namespace0_generated_92_finish(UA_Server *server, UA_UInt16* ns) {
70126return UA_Server_addNode_finish(server,
70127nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2373LU)
70128);
70129}
70130
70131/* TrueState - ns=0;i=2375 */
70132
70133static UA_StatusCode function_namespace0_generated_93_begin(UA_Server *server, UA_UInt16* ns) {
70134UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70135UA_VariableAttributes attr = UA_VariableAttributes_default;
70136attr.minimumSamplingInterval = 0.000000;
70137attr.userAccessLevel = 1;
70138attr.accessLevel = 1;
70139/* Value rank inherited */
70140attr.valueRank = -2;
70141attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
70142attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TrueState");
70143retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70144requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2375LU),
70145parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2373LU),
70146referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70147browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TrueState"),
70148typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70149attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70150if (retVal != UA_STATUSCODE_GOOD) return retVal;
70151return retVal;
70152}
70153
70154static UA_StatusCode function_namespace0_generated_93_finish(UA_Server *server, UA_UInt16* ns) {
70155return UA_Server_addNode_finish(server,
70156nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2375LU)
70157);
70158}
70159
70160/* FalseState - ns=0;i=2374 */
70161
70162static UA_StatusCode function_namespace0_generated_94_begin(UA_Server *server, UA_UInt16* ns) {
70163UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70164UA_VariableAttributes attr = UA_VariableAttributes_default;
70165attr.minimumSamplingInterval = 0.000000;
70166attr.userAccessLevel = 1;
70167attr.accessLevel = 1;
70168/* Value rank inherited */
70169attr.valueRank = -2;
70170attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
70171attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "FalseState");
70172retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70173requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2374LU),
70174parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2373LU),
70175referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70176browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "FalseState"),
70177typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70178attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70179if (retVal != UA_STATUSCODE_GOOD) return retVal;
70180return retVal;
70181}
70182
70183static UA_StatusCode function_namespace0_generated_94_finish(UA_Server *server, UA_UInt16* ns) {
70184return UA_Server_addNode_finish(server,
70185nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2374LU)
70186);
70187}
70188
70189/* MultiStateValueDiscreteType - ns=0;i=11238 */
70190
70191static UA_StatusCode function_namespace0_generated_95_begin(UA_Server *server, UA_UInt16* ns) {
70192UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70193UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
70194attr.valueRank = -2;
70195attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 26LU);
70196attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MultiStateValueDiscreteType");
70197retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
70198requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11238LU),
70199parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2372LU),
70200referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
70201browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MultiStateValueDiscreteType"),
70202typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
70203attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
70204if (retVal != UA_STATUSCODE_GOOD) return retVal;
70205return retVal;
70206}
70207
70208static UA_StatusCode function_namespace0_generated_95_finish(UA_Server *server, UA_UInt16* ns) {
70209return UA_Server_addNode_finish(server,
70210nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11238LU)
70211);
70212}
70213
70214/* ValueAsText - ns=0;i=11461 */
70215
70216static UA_StatusCode function_namespace0_generated_96_begin(UA_Server *server, UA_UInt16* ns) {
70217UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70218UA_VariableAttributes attr = UA_VariableAttributes_default;
70219attr.minimumSamplingInterval = 0.000000;
70220attr.userAccessLevel = 1;
70221attr.accessLevel = 1;
70222/* Value rank inherited */
70223attr.valueRank = -2;
70224attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
70225attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ValueAsText");
70226retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70227requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11461LU),
70228parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11238LU),
70229referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70230browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ValueAsText"),
70231typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70232attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70233if (retVal != UA_STATUSCODE_GOOD) return retVal;
70234return retVal;
70235}
70236
70237static UA_StatusCode function_namespace0_generated_96_finish(UA_Server *server, UA_UInt16* ns) {
70238return UA_Server_addNode_finish(server,
70239nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11461LU)
70240);
70241}
70242
70243/* EnumValues - ns=0;i=11241 */
70244
70245static UA_StatusCode function_namespace0_generated_97_begin(UA_Server *server, UA_UInt16* ns) {
70246UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70247UA_VariableAttributes attr = UA_VariableAttributes_default;
70248attr.minimumSamplingInterval = 0.000000;
70249attr.userAccessLevel = 1;
70250attr.accessLevel = 1;
70251attr.valueRank = 1;
70252attr.arrayDimensionsSize = 1;
70253UA_UInt32 arrayDimensions[1];
70254arrayDimensions[0] = 0;
70255attr.arrayDimensions = &arrayDimensions[0];
70256attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7594LU);
70257attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnumValues");
70258retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70259requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11241LU),
70260parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11238LU),
70261referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70262browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnumValues"),
70263typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70264attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70265if (retVal != UA_STATUSCODE_GOOD) return retVal;
70266return retVal;
70267}
70268
70269static UA_StatusCode function_namespace0_generated_97_finish(UA_Server *server, UA_UInt16* ns) {
70270return UA_Server_addNode_finish(server,
70271nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11241LU)
70272);
70273}
70274
70275/* AnalogItemType - ns=0;i=2368 */
70276
70277static UA_StatusCode function_namespace0_generated_98_begin(UA_Server *server, UA_UInt16* ns) {
70278UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70279UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
70280attr.valueRank = -2;
70281attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 26LU);
70282attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AnalogItemType");
70283retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
70284requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2368LU),
70285parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2365LU),
70286referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
70287browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AnalogItemType"),
70288typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
70289attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
70290if (retVal != UA_STATUSCODE_GOOD) return retVal;
70291return retVal;
70292}
70293
70294static UA_StatusCode function_namespace0_generated_98_finish(UA_Server *server, UA_UInt16* ns) {
70295return UA_Server_addNode_finish(server,
70296nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2368LU)
70297);
70298}
70299
70300/* EngineeringUnits - ns=0;i=2371 */
70301
70302static UA_StatusCode function_namespace0_generated_99_begin(UA_Server *server, UA_UInt16* ns) {
70303UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70304UA_VariableAttributes attr = UA_VariableAttributes_default;
70305attr.minimumSamplingInterval = 0.000000;
70306attr.userAccessLevel = 1;
70307attr.accessLevel = 1;
70308/* Value rank inherited */
70309attr.valueRank = -2;
70310attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 887LU);
70311attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EngineeringUnits");
70312retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70313requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2371LU),
70314parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2368LU),
70315referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70316browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EngineeringUnits"),
70317typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70318attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70319if (retVal != UA_STATUSCODE_GOOD) return retVal;
70320return retVal;
70321}
70322
70323static UA_StatusCode function_namespace0_generated_99_finish(UA_Server *server, UA_UInt16* ns) {
70324return UA_Server_addNode_finish(server,
70325nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2371LU)
70326);
70327}
70328
70329/* InstrumentRange - ns=0;i=2370 */
70330
70331static UA_StatusCode function_namespace0_generated_100_begin(UA_Server *server, UA_UInt16* ns) {
70332UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70333UA_VariableAttributes attr = UA_VariableAttributes_default;
70334attr.minimumSamplingInterval = 0.000000;
70335attr.userAccessLevel = 1;
70336attr.accessLevel = 1;
70337/* Value rank inherited */
70338attr.valueRank = -2;
70339attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 884LU);
70340attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InstrumentRange");
70341retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70342requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2370LU),
70343parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2368LU),
70344referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70345browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InstrumentRange"),
70346typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70347attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70348if (retVal != UA_STATUSCODE_GOOD) return retVal;
70349return retVal;
70350}
70351
70352static UA_StatusCode function_namespace0_generated_100_finish(UA_Server *server, UA_UInt16* ns) {
70353return UA_Server_addNode_finish(server,
70354nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2370LU)
70355);
70356}
70357
70358/* EURange - ns=0;i=2369 */
70359
70360static UA_StatusCode function_namespace0_generated_101_begin(UA_Server *server, UA_UInt16* ns) {
70361UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70362UA_VariableAttributes attr = UA_VariableAttributes_default;
70363attr.minimumSamplingInterval = 0.000000;
70364attr.userAccessLevel = 3;
70365attr.accessLevel = 3;
70366/* Value rank inherited */
70367attr.valueRank = -2;
70368attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 884LU);
70369attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EURange");
70370retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70371requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2369LU),
70372parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2368LU),
70373referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70374browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EURange"),
70375typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70376attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70377if (retVal != UA_STATUSCODE_GOOD) return retVal;
70378return retVal;
70379}
70380
70381static UA_StatusCode function_namespace0_generated_101_finish(UA_Server *server, UA_UInt16* ns) {
70382return UA_Server_addNode_finish(server,
70383nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2369LU)
70384);
70385}
70386
70387/* ValuePrecision - ns=0;i=2367 */
70388
70389static UA_StatusCode function_namespace0_generated_102_begin(UA_Server *server, UA_UInt16* ns) {
70390UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70391UA_VariableAttributes attr = UA_VariableAttributes_default;
70392attr.minimumSamplingInterval = 0.000000;
70393attr.userAccessLevel = 1;
70394attr.accessLevel = 1;
70395/* Value rank inherited */
70396attr.valueRank = -2;
70397attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11LU);
70398attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ValuePrecision");
70399#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS
70400attr.description = UA_LOCALIZEDTEXT(locale: "", text: "The maximum precision that the server can maintain for the item based on restrictions in the target environment.");
70401#endif
70402retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70403requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2367LU),
70404parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2365LU),
70405referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70406browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ValuePrecision"),
70407typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70408attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70409if (retVal != UA_STATUSCODE_GOOD) return retVal;
70410return retVal;
70411}
70412
70413static UA_StatusCode function_namespace0_generated_102_finish(UA_Server *server, UA_UInt16* ns) {
70414return UA_Server_addNode_finish(server,
70415nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2367LU)
70416);
70417}
70418
70419/* Definition - ns=0;i=2366 */
70420
70421static UA_StatusCode function_namespace0_generated_103_begin(UA_Server *server, UA_UInt16* ns) {
70422UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70423UA_VariableAttributes attr = UA_VariableAttributes_default;
70424attr.minimumSamplingInterval = 0.000000;
70425attr.userAccessLevel = 1;
70426attr.accessLevel = 1;
70427/* Value rank inherited */
70428attr.valueRank = -2;
70429attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
70430attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Definition");
70431#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS
70432attr.description = UA_LOCALIZEDTEXT(locale: "", text: "A vendor-specific, human readable string that specifies how the value of this DataItem is calculated.");
70433#endif
70434retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70435requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2366LU),
70436parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2365LU),
70437referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70438browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Definition"),
70439typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70440attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70441if (retVal != UA_STATUSCODE_GOOD) return retVal;
70442return retVal;
70443}
70444
70445static UA_StatusCode function_namespace0_generated_103_finish(UA_Server *server, UA_UInt16* ns) {
70446return UA_Server_addNode_finish(server,
70447nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2366LU)
70448);
70449}
70450
70451/* SubscribedDataSetType - ns=0;i=15108 */
70452
70453static UA_StatusCode function_namespace0_generated_104_begin(UA_Server *server, UA_UInt16* ns) {
70454UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70455UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
70456attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscribedDataSetType");
70457retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
70458requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15108LU),
70459parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
70460referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
70461browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscribedDataSetType"),
70462 typeDefinition: UA_NODEID_NULL,
70463attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
70464if (retVal != UA_STATUSCODE_GOOD) return retVal;
70465return retVal;
70466}
70467
70468static UA_StatusCode function_namespace0_generated_104_finish(UA_Server *server, UA_UInt16* ns) {
70469return UA_Server_addNode_finish(server,
70470nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15108LU)
70471);
70472}
70473
70474/* TargetVariablesType - ns=0;i=15111 */
70475
70476static UA_StatusCode function_namespace0_generated_105_begin(UA_Server *server, UA_UInt16* ns) {
70477UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70478UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
70479attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TargetVariablesType");
70480retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
70481requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15111LU),
70482parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15108LU),
70483referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
70484browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TargetVariablesType"),
70485 typeDefinition: UA_NODEID_NULL,
70486attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
70487if (retVal != UA_STATUSCODE_GOOD) return retVal;
70488return retVal;
70489}
70490
70491static UA_StatusCode function_namespace0_generated_105_finish(UA_Server *server, UA_UInt16* ns) {
70492return UA_Server_addNode_finish(server,
70493nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15111LU)
70494);
70495}
70496
70497/* RemoveTargetVariables - ns=0;i=15118 */
70498
70499static UA_StatusCode function_namespace0_generated_106_begin(UA_Server *server, UA_UInt16* ns) {
70500#ifdef UA_ENABLE_METHODCALLS
70501UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70502UA_MethodAttributes attr = UA_MethodAttributes_default;
70503attr.executable = true;
70504attr.userExecutable = true;
70505attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RemoveTargetVariables");
70506retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
70507requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15118LU),
70508parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15108LU),
70509referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
70510browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RemoveTargetVariables"),
70511 typeDefinition: UA_NODEID_NULL,
70512attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
70513if (retVal != UA_STATUSCODE_GOOD) return retVal;
70514retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15118LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15111LU), false);
70515if (retVal != UA_STATUSCODE_GOOD) return retVal;
70516return retVal;
70517#else
70518return UA_STATUSCODE_GOOD;
70519#endif /* UA_ENABLE_METHODCALLS */
70520}
70521
70522static UA_StatusCode function_namespace0_generated_106_finish(UA_Server *server, UA_UInt16* ns) {
70523#ifdef UA_ENABLE_METHODCALLS
70524return UA_Server_addMethodNode_finish(server,
70525nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15118LU)
70526, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
70527#else
70528return UA_STATUSCODE_GOOD;
70529#endif /* UA_ENABLE_METHODCALLS */
70530}
70531
70532/* OutputArguments - ns=0;i=15120 */
70533
70534static UA_StatusCode function_namespace0_generated_107_begin(UA_Server *server, UA_UInt16* ns) {
70535#ifdef UA_ENABLE_METHODCALLS
70536UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70537UA_VariableAttributes attr = UA_VariableAttributes_default;
70538attr.minimumSamplingInterval = 0.000000;
70539attr.userAccessLevel = 1;
70540attr.accessLevel = 1;
70541attr.valueRank = 1;
70542attr.arrayDimensionsSize = 1;
70543UA_UInt32 arrayDimensions[1];
70544arrayDimensions[0] = 0;
70545attr.arrayDimensions = &arrayDimensions[0];
70546attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
70547UA_Argument variablenode_ns_0_i_15120_variant_DataContents[1];
70548
70549UA_init(p: &variablenode_ns_0_i_15120_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
70550variablenode_ns_0_i_15120_variant_DataContents[0].name = UA_STRING(chars: "AddResults");
70551variablenode_ns_0_i_15120_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 19LU);
70552variablenode_ns_0_i_15120_variant_DataContents[0].valueRank = (UA_Int32) -1;
70553UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_15120_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
70554attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
70555retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70556requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15120LU),
70557parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15118LU),
70558referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70559browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
70560typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70561attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70562if (retVal != UA_STATUSCODE_GOOD) return retVal;
70563
70564return retVal;
70565#else
70566return UA_STATUSCODE_GOOD;
70567#endif /* UA_ENABLE_METHODCALLS */
70568}
70569
70570static UA_StatusCode function_namespace0_generated_107_finish(UA_Server *server, UA_UInt16* ns) {
70571#ifdef UA_ENABLE_METHODCALLS
70572return UA_Server_addNode_finish(server,
70573nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15120LU)
70574);
70575#else
70576return UA_STATUSCODE_GOOD;
70577#endif /* UA_ENABLE_METHODCALLS */
70578}
70579
70580/* InputArguments - ns=0;i=15119 */
70581
70582static UA_StatusCode function_namespace0_generated_108_begin(UA_Server *server, UA_UInt16* ns) {
70583#ifdef UA_ENABLE_METHODCALLS
70584UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70585UA_VariableAttributes attr = UA_VariableAttributes_default;
70586attr.minimumSamplingInterval = 0.000000;
70587attr.userAccessLevel = 1;
70588attr.accessLevel = 1;
70589attr.valueRank = 1;
70590attr.arrayDimensionsSize = 1;
70591UA_UInt32 arrayDimensions[1];
70592arrayDimensions[0] = 0;
70593attr.arrayDimensions = &arrayDimensions[0];
70594attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
70595UA_Argument variablenode_ns_0_i_15119_variant_DataContents[1];
70596
70597UA_init(p: &variablenode_ns_0_i_15119_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
70598variablenode_ns_0_i_15119_variant_DataContents[0].name = UA_STRING(chars: "ConfigurationVersion");
70599variablenode_ns_0_i_15119_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14593LU);
70600variablenode_ns_0_i_15119_variant_DataContents[0].valueRank = (UA_Int32) -1;
70601UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_15119_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
70602attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
70603retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70604requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15119LU),
70605parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15118LU),
70606referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70607browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
70608typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70609attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70610if (retVal != UA_STATUSCODE_GOOD) return retVal;
70611
70612return retVal;
70613#else
70614return UA_STATUSCODE_GOOD;
70615#endif /* UA_ENABLE_METHODCALLS */
70616}
70617
70618static UA_StatusCode function_namespace0_generated_108_finish(UA_Server *server, UA_UInt16* ns) {
70619#ifdef UA_ENABLE_METHODCALLS
70620return UA_Server_addNode_finish(server,
70621nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15119LU)
70622);
70623#else
70624return UA_STATUSCODE_GOOD;
70625#endif /* UA_ENABLE_METHODCALLS */
70626}
70627
70628/* AddTargetVariables - ns=0;i=15115 */
70629
70630static UA_StatusCode function_namespace0_generated_109_begin(UA_Server *server, UA_UInt16* ns) {
70631#ifdef UA_ENABLE_METHODCALLS
70632UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70633UA_MethodAttributes attr = UA_MethodAttributes_default;
70634attr.executable = true;
70635attr.userExecutable = true;
70636attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddTargetVariables");
70637retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
70638requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15115LU),
70639parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15108LU),
70640referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
70641browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddTargetVariables"),
70642 typeDefinition: UA_NODEID_NULL,
70643attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
70644if (retVal != UA_STATUSCODE_GOOD) return retVal;
70645retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15115LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15111LU), false);
70646if (retVal != UA_STATUSCODE_GOOD) return retVal;
70647return retVal;
70648#else
70649return UA_STATUSCODE_GOOD;
70650#endif /* UA_ENABLE_METHODCALLS */
70651}
70652
70653static UA_StatusCode function_namespace0_generated_109_finish(UA_Server *server, UA_UInt16* ns) {
70654#ifdef UA_ENABLE_METHODCALLS
70655return UA_Server_addMethodNode_finish(server,
70656nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15115LU)
70657, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
70658#else
70659return UA_STATUSCODE_GOOD;
70660#endif /* UA_ENABLE_METHODCALLS */
70661}
70662
70663/* OutputArguments - ns=0;i=15117 */
70664
70665static UA_StatusCode function_namespace0_generated_110_begin(UA_Server *server, UA_UInt16* ns) {
70666#ifdef UA_ENABLE_METHODCALLS
70667UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70668UA_VariableAttributes attr = UA_VariableAttributes_default;
70669attr.minimumSamplingInterval = 0.000000;
70670attr.userAccessLevel = 1;
70671attr.accessLevel = 1;
70672attr.valueRank = 1;
70673attr.arrayDimensionsSize = 1;
70674UA_UInt32 arrayDimensions[1];
70675arrayDimensions[0] = 0;
70676attr.arrayDimensions = &arrayDimensions[0];
70677attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
70678UA_Argument variablenode_ns_0_i_15117_variant_DataContents[1];
70679
70680UA_init(p: &variablenode_ns_0_i_15117_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
70681variablenode_ns_0_i_15117_variant_DataContents[0].name = UA_STRING(chars: "AddResults");
70682variablenode_ns_0_i_15117_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 19LU);
70683variablenode_ns_0_i_15117_variant_DataContents[0].valueRank = (UA_Int32) -1;
70684UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_15117_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
70685attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
70686retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70687requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15117LU),
70688parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15115LU),
70689referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70690browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
70691typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70692attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70693if (retVal != UA_STATUSCODE_GOOD) return retVal;
70694
70695return retVal;
70696#else
70697return UA_STATUSCODE_GOOD;
70698#endif /* UA_ENABLE_METHODCALLS */
70699}
70700
70701static UA_StatusCode function_namespace0_generated_110_finish(UA_Server *server, UA_UInt16* ns) {
70702#ifdef UA_ENABLE_METHODCALLS
70703return UA_Server_addNode_finish(server,
70704nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15117LU)
70705);
70706#else
70707return UA_STATUSCODE_GOOD;
70708#endif /* UA_ENABLE_METHODCALLS */
70709}
70710
70711/* InputArguments - ns=0;i=15116 */
70712
70713static UA_StatusCode function_namespace0_generated_111_begin(UA_Server *server, UA_UInt16* ns) {
70714#ifdef UA_ENABLE_METHODCALLS
70715UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70716UA_VariableAttributes attr = UA_VariableAttributes_default;
70717attr.minimumSamplingInterval = 0.000000;
70718attr.userAccessLevel = 1;
70719attr.accessLevel = 1;
70720attr.valueRank = 1;
70721attr.arrayDimensionsSize = 1;
70722UA_UInt32 arrayDimensions[1];
70723arrayDimensions[0] = 0;
70724attr.arrayDimensions = &arrayDimensions[0];
70725attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
70726UA_Argument variablenode_ns_0_i_15116_variant_DataContents[1];
70727
70728UA_init(p: &variablenode_ns_0_i_15116_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
70729variablenode_ns_0_i_15116_variant_DataContents[0].name = UA_STRING(chars: "ConfigurationVersion");
70730variablenode_ns_0_i_15116_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14593LU);
70731variablenode_ns_0_i_15116_variant_DataContents[0].valueRank = (UA_Int32) -1;
70732UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_15116_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
70733attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
70734retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70735requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15116LU),
70736parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15115LU),
70737referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70738browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
70739typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70740attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70741if (retVal != UA_STATUSCODE_GOOD) return retVal;
70742
70743return retVal;
70744#else
70745return UA_STATUSCODE_GOOD;
70746#endif /* UA_ENABLE_METHODCALLS */
70747}
70748
70749static UA_StatusCode function_namespace0_generated_111_finish(UA_Server *server, UA_UInt16* ns) {
70750#ifdef UA_ENABLE_METHODCALLS
70751return UA_Server_addNode_finish(server,
70752nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15116LU)
70753);
70754#else
70755return UA_STATUSCODE_GOOD;
70756#endif /* UA_ENABLE_METHODCALLS */
70757}
70758
70759/* TargetVariables - ns=0;i=15114 */
70760
70761static UA_StatusCode function_namespace0_generated_112_begin(UA_Server *server, UA_UInt16* ns) {
70762UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70763UA_VariableAttributes attr = UA_VariableAttributes_default;
70764attr.minimumSamplingInterval = 0.000000;
70765attr.userAccessLevel = 1;
70766attr.accessLevel = 1;
70767/* Value rank inherited */
70768attr.valueRank = -2;
70769/* DataType inherited */
70770attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
70771attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TargetVariables");
70772retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70773requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15114LU),
70774parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15111LU),
70775referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70776browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TargetVariables"),
70777typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70778attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70779if (retVal != UA_STATUSCODE_GOOD) return retVal;
70780return retVal;
70781}
70782
70783static UA_StatusCode function_namespace0_generated_112_finish(UA_Server *server, UA_UInt16* ns) {
70784return UA_Server_addNode_finish(server,
70785nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15114LU)
70786);
70787}
70788
70789/* DataSetReaderMessageType - ns=0;i=21104 */
70790
70791static UA_StatusCode function_namespace0_generated_113_begin(UA_Server *server, UA_UInt16* ns) {
70792UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70793UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
70794attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetReaderMessageType");
70795retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
70796requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21104LU),
70797parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
70798referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
70799browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetReaderMessageType"),
70800 typeDefinition: UA_NODEID_NULL,
70801attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
70802if (retVal != UA_STATUSCODE_GOOD) return retVal;
70803return retVal;
70804}
70805
70806static UA_StatusCode function_namespace0_generated_113_finish(UA_Server *server, UA_UInt16* ns) {
70807return UA_Server_addNode_finish(server,
70808nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21104LU)
70809);
70810}
70811
70812/* UadpDataSetReaderMessageType - ns=0;i=21116 */
70813
70814static UA_StatusCode function_namespace0_generated_114_begin(UA_Server *server, UA_UInt16* ns) {
70815UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70816UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
70817attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UadpDataSetReaderMessageType");
70818retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
70819requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21116LU),
70820parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21104LU),
70821referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
70822browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UadpDataSetReaderMessageType"),
70823 typeDefinition: UA_NODEID_NULL,
70824attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
70825if (retVal != UA_STATUSCODE_GOOD) return retVal;
70826return retVal;
70827}
70828
70829static UA_StatusCode function_namespace0_generated_114_finish(UA_Server *server, UA_UInt16* ns) {
70830return UA_Server_addNode_finish(server,
70831nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21116LU)
70832);
70833}
70834
70835/* DataSetReaderTransportType - ns=0;i=15319 */
70836
70837static UA_StatusCode function_namespace0_generated_115_begin(UA_Server *server, UA_UInt16* ns) {
70838UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70839UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
70840attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetReaderTransportType");
70841retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
70842requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15319LU),
70843parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
70844referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
70845browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetReaderTransportType"),
70846 typeDefinition: UA_NODEID_NULL,
70847attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
70848if (retVal != UA_STATUSCODE_GOOD) return retVal;
70849return retVal;
70850}
70851
70852static UA_StatusCode function_namespace0_generated_115_finish(UA_Server *server, UA_UInt16* ns) {
70853return UA_Server_addNode_finish(server,
70854nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15319LU)
70855);
70856}
70857
70858/* BrokerDataSetReaderTransportType - ns=0;i=21142 */
70859
70860static UA_StatusCode function_namespace0_generated_116_begin(UA_Server *server, UA_UInt16* ns) {
70861UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70862UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
70863attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BrokerDataSetReaderTransportType");
70864retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
70865requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21142LU),
70866parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
70867referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
70868browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BrokerDataSetReaderTransportType"),
70869 typeDefinition: UA_NODEID_NULL,
70870attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
70871if (retVal != UA_STATUSCODE_GOOD) return retVal;
70872retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21142LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15319LU), false);
70873if (retVal != UA_STATUSCODE_GOOD) return retVal;
70874return retVal;
70875}
70876
70877static UA_StatusCode function_namespace0_generated_116_finish(UA_Server *server, UA_UInt16* ns) {
70878return UA_Server_addNode_finish(server,
70879nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21142LU)
70880);
70881}
70882
70883/* DataSetReaderType - ns=0;i=15306 */
70884
70885static UA_StatusCode function_namespace0_generated_117_begin(UA_Server *server, UA_UInt16* ns) {
70886UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70887UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
70888attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetReaderType");
70889retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
70890requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15306LU),
70891parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
70892referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
70893browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetReaderType"),
70894 typeDefinition: UA_NODEID_NULL,
70895attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
70896if (retVal != UA_STATUSCODE_GOOD) return retVal;
70897return retVal;
70898}
70899
70900static UA_StatusCode function_namespace0_generated_117_finish(UA_Server *server, UA_UInt16* ns) {
70901return UA_Server_addNode_finish(server,
70902nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15306LU)
70903);
70904}
70905
70906/* MessageSettings - ns=0;i=21103 */
70907
70908static UA_StatusCode function_namespace0_generated_118_begin(UA_Server *server, UA_UInt16* ns) {
70909UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70910UA_ObjectAttributes attr = UA_ObjectAttributes_default;
70911attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MessageSettings");
70912retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
70913requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21103LU),
70914parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15306LU),
70915referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
70916browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MessageSettings"),
70917typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21104LU),
70918attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
70919if (retVal != UA_STATUSCODE_GOOD) return retVal;
70920return retVal;
70921}
70922
70923static UA_StatusCode function_namespace0_generated_118_finish(UA_Server *server, UA_UInt16* ns) {
70924return UA_Server_addNode_finish(server,
70925nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21103LU)
70926);
70927}
70928
70929/* MessageReceiveTimeout - ns=0;i=21102 */
70930
70931static UA_StatusCode function_namespace0_generated_119_begin(UA_Server *server, UA_UInt16* ns) {
70932UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70933UA_VariableAttributes attr = UA_VariableAttributes_default;
70934attr.minimumSamplingInterval = 0.000000;
70935attr.userAccessLevel = 1;
70936attr.accessLevel = 1;
70937/* Value rank inherited */
70938attr.valueRank = -2;
70939attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU);
70940attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MessageReceiveTimeout");
70941retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70942requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21102LU),
70943parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15306LU),
70944referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70945browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MessageReceiveTimeout"),
70946typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70947attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70948if (retVal != UA_STATUSCODE_GOOD) return retVal;
70949return retVal;
70950}
70951
70952static UA_StatusCode function_namespace0_generated_119_finish(UA_Server *server, UA_UInt16* ns) {
70953return UA_Server_addNode_finish(server,
70954nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21102LU)
70955);
70956}
70957
70958/* DataSetFieldContentMask - ns=0;i=21101 */
70959
70960static UA_StatusCode function_namespace0_generated_120_begin(UA_Server *server, UA_UInt16* ns) {
70961UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70962UA_VariableAttributes attr = UA_VariableAttributes_default;
70963attr.minimumSamplingInterval = 0.000000;
70964attr.userAccessLevel = 1;
70965attr.accessLevel = 1;
70966/* Value rank inherited */
70967attr.valueRank = -2;
70968attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15583LU);
70969attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetFieldContentMask");
70970retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
70971requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21101LU),
70972parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15306LU),
70973referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
70974browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetFieldContentMask"),
70975typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
70976attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
70977if (retVal != UA_STATUSCODE_GOOD) return retVal;
70978return retVal;
70979}
70980
70981static UA_StatusCode function_namespace0_generated_120_finish(UA_Server *server, UA_UInt16* ns) {
70982return UA_Server_addNode_finish(server,
70983nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21101LU)
70984);
70985}
70986
70987/* DataSetMetaData - ns=0;i=21100 */
70988
70989static UA_StatusCode function_namespace0_generated_121_begin(UA_Server *server, UA_UInt16* ns) {
70990UA_StatusCode retVal = UA_STATUSCODE_GOOD;
70991UA_VariableAttributes attr = UA_VariableAttributes_default;
70992attr.minimumSamplingInterval = 0.000000;
70993attr.userAccessLevel = 1;
70994attr.accessLevel = 1;
70995/* Value rank inherited */
70996attr.valueRank = -2;
70997attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14523LU);
70998attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetMetaData");
70999retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71000requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21100LU),
71001parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15306LU),
71002referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71003browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetMetaData"),
71004typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71005attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71006if (retVal != UA_STATUSCODE_GOOD) return retVal;
71007return retVal;
71008}
71009
71010static UA_StatusCode function_namespace0_generated_121_finish(UA_Server *server, UA_UInt16* ns) {
71011return UA_Server_addNode_finish(server,
71012nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21100LU)
71013);
71014}
71015
71016/* DataSetWriterId - ns=0;i=21099 */
71017
71018static UA_StatusCode function_namespace0_generated_122_begin(UA_Server *server, UA_UInt16* ns) {
71019UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71020UA_VariableAttributes attr = UA_VariableAttributes_default;
71021attr.minimumSamplingInterval = 0.000000;
71022attr.userAccessLevel = 1;
71023attr.accessLevel = 1;
71024/* Value rank inherited */
71025attr.valueRank = -2;
71026attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
71027attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetWriterId");
71028retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71029requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21099LU),
71030parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15306LU),
71031referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71032browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetWriterId"),
71033typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71034attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71035if (retVal != UA_STATUSCODE_GOOD) return retVal;
71036return retVal;
71037}
71038
71039static UA_StatusCode function_namespace0_generated_122_finish(UA_Server *server, UA_UInt16* ns) {
71040return UA_Server_addNode_finish(server,
71041nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21099LU)
71042);
71043}
71044
71045/* WriterGroupId - ns=0;i=21098 */
71046
71047static UA_StatusCode function_namespace0_generated_123_begin(UA_Server *server, UA_UInt16* ns) {
71048UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71049UA_VariableAttributes attr = UA_VariableAttributes_default;
71050attr.minimumSamplingInterval = 0.000000;
71051attr.userAccessLevel = 1;
71052attr.accessLevel = 1;
71053/* Value rank inherited */
71054attr.valueRank = -2;
71055attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
71056attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "WriterGroupId");
71057retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71058requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21098LU),
71059parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15306LU),
71060referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71061browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "WriterGroupId"),
71062typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71063attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71064if (retVal != UA_STATUSCODE_GOOD) return retVal;
71065return retVal;
71066}
71067
71068static UA_StatusCode function_namespace0_generated_123_finish(UA_Server *server, UA_UInt16* ns) {
71069return UA_Server_addNode_finish(server,
71070nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21098LU)
71071);
71072}
71073
71074/* PublisherId - ns=0;i=21097 */
71075
71076static UA_StatusCode function_namespace0_generated_124_begin(UA_Server *server, UA_UInt16* ns) {
71077UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71078UA_VariableAttributes attr = UA_VariableAttributes_default;
71079attr.minimumSamplingInterval = 0.000000;
71080attr.userAccessLevel = 1;
71081attr.accessLevel = 1;
71082/* Value rank inherited */
71083attr.valueRank = -2;
71084/* DataType inherited */
71085attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
71086attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublisherId");
71087retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71088requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21097LU),
71089parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15306LU),
71090referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71091browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublisherId"),
71092typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71093attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71094if (retVal != UA_STATUSCODE_GOOD) return retVal;
71095return retVal;
71096}
71097
71098static UA_StatusCode function_namespace0_generated_124_finish(UA_Server *server, UA_UInt16* ns) {
71099return UA_Server_addNode_finish(server,
71100nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21097LU)
71101);
71102}
71103
71104/* DataSetReaderProperties - ns=0;i=17494 */
71105
71106static UA_StatusCode function_namespace0_generated_125_begin(UA_Server *server, UA_UInt16* ns) {
71107UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71108UA_VariableAttributes attr = UA_VariableAttributes_default;
71109attr.minimumSamplingInterval = 0.000000;
71110attr.userAccessLevel = 1;
71111attr.accessLevel = 1;
71112attr.valueRank = 1;
71113attr.arrayDimensionsSize = 1;
71114UA_UInt32 arrayDimensions[1];
71115arrayDimensions[0] = 0;
71116attr.arrayDimensions = &arrayDimensions[0];
71117attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14533LU);
71118attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetReaderProperties");
71119retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71120requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17494LU),
71121parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15306LU),
71122referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71123browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetReaderProperties"),
71124typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71125attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71126if (retVal != UA_STATUSCODE_GOOD) return retVal;
71127return retVal;
71128}
71129
71130static UA_StatusCode function_namespace0_generated_125_finish(UA_Server *server, UA_UInt16* ns) {
71131return UA_Server_addNode_finish(server,
71132nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17494LU)
71133);
71134}
71135
71136/* SubscribedDataSet - ns=0;i=15316 */
71137
71138static UA_StatusCode function_namespace0_generated_126_begin(UA_Server *server, UA_UInt16* ns) {
71139UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71140UA_ObjectAttributes attr = UA_ObjectAttributes_default;
71141attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscribedDataSet");
71142retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
71143requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15316LU),
71144parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15306LU),
71145referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
71146browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscribedDataSet"),
71147typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15108LU),
71148attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
71149if (retVal != UA_STATUSCODE_GOOD) return retVal;
71150return retVal;
71151}
71152
71153static UA_StatusCode function_namespace0_generated_126_finish(UA_Server *server, UA_UInt16* ns) {
71154return UA_Server_addNode_finish(server,
71155nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15316LU)
71156);
71157}
71158
71159/* TransportSettings - ns=0;i=15311 */
71160
71161static UA_StatusCode function_namespace0_generated_127_begin(UA_Server *server, UA_UInt16* ns) {
71162UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71163UA_ObjectAttributes attr = UA_ObjectAttributes_default;
71164attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransportSettings");
71165retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
71166requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15311LU),
71167parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15306LU),
71168referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
71169browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransportSettings"),
71170typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15319LU),
71171attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
71172if (retVal != UA_STATUSCODE_GOOD) return retVal;
71173return retVal;
71174}
71175
71176static UA_StatusCode function_namespace0_generated_127_finish(UA_Server *server, UA_UInt16* ns) {
71177return UA_Server_addNode_finish(server,
71178nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15311LU)
71179);
71180}
71181
71182/* DataSetWriterMessageType - ns=0;i=21096 */
71183
71184static UA_StatusCode function_namespace0_generated_128_begin(UA_Server *server, UA_UInt16* ns) {
71185UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71186UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
71187attr.isAbstract = true;
71188attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetWriterMessageType");
71189retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
71190requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21096LU),
71191parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
71192referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
71193browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetWriterMessageType"),
71194 typeDefinition: UA_NODEID_NULL,
71195attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
71196if (retVal != UA_STATUSCODE_GOOD) return retVal;
71197return retVal;
71198}
71199
71200static UA_StatusCode function_namespace0_generated_128_finish(UA_Server *server, UA_UInt16* ns) {
71201return UA_Server_addNode_finish(server,
71202nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21096LU)
71203);
71204}
71205
71206/* UadpDataSetWriterMessageType - ns=0;i=21111 */
71207
71208static UA_StatusCode function_namespace0_generated_129_begin(UA_Server *server, UA_UInt16* ns) {
71209UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71210UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
71211attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UadpDataSetWriterMessageType");
71212retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
71213requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21111LU),
71214parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21096LU),
71215referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
71216browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UadpDataSetWriterMessageType"),
71217 typeDefinition: UA_NODEID_NULL,
71218attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
71219if (retVal != UA_STATUSCODE_GOOD) return retVal;
71220return retVal;
71221}
71222
71223static UA_StatusCode function_namespace0_generated_129_finish(UA_Server *server, UA_UInt16* ns) {
71224return UA_Server_addNode_finish(server,
71225nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21111LU)
71226);
71227}
71228
71229/* WriterGroupMessageType - ns=0;i=17998 */
71230
71231static UA_StatusCode function_namespace0_generated_130_begin(UA_Server *server, UA_UInt16* ns) {
71232UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71233UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
71234attr.isAbstract = true;
71235attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "WriterGroupMessageType");
71236retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
71237requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17998LU),
71238parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
71239referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
71240browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "WriterGroupMessageType"),
71241 typeDefinition: UA_NODEID_NULL,
71242attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
71243if (retVal != UA_STATUSCODE_GOOD) return retVal;
71244return retVal;
71245}
71246
71247static UA_StatusCode function_namespace0_generated_130_finish(UA_Server *server, UA_UInt16* ns) {
71248return UA_Server_addNode_finish(server,
71249nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17998LU)
71250);
71251}
71252
71253/* UadpWriterGroupMessageType - ns=0;i=21105 */
71254
71255static UA_StatusCode function_namespace0_generated_131_begin(UA_Server *server, UA_UInt16* ns) {
71256UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71257UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
71258attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UadpWriterGroupMessageType");
71259retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
71260requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21105LU),
71261parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17998LU),
71262referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
71263browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UadpWriterGroupMessageType"),
71264 typeDefinition: UA_NODEID_NULL,
71265attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
71266if (retVal != UA_STATUSCODE_GOOD) return retVal;
71267return retVal;
71268}
71269
71270static UA_StatusCode function_namespace0_generated_131_finish(UA_Server *server, UA_UInt16* ns) {
71271return UA_Server_addNode_finish(server,
71272nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21105LU)
71273);
71274}
71275
71276/* SelectionListType - ns=0;i=16309 */
71277
71278static UA_StatusCode function_namespace0_generated_132_begin(UA_Server *server, UA_UInt16* ns) {
71279UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71280UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
71281attr.valueRank = -2;
71282/* DataType inherited */
71283attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
71284attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SelectionListType");
71285retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
71286requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16309LU),
71287parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
71288referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
71289browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SelectionListType"),
71290typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
71291attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
71292if (retVal != UA_STATUSCODE_GOOD) return retVal;
71293return retVal;
71294}
71295
71296static UA_StatusCode function_namespace0_generated_132_finish(UA_Server *server, UA_UInt16* ns) {
71297return UA_Server_addNode_finish(server,
71298nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16309LU)
71299);
71300}
71301
71302/* SelectionDescriptions - ns=0;i=17633 */
71303
71304static UA_StatusCode function_namespace0_generated_133_begin(UA_Server *server, UA_UInt16* ns) {
71305UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71306UA_VariableAttributes attr = UA_VariableAttributes_default;
71307attr.minimumSamplingInterval = 0.000000;
71308attr.userAccessLevel = 1;
71309attr.accessLevel = 1;
71310attr.valueRank = 1;
71311attr.arrayDimensionsSize = 1;
71312UA_UInt32 arrayDimensions[1];
71313arrayDimensions[0] = 0;
71314attr.arrayDimensions = &arrayDimensions[0];
71315attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
71316attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SelectionDescriptions");
71317retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71318requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17633LU),
71319parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16309LU),
71320referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71321browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SelectionDescriptions"),
71322typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71323attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71324if (retVal != UA_STATUSCODE_GOOD) return retVal;
71325return retVal;
71326}
71327
71328static UA_StatusCode function_namespace0_generated_133_finish(UA_Server *server, UA_UInt16* ns) {
71329return UA_Server_addNode_finish(server,
71330nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17633LU)
71331);
71332}
71333
71334/* Selections - ns=0;i=17632 */
71335
71336static UA_StatusCode function_namespace0_generated_134_begin(UA_Server *server, UA_UInt16* ns) {
71337UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71338UA_VariableAttributes attr = UA_VariableAttributes_default;
71339attr.minimumSamplingInterval = 0.000000;
71340attr.userAccessLevel = 1;
71341attr.accessLevel = 1;
71342attr.valueRank = 1;
71343attr.arrayDimensionsSize = 1;
71344UA_UInt32 arrayDimensions[1];
71345arrayDimensions[0] = 0;
71346attr.arrayDimensions = &arrayDimensions[0];
71347/* DataType inherited */
71348attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
71349attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Selections");
71350retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71351requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17632LU),
71352parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16309LU),
71353referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71354browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Selections"),
71355typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71356attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71357if (retVal != UA_STATUSCODE_GOOD) return retVal;
71358return retVal;
71359}
71360
71361static UA_StatusCode function_namespace0_generated_134_finish(UA_Server *server, UA_UInt16* ns) {
71362return UA_Server_addNode_finish(server,
71363nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17632LU)
71364);
71365}
71366
71367/* RestrictToList - ns=0;i=16312 */
71368
71369static UA_StatusCode function_namespace0_generated_135_begin(UA_Server *server, UA_UInt16* ns) {
71370UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71371UA_VariableAttributes attr = UA_VariableAttributes_default;
71372attr.minimumSamplingInterval = 0.000000;
71373attr.userAccessLevel = 1;
71374attr.accessLevel = 1;
71375/* Value rank inherited */
71376attr.valueRank = -2;
71377attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
71378attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RestrictToList");
71379retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71380requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16312LU),
71381parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16309LU),
71382referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71383browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RestrictToList"),
71384typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71385attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71386if (retVal != UA_STATUSCODE_GOOD) return retVal;
71387return retVal;
71388}
71389
71390static UA_StatusCode function_namespace0_generated_135_finish(UA_Server *server, UA_UInt16* ns) {
71391return UA_Server_addNode_finish(server,
71392nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16312LU)
71393);
71394}
71395
71396/* PubSubStatusType - ns=0;i=14643 */
71397
71398static UA_StatusCode function_namespace0_generated_136_begin(UA_Server *server, UA_UInt16* ns) {
71399UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71400UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
71401attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PubSubStatusType");
71402retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
71403requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14643LU),
71404parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
71405referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
71406browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PubSubStatusType"),
71407 typeDefinition: UA_NODEID_NULL,
71408attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
71409if (retVal != UA_STATUSCODE_GOOD) return retVal;
71410return retVal;
71411}
71412
71413static UA_StatusCode function_namespace0_generated_136_finish(UA_Server *server, UA_UInt16* ns) {
71414return UA_Server_addNode_finish(server,
71415nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14643LU)
71416);
71417}
71418
71419/* Disable - ns=0;i=14646 */
71420
71421static UA_StatusCode function_namespace0_generated_137_begin(UA_Server *server, UA_UInt16* ns) {
71422#ifdef UA_ENABLE_METHODCALLS
71423UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71424UA_MethodAttributes attr = UA_MethodAttributes_default;
71425attr.executable = true;
71426attr.userExecutable = true;
71427attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Disable");
71428retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
71429requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14646LU),
71430parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14643LU),
71431referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
71432browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Disable"),
71433 typeDefinition: UA_NODEID_NULL,
71434attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
71435if (retVal != UA_STATUSCODE_GOOD) return retVal;
71436return retVal;
71437#else
71438return UA_STATUSCODE_GOOD;
71439#endif /* UA_ENABLE_METHODCALLS */
71440}
71441
71442static UA_StatusCode function_namespace0_generated_137_finish(UA_Server *server, UA_UInt16* ns) {
71443#ifdef UA_ENABLE_METHODCALLS
71444return UA_Server_addMethodNode_finish(server,
71445nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14646LU)
71446, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
71447#else
71448return UA_STATUSCODE_GOOD;
71449#endif /* UA_ENABLE_METHODCALLS */
71450}
71451
71452/* Enable - ns=0;i=14645 */
71453
71454static UA_StatusCode function_namespace0_generated_138_begin(UA_Server *server, UA_UInt16* ns) {
71455#ifdef UA_ENABLE_METHODCALLS
71456UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71457UA_MethodAttributes attr = UA_MethodAttributes_default;
71458attr.executable = true;
71459attr.userExecutable = true;
71460attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Enable");
71461retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
71462requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14645LU),
71463parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14643LU),
71464referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
71465browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Enable"),
71466 typeDefinition: UA_NODEID_NULL,
71467attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
71468if (retVal != UA_STATUSCODE_GOOD) return retVal;
71469return retVal;
71470#else
71471return UA_STATUSCODE_GOOD;
71472#endif /* UA_ENABLE_METHODCALLS */
71473}
71474
71475static UA_StatusCode function_namespace0_generated_138_finish(UA_Server *server, UA_UInt16* ns) {
71476#ifdef UA_ENABLE_METHODCALLS
71477return UA_Server_addMethodNode_finish(server,
71478nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14645LU)
71479, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
71480#else
71481return UA_STATUSCODE_GOOD;
71482#endif /* UA_ENABLE_METHODCALLS */
71483}
71484
71485/* State - ns=0;i=14644 */
71486
71487static UA_StatusCode function_namespace0_generated_139_begin(UA_Server *server, UA_UInt16* ns) {
71488UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71489UA_VariableAttributes attr = UA_VariableAttributes_default;
71490attr.minimumSamplingInterval = 0.000000;
71491attr.userAccessLevel = 1;
71492attr.accessLevel = 1;
71493/* Value rank inherited */
71494attr.valueRank = -2;
71495attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14647LU);
71496attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "State");
71497retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71498requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14644LU),
71499parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14643LU),
71500referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
71501browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "State"),
71502typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
71503attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71504if (retVal != UA_STATUSCODE_GOOD) return retVal;
71505return retVal;
71506}
71507
71508static UA_StatusCode function_namespace0_generated_139_finish(UA_Server *server, UA_UInt16* ns) {
71509return UA_Server_addNode_finish(server,
71510nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14644LU)
71511);
71512}
71513
71514/* StandaloneSubscribedDataSetType - ns=0;i=23828 */
71515
71516static UA_StatusCode function_namespace0_generated_140_begin(UA_Server *server, UA_UInt16* ns) {
71517UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71518UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
71519attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "StandaloneSubscribedDataSetType");
71520retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
71521requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23828LU),
71522parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
71523referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
71524browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "StandaloneSubscribedDataSetType"),
71525 typeDefinition: UA_NODEID_NULL,
71526attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
71527if (retVal != UA_STATUSCODE_GOOD) return retVal;
71528return retVal;
71529}
71530
71531static UA_StatusCode function_namespace0_generated_140_finish(UA_Server *server, UA_UInt16* ns) {
71532return UA_Server_addNode_finish(server,
71533nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23828LU)
71534);
71535}
71536
71537/* IsConnected - ns=0;i=23831 */
71538
71539static UA_StatusCode function_namespace0_generated_141_begin(UA_Server *server, UA_UInt16* ns) {
71540UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71541UA_VariableAttributes attr = UA_VariableAttributes_default;
71542attr.minimumSamplingInterval = 0.000000;
71543attr.userAccessLevel = 1;
71544attr.accessLevel = 1;
71545/* Value rank inherited */
71546attr.valueRank = -2;
71547attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
71548attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "IsConnected");
71549retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71550requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23831LU),
71551parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23828LU),
71552referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71553browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "IsConnected"),
71554typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71555attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71556if (retVal != UA_STATUSCODE_GOOD) return retVal;
71557return retVal;
71558}
71559
71560static UA_StatusCode function_namespace0_generated_141_finish(UA_Server *server, UA_UInt16* ns) {
71561return UA_Server_addNode_finish(server,
71562nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23831LU)
71563);
71564}
71565
71566/* DataSetMetaData - ns=0;i=23830 */
71567
71568static UA_StatusCode function_namespace0_generated_142_begin(UA_Server *server, UA_UInt16* ns) {
71569UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71570UA_VariableAttributes attr = UA_VariableAttributes_default;
71571attr.minimumSamplingInterval = 0.000000;
71572attr.userAccessLevel = 1;
71573attr.accessLevel = 1;
71574/* Value rank inherited */
71575attr.valueRank = -2;
71576attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14523LU);
71577attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetMetaData");
71578retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71579requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23830LU),
71580parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23828LU),
71581referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71582browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetMetaData"),
71583typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71584attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71585if (retVal != UA_STATUSCODE_GOOD) return retVal;
71586return retVal;
71587}
71588
71589static UA_StatusCode function_namespace0_generated_142_finish(UA_Server *server, UA_UInt16* ns) {
71590return UA_Server_addNode_finish(server,
71591nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23830LU)
71592);
71593}
71594
71595/* SubscribedDataSet - ns=0;i=23829 */
71596
71597static UA_StatusCode function_namespace0_generated_143_begin(UA_Server *server, UA_UInt16* ns) {
71598UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71599UA_ObjectAttributes attr = UA_ObjectAttributes_default;
71600attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscribedDataSet");
71601retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
71602requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23829LU),
71603parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23828LU),
71604referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
71605browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscribedDataSet"),
71606typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15108LU),
71607attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
71608if (retVal != UA_STATUSCODE_GOOD) return retVal;
71609return retVal;
71610}
71611
71612static UA_StatusCode function_namespace0_generated_143_finish(UA_Server *server, UA_UInt16* ns) {
71613return UA_Server_addNode_finish(server,
71614nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23829LU)
71615);
71616}
71617
71618/* SubscribedDataSetFolderType - ns=0;i=23795 */
71619
71620static UA_StatusCode function_namespace0_generated_144_begin(UA_Server *server, UA_UInt16* ns) {
71621UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71622UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
71623attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscribedDataSetFolderType");
71624retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
71625requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23795LU),
71626parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 61LU),
71627referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
71628browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscribedDataSetFolderType"),
71629 typeDefinition: UA_NODEID_NULL,
71630attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
71631if (retVal != UA_STATUSCODE_GOOD) return retVal;
71632return retVal;
71633}
71634
71635static UA_StatusCode function_namespace0_generated_144_finish(UA_Server *server, UA_UInt16* ns) {
71636return UA_Server_addNode_finish(server,
71637nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23795LU)
71638);
71639}
71640
71641/* RemoveDataSetFolder - ns=0;i=23819 */
71642
71643static UA_StatusCode function_namespace0_generated_145_begin(UA_Server *server, UA_UInt16* ns) {
71644#ifdef UA_ENABLE_METHODCALLS
71645UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71646UA_MethodAttributes attr = UA_MethodAttributes_default;
71647attr.executable = true;
71648attr.userExecutable = true;
71649attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RemoveDataSetFolder");
71650retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
71651requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23819LU),
71652parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23795LU),
71653referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
71654browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RemoveDataSetFolder"),
71655 typeDefinition: UA_NODEID_NULL,
71656attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
71657if (retVal != UA_STATUSCODE_GOOD) return retVal;
71658return retVal;
71659#else
71660return UA_STATUSCODE_GOOD;
71661#endif /* UA_ENABLE_METHODCALLS */
71662}
71663
71664static UA_StatusCode function_namespace0_generated_145_finish(UA_Server *server, UA_UInt16* ns) {
71665#ifdef UA_ENABLE_METHODCALLS
71666return UA_Server_addMethodNode_finish(server,
71667nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23819LU)
71668, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
71669#else
71670return UA_STATUSCODE_GOOD;
71671#endif /* UA_ENABLE_METHODCALLS */
71672}
71673
71674/* InputArguments - ns=0;i=23820 */
71675
71676static UA_StatusCode function_namespace0_generated_146_begin(UA_Server *server, UA_UInt16* ns) {
71677#ifdef UA_ENABLE_METHODCALLS
71678UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71679UA_VariableAttributes attr = UA_VariableAttributes_default;
71680attr.minimumSamplingInterval = 0.000000;
71681attr.userAccessLevel = 1;
71682attr.accessLevel = 1;
71683attr.valueRank = 1;
71684attr.arrayDimensionsSize = 1;
71685UA_UInt32 arrayDimensions[1];
71686arrayDimensions[0] = 1;
71687attr.arrayDimensions = &arrayDimensions[0];
71688attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
71689UA_Argument variablenode_ns_0_i_23820_variant_DataContents[1];
71690
71691UA_init(p: &variablenode_ns_0_i_23820_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
71692variablenode_ns_0_i_23820_variant_DataContents[0].name = UA_STRING(chars: "DataSetFolderNodeId");
71693variablenode_ns_0_i_23820_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
71694variablenode_ns_0_i_23820_variant_DataContents[0].valueRank = (UA_Int32) -1;
71695UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_23820_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
71696attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
71697retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71698requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23820LU),
71699parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23819LU),
71700referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71701browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
71702typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71703attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71704if (retVal != UA_STATUSCODE_GOOD) return retVal;
71705
71706return retVal;
71707#else
71708return UA_STATUSCODE_GOOD;
71709#endif /* UA_ENABLE_METHODCALLS */
71710}
71711
71712static UA_StatusCode function_namespace0_generated_146_finish(UA_Server *server, UA_UInt16* ns) {
71713#ifdef UA_ENABLE_METHODCALLS
71714return UA_Server_addNode_finish(server,
71715nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23820LU)
71716);
71717#else
71718return UA_STATUSCODE_GOOD;
71719#endif /* UA_ENABLE_METHODCALLS */
71720}
71721
71722/* AddDataSetFolder - ns=0;i=23816 */
71723
71724static UA_StatusCode function_namespace0_generated_147_begin(UA_Server *server, UA_UInt16* ns) {
71725#ifdef UA_ENABLE_METHODCALLS
71726UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71727UA_MethodAttributes attr = UA_MethodAttributes_default;
71728attr.executable = true;
71729attr.userExecutable = true;
71730attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddDataSetFolder");
71731retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
71732requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23816LU),
71733parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23795LU),
71734referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
71735browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddDataSetFolder"),
71736 typeDefinition: UA_NODEID_NULL,
71737attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
71738if (retVal != UA_STATUSCODE_GOOD) return retVal;
71739return retVal;
71740#else
71741return UA_STATUSCODE_GOOD;
71742#endif /* UA_ENABLE_METHODCALLS */
71743}
71744
71745static UA_StatusCode function_namespace0_generated_147_finish(UA_Server *server, UA_UInt16* ns) {
71746#ifdef UA_ENABLE_METHODCALLS
71747return UA_Server_addMethodNode_finish(server,
71748nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23816LU)
71749, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
71750#else
71751return UA_STATUSCODE_GOOD;
71752#endif /* UA_ENABLE_METHODCALLS */
71753}
71754
71755/* OutputArguments - ns=0;i=23818 */
71756
71757static UA_StatusCode function_namespace0_generated_148_begin(UA_Server *server, UA_UInt16* ns) {
71758#ifdef UA_ENABLE_METHODCALLS
71759UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71760UA_VariableAttributes attr = UA_VariableAttributes_default;
71761attr.minimumSamplingInterval = 0.000000;
71762attr.userAccessLevel = 1;
71763attr.accessLevel = 1;
71764attr.valueRank = 1;
71765attr.arrayDimensionsSize = 1;
71766UA_UInt32 arrayDimensions[1];
71767arrayDimensions[0] = 1;
71768attr.arrayDimensions = &arrayDimensions[0];
71769attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
71770UA_Argument variablenode_ns_0_i_23818_variant_DataContents[1];
71771
71772UA_init(p: &variablenode_ns_0_i_23818_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
71773variablenode_ns_0_i_23818_variant_DataContents[0].name = UA_STRING(chars: "DataSetFolderNodeId");
71774variablenode_ns_0_i_23818_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
71775variablenode_ns_0_i_23818_variant_DataContents[0].valueRank = (UA_Int32) -1;
71776UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_23818_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
71777attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
71778retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71779requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23818LU),
71780parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23816LU),
71781referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71782browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
71783typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71784attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71785if (retVal != UA_STATUSCODE_GOOD) return retVal;
71786
71787return retVal;
71788#else
71789return UA_STATUSCODE_GOOD;
71790#endif /* UA_ENABLE_METHODCALLS */
71791}
71792
71793static UA_StatusCode function_namespace0_generated_148_finish(UA_Server *server, UA_UInt16* ns) {
71794#ifdef UA_ENABLE_METHODCALLS
71795return UA_Server_addNode_finish(server,
71796nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23818LU)
71797);
71798#else
71799return UA_STATUSCODE_GOOD;
71800#endif /* UA_ENABLE_METHODCALLS */
71801}
71802
71803/* InputArguments - ns=0;i=23817 */
71804
71805static UA_StatusCode function_namespace0_generated_149_begin(UA_Server *server, UA_UInt16* ns) {
71806#ifdef UA_ENABLE_METHODCALLS
71807UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71808UA_VariableAttributes attr = UA_VariableAttributes_default;
71809attr.minimumSamplingInterval = 0.000000;
71810attr.userAccessLevel = 1;
71811attr.accessLevel = 1;
71812attr.valueRank = 1;
71813attr.arrayDimensionsSize = 1;
71814UA_UInt32 arrayDimensions[1];
71815arrayDimensions[0] = 1;
71816attr.arrayDimensions = &arrayDimensions[0];
71817attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
71818UA_Argument variablenode_ns_0_i_23817_variant_DataContents[1];
71819
71820UA_init(p: &variablenode_ns_0_i_23817_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
71821variablenode_ns_0_i_23817_variant_DataContents[0].name = UA_STRING(chars: "Name");
71822variablenode_ns_0_i_23817_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
71823variablenode_ns_0_i_23817_variant_DataContents[0].valueRank = (UA_Int32) -1;
71824UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_23817_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
71825attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
71826retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71827requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23817LU),
71828parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23816LU),
71829referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71830browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
71831typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71832attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71833if (retVal != UA_STATUSCODE_GOOD) return retVal;
71834
71835return retVal;
71836#else
71837return UA_STATUSCODE_GOOD;
71838#endif /* UA_ENABLE_METHODCALLS */
71839}
71840
71841static UA_StatusCode function_namespace0_generated_149_finish(UA_Server *server, UA_UInt16* ns) {
71842#ifdef UA_ENABLE_METHODCALLS
71843return UA_Server_addNode_finish(server,
71844nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23817LU)
71845);
71846#else
71847return UA_STATUSCODE_GOOD;
71848#endif /* UA_ENABLE_METHODCALLS */
71849}
71850
71851/* RemoveSubscribedDataSet - ns=0;i=23814 */
71852
71853static UA_StatusCode function_namespace0_generated_150_begin(UA_Server *server, UA_UInt16* ns) {
71854#ifdef UA_ENABLE_METHODCALLS
71855UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71856UA_MethodAttributes attr = UA_MethodAttributes_default;
71857attr.executable = true;
71858attr.userExecutable = true;
71859attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RemoveSubscribedDataSet");
71860retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
71861requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23814LU),
71862parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23795LU),
71863referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
71864browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RemoveSubscribedDataSet"),
71865 typeDefinition: UA_NODEID_NULL,
71866attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
71867if (retVal != UA_STATUSCODE_GOOD) return retVal;
71868return retVal;
71869#else
71870return UA_STATUSCODE_GOOD;
71871#endif /* UA_ENABLE_METHODCALLS */
71872}
71873
71874static UA_StatusCode function_namespace0_generated_150_finish(UA_Server *server, UA_UInt16* ns) {
71875#ifdef UA_ENABLE_METHODCALLS
71876return UA_Server_addMethodNode_finish(server,
71877nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23814LU)
71878, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
71879#else
71880return UA_STATUSCODE_GOOD;
71881#endif /* UA_ENABLE_METHODCALLS */
71882}
71883
71884/* InputArguments - ns=0;i=23815 */
71885
71886static UA_StatusCode function_namespace0_generated_151_begin(UA_Server *server, UA_UInt16* ns) {
71887#ifdef UA_ENABLE_METHODCALLS
71888UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71889UA_VariableAttributes attr = UA_VariableAttributes_default;
71890attr.minimumSamplingInterval = 0.000000;
71891attr.userAccessLevel = 1;
71892attr.accessLevel = 1;
71893attr.valueRank = 1;
71894attr.arrayDimensionsSize = 1;
71895UA_UInt32 arrayDimensions[1];
71896arrayDimensions[0] = 1;
71897attr.arrayDimensions = &arrayDimensions[0];
71898attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
71899UA_Argument variablenode_ns_0_i_23815_variant_DataContents[1];
71900
71901UA_init(p: &variablenode_ns_0_i_23815_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
71902variablenode_ns_0_i_23815_variant_DataContents[0].name = UA_STRING(chars: "SubscribedDataSetNodeId");
71903variablenode_ns_0_i_23815_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
71904variablenode_ns_0_i_23815_variant_DataContents[0].valueRank = (UA_Int32) -1;
71905UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_23815_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
71906attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
71907retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71908requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23815LU),
71909parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23814LU),
71910referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71911browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
71912typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71913attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71914if (retVal != UA_STATUSCODE_GOOD) return retVal;
71915
71916return retVal;
71917#else
71918return UA_STATUSCODE_GOOD;
71919#endif /* UA_ENABLE_METHODCALLS */
71920}
71921
71922static UA_StatusCode function_namespace0_generated_151_finish(UA_Server *server, UA_UInt16* ns) {
71923#ifdef UA_ENABLE_METHODCALLS
71924return UA_Server_addNode_finish(server,
71925nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23815LU)
71926);
71927#else
71928return UA_STATUSCODE_GOOD;
71929#endif /* UA_ENABLE_METHODCALLS */
71930}
71931
71932/* AddSubscribedDataSet - ns=0;i=23811 */
71933
71934static UA_StatusCode function_namespace0_generated_152_begin(UA_Server *server, UA_UInt16* ns) {
71935#ifdef UA_ENABLE_METHODCALLS
71936UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71937UA_MethodAttributes attr = UA_MethodAttributes_default;
71938attr.executable = true;
71939attr.userExecutable = true;
71940attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddSubscribedDataSet");
71941retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
71942requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23811LU),
71943parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23795LU),
71944referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
71945browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddSubscribedDataSet"),
71946 typeDefinition: UA_NODEID_NULL,
71947attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
71948if (retVal != UA_STATUSCODE_GOOD) return retVal;
71949return retVal;
71950#else
71951return UA_STATUSCODE_GOOD;
71952#endif /* UA_ENABLE_METHODCALLS */
71953}
71954
71955static UA_StatusCode function_namespace0_generated_152_finish(UA_Server *server, UA_UInt16* ns) {
71956#ifdef UA_ENABLE_METHODCALLS
71957return UA_Server_addMethodNode_finish(server,
71958nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23811LU)
71959, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
71960#else
71961return UA_STATUSCODE_GOOD;
71962#endif /* UA_ENABLE_METHODCALLS */
71963}
71964
71965/* OutputArguments - ns=0;i=23813 */
71966
71967static UA_StatusCode function_namespace0_generated_153_begin(UA_Server *server, UA_UInt16* ns) {
71968#ifdef UA_ENABLE_METHODCALLS
71969UA_StatusCode retVal = UA_STATUSCODE_GOOD;
71970UA_VariableAttributes attr = UA_VariableAttributes_default;
71971attr.minimumSamplingInterval = 0.000000;
71972attr.userAccessLevel = 1;
71973attr.accessLevel = 1;
71974attr.valueRank = 1;
71975attr.arrayDimensionsSize = 1;
71976UA_UInt32 arrayDimensions[1];
71977arrayDimensions[0] = 1;
71978attr.arrayDimensions = &arrayDimensions[0];
71979attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
71980UA_Argument variablenode_ns_0_i_23813_variant_DataContents[1];
71981
71982UA_init(p: &variablenode_ns_0_i_23813_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
71983variablenode_ns_0_i_23813_variant_DataContents[0].name = UA_STRING(chars: "SubscribedDataSetNodeId");
71984variablenode_ns_0_i_23813_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
71985variablenode_ns_0_i_23813_variant_DataContents[0].valueRank = (UA_Int32) -1;
71986UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_23813_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
71987attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
71988retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
71989requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23813LU),
71990parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23811LU),
71991referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
71992browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
71993typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
71994attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
71995if (retVal != UA_STATUSCODE_GOOD) return retVal;
71996
71997return retVal;
71998#else
71999return UA_STATUSCODE_GOOD;
72000#endif /* UA_ENABLE_METHODCALLS */
72001}
72002
72003static UA_StatusCode function_namespace0_generated_153_finish(UA_Server *server, UA_UInt16* ns) {
72004#ifdef UA_ENABLE_METHODCALLS
72005return UA_Server_addNode_finish(server,
72006nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23813LU)
72007);
72008#else
72009return UA_STATUSCODE_GOOD;
72010#endif /* UA_ENABLE_METHODCALLS */
72011}
72012
72013/* InputArguments - ns=0;i=23812 */
72014
72015static UA_StatusCode function_namespace0_generated_154_begin(UA_Server *server, UA_UInt16* ns) {
72016#ifdef UA_ENABLE_METHODCALLS
72017UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72018UA_VariableAttributes attr = UA_VariableAttributes_default;
72019attr.minimumSamplingInterval = 0.000000;
72020attr.userAccessLevel = 1;
72021attr.accessLevel = 1;
72022attr.valueRank = 1;
72023attr.arrayDimensionsSize = 1;
72024UA_UInt32 arrayDimensions[1];
72025arrayDimensions[0] = 1;
72026attr.arrayDimensions = &arrayDimensions[0];
72027attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
72028UA_Argument variablenode_ns_0_i_23812_variant_DataContents[1];
72029
72030UA_init(p: &variablenode_ns_0_i_23812_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72031variablenode_ns_0_i_23812_variant_DataContents[0].name = UA_STRING(chars: "SubscribedDataSet");
72032variablenode_ns_0_i_23812_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23600LU);
72033variablenode_ns_0_i_23812_variant_DataContents[0].valueRank = (UA_Int32) -1;
72034UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_23812_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72035attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
72036retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72037requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23812LU),
72038parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23811LU),
72039referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72040browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
72041typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72042attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72043if (retVal != UA_STATUSCODE_GOOD) return retVal;
72044
72045return retVal;
72046#else
72047return UA_STATUSCODE_GOOD;
72048#endif /* UA_ENABLE_METHODCALLS */
72049}
72050
72051static UA_StatusCode function_namespace0_generated_154_finish(UA_Server *server, UA_UInt16* ns) {
72052#ifdef UA_ENABLE_METHODCALLS
72053return UA_Server_addNode_finish(server,
72054nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23812LU)
72055);
72056#else
72057return UA_STATUSCODE_GOOD;
72058#endif /* UA_ENABLE_METHODCALLS */
72059}
72060
72061/* <StandaloneSubscribedDataSetName> - ns=0;i=23807 */
72062
72063static UA_StatusCode function_namespace0_generated_155_begin(UA_Server *server, UA_UInt16* ns) {
72064UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72065UA_ObjectAttributes attr = UA_ObjectAttributes_default;
72066attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "<StandaloneSubscribedDataSetName>");
72067retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
72068requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23807LU),
72069parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23795LU),
72070referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
72071browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "<StandaloneSubscribedDataSetName>"),
72072typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23828LU),
72073attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
72074if (retVal != UA_STATUSCODE_GOOD) return retVal;
72075return retVal;
72076}
72077
72078static UA_StatusCode function_namespace0_generated_155_finish(UA_Server *server, UA_UInt16* ns) {
72079return UA_Server_addNode_finish(server,
72080nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23807LU)
72081);
72082}
72083
72084/* IsConnected - ns=0;i=23810 */
72085
72086static UA_StatusCode function_namespace0_generated_156_begin(UA_Server *server, UA_UInt16* ns) {
72087UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72088UA_VariableAttributes attr = UA_VariableAttributes_default;
72089attr.minimumSamplingInterval = 0.000000;
72090attr.userAccessLevel = 1;
72091attr.accessLevel = 1;
72092/* Value rank inherited */
72093attr.valueRank = -2;
72094attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
72095attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "IsConnected");
72096retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72097requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23810LU),
72098parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23807LU),
72099referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72100browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "IsConnected"),
72101typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72102attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72103if (retVal != UA_STATUSCODE_GOOD) return retVal;
72104return retVal;
72105}
72106
72107static UA_StatusCode function_namespace0_generated_156_finish(UA_Server *server, UA_UInt16* ns) {
72108return UA_Server_addNode_finish(server,
72109nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23810LU)
72110);
72111}
72112
72113/* DataSetMetaData - ns=0;i=23809 */
72114
72115static UA_StatusCode function_namespace0_generated_157_begin(UA_Server *server, UA_UInt16* ns) {
72116UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72117UA_VariableAttributes attr = UA_VariableAttributes_default;
72118attr.minimumSamplingInterval = 0.000000;
72119attr.userAccessLevel = 1;
72120attr.accessLevel = 1;
72121/* Value rank inherited */
72122attr.valueRank = -2;
72123attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14523LU);
72124attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetMetaData");
72125retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72126requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23809LU),
72127parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23807LU),
72128referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72129browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetMetaData"),
72130typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72131attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72132if (retVal != UA_STATUSCODE_GOOD) return retVal;
72133return retVal;
72134}
72135
72136static UA_StatusCode function_namespace0_generated_157_finish(UA_Server *server, UA_UInt16* ns) {
72137return UA_Server_addNode_finish(server,
72138nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23809LU)
72139);
72140}
72141
72142/* SubscribedDataSet - ns=0;i=23808 */
72143
72144static UA_StatusCode function_namespace0_generated_158_begin(UA_Server *server, UA_UInt16* ns) {
72145UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72146UA_ObjectAttributes attr = UA_ObjectAttributes_default;
72147attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscribedDataSet");
72148retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
72149requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23808LU),
72150parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23807LU),
72151referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
72152browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscribedDataSet"),
72153typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15108LU),
72154attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
72155if (retVal != UA_STATUSCODE_GOOD) return retVal;
72156return retVal;
72157}
72158
72159static UA_StatusCode function_namespace0_generated_158_finish(UA_Server *server, UA_UInt16* ns) {
72160return UA_Server_addNode_finish(server,
72161nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23808LU)
72162);
72163}
72164
72165/* <SubscribedDataSetFolderName> - ns=0;i=23796 */
72166
72167static UA_StatusCode function_namespace0_generated_159_begin(UA_Server *server, UA_UInt16* ns) {
72168UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72169UA_ObjectAttributes attr = UA_ObjectAttributes_default;
72170attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "<SubscribedDataSetFolderName>");
72171retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
72172requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23796LU),
72173parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23795LU),
72174referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 35LU),
72175browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "<SubscribedDataSetFolderName>"),
72176typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23795LU),
72177attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
72178if (retVal != UA_STATUSCODE_GOOD) return retVal;
72179return retVal;
72180}
72181
72182static UA_StatusCode function_namespace0_generated_159_finish(UA_Server *server, UA_UInt16* ns) {
72183return UA_Server_addNode_finish(server,
72184nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23796LU)
72185);
72186}
72187
72188/* RemoveDataSetFolder - ns=0;i=23805 */
72189
72190static UA_StatusCode function_namespace0_generated_160_begin(UA_Server *server, UA_UInt16* ns) {
72191#ifdef UA_ENABLE_METHODCALLS
72192UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72193UA_MethodAttributes attr = UA_MethodAttributes_default;
72194attr.executable = true;
72195attr.userExecutable = true;
72196attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RemoveDataSetFolder");
72197retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
72198requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23805LU),
72199parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23796LU),
72200referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
72201browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RemoveDataSetFolder"),
72202 typeDefinition: UA_NODEID_NULL,
72203attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
72204if (retVal != UA_STATUSCODE_GOOD) return retVal;
72205return retVal;
72206#else
72207return UA_STATUSCODE_GOOD;
72208#endif /* UA_ENABLE_METHODCALLS */
72209}
72210
72211static UA_StatusCode function_namespace0_generated_160_finish(UA_Server *server, UA_UInt16* ns) {
72212#ifdef UA_ENABLE_METHODCALLS
72213return UA_Server_addMethodNode_finish(server,
72214nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23805LU)
72215, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
72216#else
72217return UA_STATUSCODE_GOOD;
72218#endif /* UA_ENABLE_METHODCALLS */
72219}
72220
72221/* InputArguments - ns=0;i=23806 */
72222
72223static UA_StatusCode function_namespace0_generated_161_begin(UA_Server *server, UA_UInt16* ns) {
72224#ifdef UA_ENABLE_METHODCALLS
72225UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72226UA_VariableAttributes attr = UA_VariableAttributes_default;
72227attr.minimumSamplingInterval = 0.000000;
72228attr.userAccessLevel = 1;
72229attr.accessLevel = 1;
72230attr.valueRank = 1;
72231attr.arrayDimensionsSize = 1;
72232UA_UInt32 arrayDimensions[1];
72233arrayDimensions[0] = 1;
72234attr.arrayDimensions = &arrayDimensions[0];
72235attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
72236UA_Argument variablenode_ns_0_i_23806_variant_DataContents[1];
72237
72238UA_init(p: &variablenode_ns_0_i_23806_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72239variablenode_ns_0_i_23806_variant_DataContents[0].name = UA_STRING(chars: "DataSetFolderNodeId");
72240variablenode_ns_0_i_23806_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
72241variablenode_ns_0_i_23806_variant_DataContents[0].valueRank = (UA_Int32) -1;
72242UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_23806_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72243attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
72244retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72245requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23806LU),
72246parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23805LU),
72247referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72248browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
72249typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72250attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72251if (retVal != UA_STATUSCODE_GOOD) return retVal;
72252
72253return retVal;
72254#else
72255return UA_STATUSCODE_GOOD;
72256#endif /* UA_ENABLE_METHODCALLS */
72257}
72258
72259static UA_StatusCode function_namespace0_generated_161_finish(UA_Server *server, UA_UInt16* ns) {
72260#ifdef UA_ENABLE_METHODCALLS
72261return UA_Server_addNode_finish(server,
72262nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23806LU)
72263);
72264#else
72265return UA_STATUSCODE_GOOD;
72266#endif /* UA_ENABLE_METHODCALLS */
72267}
72268
72269/* AddDataSetFolder - ns=0;i=23802 */
72270
72271static UA_StatusCode function_namespace0_generated_162_begin(UA_Server *server, UA_UInt16* ns) {
72272#ifdef UA_ENABLE_METHODCALLS
72273UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72274UA_MethodAttributes attr = UA_MethodAttributes_default;
72275attr.executable = true;
72276attr.userExecutable = true;
72277attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddDataSetFolder");
72278retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
72279requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23802LU),
72280parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23796LU),
72281referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
72282browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddDataSetFolder"),
72283 typeDefinition: UA_NODEID_NULL,
72284attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
72285if (retVal != UA_STATUSCODE_GOOD) return retVal;
72286return retVal;
72287#else
72288return UA_STATUSCODE_GOOD;
72289#endif /* UA_ENABLE_METHODCALLS */
72290}
72291
72292static UA_StatusCode function_namespace0_generated_162_finish(UA_Server *server, UA_UInt16* ns) {
72293#ifdef UA_ENABLE_METHODCALLS
72294return UA_Server_addMethodNode_finish(server,
72295nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23802LU)
72296, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
72297#else
72298return UA_STATUSCODE_GOOD;
72299#endif /* UA_ENABLE_METHODCALLS */
72300}
72301
72302/* OutputArguments - ns=0;i=23804 */
72303
72304static UA_StatusCode function_namespace0_generated_163_begin(UA_Server *server, UA_UInt16* ns) {
72305#ifdef UA_ENABLE_METHODCALLS
72306UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72307UA_VariableAttributes attr = UA_VariableAttributes_default;
72308attr.minimumSamplingInterval = 0.000000;
72309attr.userAccessLevel = 1;
72310attr.accessLevel = 1;
72311attr.valueRank = 1;
72312attr.arrayDimensionsSize = 1;
72313UA_UInt32 arrayDimensions[1];
72314arrayDimensions[0] = 1;
72315attr.arrayDimensions = &arrayDimensions[0];
72316attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
72317UA_Argument variablenode_ns_0_i_23804_variant_DataContents[1];
72318
72319UA_init(p: &variablenode_ns_0_i_23804_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72320variablenode_ns_0_i_23804_variant_DataContents[0].name = UA_STRING(chars: "DataSetFolderNodeId");
72321variablenode_ns_0_i_23804_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
72322variablenode_ns_0_i_23804_variant_DataContents[0].valueRank = (UA_Int32) -1;
72323UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_23804_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72324attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
72325retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72326requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23804LU),
72327parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23802LU),
72328referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72329browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
72330typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72331attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72332if (retVal != UA_STATUSCODE_GOOD) return retVal;
72333
72334return retVal;
72335#else
72336return UA_STATUSCODE_GOOD;
72337#endif /* UA_ENABLE_METHODCALLS */
72338}
72339
72340static UA_StatusCode function_namespace0_generated_163_finish(UA_Server *server, UA_UInt16* ns) {
72341#ifdef UA_ENABLE_METHODCALLS
72342return UA_Server_addNode_finish(server,
72343nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23804LU)
72344);
72345#else
72346return UA_STATUSCODE_GOOD;
72347#endif /* UA_ENABLE_METHODCALLS */
72348}
72349
72350/* InputArguments - ns=0;i=23803 */
72351
72352static UA_StatusCode function_namespace0_generated_164_begin(UA_Server *server, UA_UInt16* ns) {
72353#ifdef UA_ENABLE_METHODCALLS
72354UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72355UA_VariableAttributes attr = UA_VariableAttributes_default;
72356attr.minimumSamplingInterval = 0.000000;
72357attr.userAccessLevel = 1;
72358attr.accessLevel = 1;
72359attr.valueRank = 1;
72360attr.arrayDimensionsSize = 1;
72361UA_UInt32 arrayDimensions[1];
72362arrayDimensions[0] = 1;
72363attr.arrayDimensions = &arrayDimensions[0];
72364attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
72365UA_Argument variablenode_ns_0_i_23803_variant_DataContents[1];
72366
72367UA_init(p: &variablenode_ns_0_i_23803_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72368variablenode_ns_0_i_23803_variant_DataContents[0].name = UA_STRING(chars: "Name");
72369variablenode_ns_0_i_23803_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
72370variablenode_ns_0_i_23803_variant_DataContents[0].valueRank = (UA_Int32) -1;
72371UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_23803_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72372attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
72373retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72374requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23803LU),
72375parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23802LU),
72376referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72377browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
72378typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72379attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72380if (retVal != UA_STATUSCODE_GOOD) return retVal;
72381
72382return retVal;
72383#else
72384return UA_STATUSCODE_GOOD;
72385#endif /* UA_ENABLE_METHODCALLS */
72386}
72387
72388static UA_StatusCode function_namespace0_generated_164_finish(UA_Server *server, UA_UInt16* ns) {
72389#ifdef UA_ENABLE_METHODCALLS
72390return UA_Server_addNode_finish(server,
72391nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23803LU)
72392);
72393#else
72394return UA_STATUSCODE_GOOD;
72395#endif /* UA_ENABLE_METHODCALLS */
72396}
72397
72398/* RemoveSubscribedDataSet - ns=0;i=23800 */
72399
72400static UA_StatusCode function_namespace0_generated_165_begin(UA_Server *server, UA_UInt16* ns) {
72401#ifdef UA_ENABLE_METHODCALLS
72402UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72403UA_MethodAttributes attr = UA_MethodAttributes_default;
72404attr.executable = true;
72405attr.userExecutable = true;
72406attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RemoveSubscribedDataSet");
72407retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
72408requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23800LU),
72409parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23796LU),
72410referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
72411browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RemoveSubscribedDataSet"),
72412 typeDefinition: UA_NODEID_NULL,
72413attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
72414if (retVal != UA_STATUSCODE_GOOD) return retVal;
72415return retVal;
72416#else
72417return UA_STATUSCODE_GOOD;
72418#endif /* UA_ENABLE_METHODCALLS */
72419}
72420
72421static UA_StatusCode function_namespace0_generated_165_finish(UA_Server *server, UA_UInt16* ns) {
72422#ifdef UA_ENABLE_METHODCALLS
72423return UA_Server_addMethodNode_finish(server,
72424nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23800LU)
72425, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
72426#else
72427return UA_STATUSCODE_GOOD;
72428#endif /* UA_ENABLE_METHODCALLS */
72429}
72430
72431/* InputArguments - ns=0;i=23801 */
72432
72433static UA_StatusCode function_namespace0_generated_166_begin(UA_Server *server, UA_UInt16* ns) {
72434#ifdef UA_ENABLE_METHODCALLS
72435UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72436UA_VariableAttributes attr = UA_VariableAttributes_default;
72437attr.minimumSamplingInterval = 0.000000;
72438attr.userAccessLevel = 1;
72439attr.accessLevel = 1;
72440attr.valueRank = 1;
72441attr.arrayDimensionsSize = 1;
72442UA_UInt32 arrayDimensions[1];
72443arrayDimensions[0] = 1;
72444attr.arrayDimensions = &arrayDimensions[0];
72445attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
72446UA_Argument variablenode_ns_0_i_23801_variant_DataContents[1];
72447
72448UA_init(p: &variablenode_ns_0_i_23801_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72449variablenode_ns_0_i_23801_variant_DataContents[0].name = UA_STRING(chars: "SubscribedDataSetNodeId");
72450variablenode_ns_0_i_23801_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
72451variablenode_ns_0_i_23801_variant_DataContents[0].valueRank = (UA_Int32) -1;
72452UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_23801_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72453attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
72454retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72455requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23801LU),
72456parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23800LU),
72457referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72458browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
72459typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72460attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72461if (retVal != UA_STATUSCODE_GOOD) return retVal;
72462
72463return retVal;
72464#else
72465return UA_STATUSCODE_GOOD;
72466#endif /* UA_ENABLE_METHODCALLS */
72467}
72468
72469static UA_StatusCode function_namespace0_generated_166_finish(UA_Server *server, UA_UInt16* ns) {
72470#ifdef UA_ENABLE_METHODCALLS
72471return UA_Server_addNode_finish(server,
72472nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23801LU)
72473);
72474#else
72475return UA_STATUSCODE_GOOD;
72476#endif /* UA_ENABLE_METHODCALLS */
72477}
72478
72479/* AddSubscribedDataSet - ns=0;i=23797 */
72480
72481static UA_StatusCode function_namespace0_generated_167_begin(UA_Server *server, UA_UInt16* ns) {
72482#ifdef UA_ENABLE_METHODCALLS
72483UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72484UA_MethodAttributes attr = UA_MethodAttributes_default;
72485attr.executable = true;
72486attr.userExecutable = true;
72487attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddSubscribedDataSet");
72488retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
72489requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23797LU),
72490parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23796LU),
72491referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
72492browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddSubscribedDataSet"),
72493 typeDefinition: UA_NODEID_NULL,
72494attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
72495if (retVal != UA_STATUSCODE_GOOD) return retVal;
72496return retVal;
72497#else
72498return UA_STATUSCODE_GOOD;
72499#endif /* UA_ENABLE_METHODCALLS */
72500}
72501
72502static UA_StatusCode function_namespace0_generated_167_finish(UA_Server *server, UA_UInt16* ns) {
72503#ifdef UA_ENABLE_METHODCALLS
72504return UA_Server_addMethodNode_finish(server,
72505nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23797LU)
72506, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
72507#else
72508return UA_STATUSCODE_GOOD;
72509#endif /* UA_ENABLE_METHODCALLS */
72510}
72511
72512/* OutputArguments - ns=0;i=23799 */
72513
72514static UA_StatusCode function_namespace0_generated_168_begin(UA_Server *server, UA_UInt16* ns) {
72515#ifdef UA_ENABLE_METHODCALLS
72516UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72517UA_VariableAttributes attr = UA_VariableAttributes_default;
72518attr.minimumSamplingInterval = 0.000000;
72519attr.userAccessLevel = 1;
72520attr.accessLevel = 1;
72521attr.valueRank = 1;
72522attr.arrayDimensionsSize = 1;
72523UA_UInt32 arrayDimensions[1];
72524arrayDimensions[0] = 1;
72525attr.arrayDimensions = &arrayDimensions[0];
72526attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
72527UA_Argument variablenode_ns_0_i_23799_variant_DataContents[1];
72528
72529UA_init(p: &variablenode_ns_0_i_23799_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72530variablenode_ns_0_i_23799_variant_DataContents[0].name = UA_STRING(chars: "SubscribedDataSetNodeId");
72531variablenode_ns_0_i_23799_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
72532variablenode_ns_0_i_23799_variant_DataContents[0].valueRank = (UA_Int32) -1;
72533UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_23799_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72534attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
72535retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72536requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23799LU),
72537parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23797LU),
72538referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72539browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
72540typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72541attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72542if (retVal != UA_STATUSCODE_GOOD) return retVal;
72543
72544return retVal;
72545#else
72546return UA_STATUSCODE_GOOD;
72547#endif /* UA_ENABLE_METHODCALLS */
72548}
72549
72550static UA_StatusCode function_namespace0_generated_168_finish(UA_Server *server, UA_UInt16* ns) {
72551#ifdef UA_ENABLE_METHODCALLS
72552return UA_Server_addNode_finish(server,
72553nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23799LU)
72554);
72555#else
72556return UA_STATUSCODE_GOOD;
72557#endif /* UA_ENABLE_METHODCALLS */
72558}
72559
72560/* InputArguments - ns=0;i=23798 */
72561
72562static UA_StatusCode function_namespace0_generated_169_begin(UA_Server *server, UA_UInt16* ns) {
72563#ifdef UA_ENABLE_METHODCALLS
72564UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72565UA_VariableAttributes attr = UA_VariableAttributes_default;
72566attr.minimumSamplingInterval = 0.000000;
72567attr.userAccessLevel = 1;
72568attr.accessLevel = 1;
72569attr.valueRank = 1;
72570attr.arrayDimensionsSize = 1;
72571UA_UInt32 arrayDimensions[1];
72572arrayDimensions[0] = 1;
72573attr.arrayDimensions = &arrayDimensions[0];
72574attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
72575UA_Argument variablenode_ns_0_i_23798_variant_DataContents[1];
72576
72577UA_init(p: &variablenode_ns_0_i_23798_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72578variablenode_ns_0_i_23798_variant_DataContents[0].name = UA_STRING(chars: "SubscribedDataSet");
72579variablenode_ns_0_i_23798_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23600LU);
72580variablenode_ns_0_i_23798_variant_DataContents[0].valueRank = (UA_Int32) -1;
72581UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_23798_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72582attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
72583retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72584requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23798LU),
72585parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23797LU),
72586referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72587browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
72588typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72589attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72590if (retVal != UA_STATUSCODE_GOOD) return retVal;
72591
72592return retVal;
72593#else
72594return UA_STATUSCODE_GOOD;
72595#endif /* UA_ENABLE_METHODCALLS */
72596}
72597
72598static UA_StatusCode function_namespace0_generated_169_finish(UA_Server *server, UA_UInt16* ns) {
72599#ifdef UA_ENABLE_METHODCALLS
72600return UA_Server_addNode_finish(server,
72601nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23798LU)
72602);
72603#else
72604return UA_STATUSCODE_GOOD;
72605#endif /* UA_ENABLE_METHODCALLS */
72606}
72607
72608/* DataSetWriterType - ns=0;i=15298 */
72609
72610static UA_StatusCode function_namespace0_generated_170_begin(UA_Server *server, UA_UInt16* ns) {
72611UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72612UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
72613attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetWriterType");
72614retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
72615requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15298LU),
72616parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
72617referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
72618browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetWriterType"),
72619 typeDefinition: UA_NODEID_NULL,
72620attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
72621if (retVal != UA_STATUSCODE_GOOD) return retVal;
72622return retVal;
72623}
72624
72625static UA_StatusCode function_namespace0_generated_170_finish(UA_Server *server, UA_UInt16* ns) {
72626return UA_Server_addNode_finish(server,
72627nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15298LU)
72628);
72629}
72630
72631/* KeyFrameCount - ns=0;i=21094 */
72632
72633static UA_StatusCode function_namespace0_generated_171_begin(UA_Server *server, UA_UInt16* ns) {
72634UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72635UA_VariableAttributes attr = UA_VariableAttributes_default;
72636attr.minimumSamplingInterval = 0.000000;
72637attr.userAccessLevel = 1;
72638attr.accessLevel = 1;
72639/* Value rank inherited */
72640attr.valueRank = -2;
72641attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
72642attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "KeyFrameCount");
72643retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72644requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21094LU),
72645parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15298LU),
72646referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72647browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "KeyFrameCount"),
72648typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72649attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72650if (retVal != UA_STATUSCODE_GOOD) return retVal;
72651return retVal;
72652}
72653
72654static UA_StatusCode function_namespace0_generated_171_finish(UA_Server *server, UA_UInt16* ns) {
72655return UA_Server_addNode_finish(server,
72656nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21094LU)
72657);
72658}
72659
72660/* DataSetFieldContentMask - ns=0;i=21093 */
72661
72662static UA_StatusCode function_namespace0_generated_172_begin(UA_Server *server, UA_UInt16* ns) {
72663UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72664UA_VariableAttributes attr = UA_VariableAttributes_default;
72665attr.minimumSamplingInterval = 0.000000;
72666attr.userAccessLevel = 1;
72667attr.accessLevel = 1;
72668/* Value rank inherited */
72669attr.valueRank = -2;
72670attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15583LU);
72671attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetFieldContentMask");
72672retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72673requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21093LU),
72674parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15298LU),
72675referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72676browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetFieldContentMask"),
72677typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72678attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72679if (retVal != UA_STATUSCODE_GOOD) return retVal;
72680return retVal;
72681}
72682
72683static UA_StatusCode function_namespace0_generated_172_finish(UA_Server *server, UA_UInt16* ns) {
72684return UA_Server_addNode_finish(server,
72685nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21093LU)
72686);
72687}
72688
72689/* DataSetWriterId - ns=0;i=21092 */
72690
72691static UA_StatusCode function_namespace0_generated_173_begin(UA_Server *server, UA_UInt16* ns) {
72692UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72693UA_VariableAttributes attr = UA_VariableAttributes_default;
72694attr.minimumSamplingInterval = 0.000000;
72695attr.userAccessLevel = 1;
72696attr.accessLevel = 1;
72697/* Value rank inherited */
72698attr.valueRank = -2;
72699attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
72700attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetWriterId");
72701retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72702requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21092LU),
72703parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15298LU),
72704referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72705browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetWriterId"),
72706typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72707attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72708if (retVal != UA_STATUSCODE_GOOD) return retVal;
72709return retVal;
72710}
72711
72712static UA_StatusCode function_namespace0_generated_173_finish(UA_Server *server, UA_UInt16* ns) {
72713return UA_Server_addNode_finish(server,
72714nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21092LU)
72715);
72716}
72717
72718/* DataSetWriterProperties - ns=0;i=17493 */
72719
72720static UA_StatusCode function_namespace0_generated_174_begin(UA_Server *server, UA_UInt16* ns) {
72721UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72722UA_VariableAttributes attr = UA_VariableAttributes_default;
72723attr.minimumSamplingInterval = 0.000000;
72724attr.userAccessLevel = 1;
72725attr.accessLevel = 1;
72726attr.valueRank = 1;
72727attr.arrayDimensionsSize = 1;
72728UA_UInt32 arrayDimensions[1];
72729arrayDimensions[0] = 0;
72730attr.arrayDimensions = &arrayDimensions[0];
72731attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14533LU);
72732attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetWriterProperties");
72733retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72734requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17493LU),
72735parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15298LU),
72736referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72737browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetWriterProperties"),
72738typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72739attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72740if (retVal != UA_STATUSCODE_GOOD) return retVal;
72741return retVal;
72742}
72743
72744static UA_StatusCode function_namespace0_generated_174_finish(UA_Server *server, UA_UInt16* ns) {
72745return UA_Server_addNode_finish(server,
72746nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17493LU)
72747);
72748}
72749
72750/* TransportSettings - ns=0;i=15303 */
72751
72752static UA_StatusCode function_namespace0_generated_175_begin(UA_Server *server, UA_UInt16* ns) {
72753UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72754UA_ObjectAttributes attr = UA_ObjectAttributes_default;
72755attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransportSettings");
72756retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
72757requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15303LU),
72758parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15298LU),
72759referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
72760browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransportSettings"),
72761typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
72762attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
72763if (retVal != UA_STATUSCODE_GOOD) return retVal;
72764return retVal;
72765}
72766
72767static UA_StatusCode function_namespace0_generated_175_finish(UA_Server *server, UA_UInt16* ns) {
72768return UA_Server_addNode_finish(server,
72769nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15303LU)
72770);
72771}
72772
72773/* PubSubGroupType - ns=0;i=14232 */
72774
72775static UA_StatusCode function_namespace0_generated_176_begin(UA_Server *server, UA_UInt16* ns) {
72776UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72777UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
72778attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PubSubGroupType");
72779retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
72780requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14232LU),
72781parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
72782referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
72783browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PubSubGroupType"),
72784 typeDefinition: UA_NODEID_NULL,
72785attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
72786if (retVal != UA_STATUSCODE_GOOD) return retVal;
72787return retVal;
72788}
72789
72790static UA_StatusCode function_namespace0_generated_176_finish(UA_Server *server, UA_UInt16* ns) {
72791return UA_Server_addNode_finish(server,
72792nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14232LU)
72793);
72794}
72795
72796/* ReaderGroupType - ns=0;i=17999 */
72797
72798static UA_StatusCode function_namespace0_generated_177_begin(UA_Server *server, UA_UInt16* ns) {
72799UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72800UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
72801attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ReaderGroupType");
72802retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
72803requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17999LU),
72804parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14232LU),
72805referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
72806browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ReaderGroupType"),
72807 typeDefinition: UA_NODEID_NULL,
72808attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
72809if (retVal != UA_STATUSCODE_GOOD) return retVal;
72810return retVal;
72811}
72812
72813static UA_StatusCode function_namespace0_generated_177_finish(UA_Server *server, UA_UInt16* ns) {
72814return UA_Server_addNode_finish(server,
72815nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17999LU)
72816);
72817}
72818
72819/* RemoveDataSetReader - ns=0;i=21085 */
72820
72821static UA_StatusCode function_namespace0_generated_178_begin(UA_Server *server, UA_UInt16* ns) {
72822#ifdef UA_ENABLE_METHODCALLS
72823UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72824UA_MethodAttributes attr = UA_MethodAttributes_default;
72825attr.executable = true;
72826attr.userExecutable = true;
72827attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RemoveDataSetReader");
72828retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
72829requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21085LU),
72830parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17999LU),
72831referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
72832browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RemoveDataSetReader"),
72833 typeDefinition: UA_NODEID_NULL,
72834attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
72835if (retVal != UA_STATUSCODE_GOOD) return retVal;
72836return retVal;
72837#else
72838return UA_STATUSCODE_GOOD;
72839#endif /* UA_ENABLE_METHODCALLS */
72840}
72841
72842static UA_StatusCode function_namespace0_generated_178_finish(UA_Server *server, UA_UInt16* ns) {
72843#ifdef UA_ENABLE_METHODCALLS
72844return UA_Server_addMethodNode_finish(server,
72845nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21085LU)
72846, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
72847#else
72848return UA_STATUSCODE_GOOD;
72849#endif /* UA_ENABLE_METHODCALLS */
72850}
72851
72852/* InputArguments - ns=0;i=21086 */
72853
72854static UA_StatusCode function_namespace0_generated_179_begin(UA_Server *server, UA_UInt16* ns) {
72855#ifdef UA_ENABLE_METHODCALLS
72856UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72857UA_VariableAttributes attr = UA_VariableAttributes_default;
72858attr.minimumSamplingInterval = 0.000000;
72859attr.userAccessLevel = 1;
72860attr.accessLevel = 1;
72861attr.valueRank = 1;
72862attr.arrayDimensionsSize = 1;
72863UA_UInt32 arrayDimensions[1];
72864arrayDimensions[0] = 0;
72865attr.arrayDimensions = &arrayDimensions[0];
72866attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
72867UA_Argument variablenode_ns_0_i_21086_variant_DataContents[1];
72868
72869UA_init(p: &variablenode_ns_0_i_21086_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72870variablenode_ns_0_i_21086_variant_DataContents[0].name = UA_STRING(chars: "DataSetReaderNodeId");
72871variablenode_ns_0_i_21086_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15623LU);
72872variablenode_ns_0_i_21086_variant_DataContents[0].valueRank = (UA_Int32) -1;
72873UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_21086_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72874attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
72875retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72876requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21086LU),
72877parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21085LU),
72878referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72879browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
72880typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72881attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72882if (retVal != UA_STATUSCODE_GOOD) return retVal;
72883
72884return retVal;
72885#else
72886return UA_STATUSCODE_GOOD;
72887#endif /* UA_ENABLE_METHODCALLS */
72888}
72889
72890static UA_StatusCode function_namespace0_generated_179_finish(UA_Server *server, UA_UInt16* ns) {
72891#ifdef UA_ENABLE_METHODCALLS
72892return UA_Server_addNode_finish(server,
72893nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21086LU)
72894);
72895#else
72896return UA_STATUSCODE_GOOD;
72897#endif /* UA_ENABLE_METHODCALLS */
72898}
72899
72900/* AddDataSetReader - ns=0;i=21082 */
72901
72902static UA_StatusCode function_namespace0_generated_180_begin(UA_Server *server, UA_UInt16* ns) {
72903#ifdef UA_ENABLE_METHODCALLS
72904UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72905UA_MethodAttributes attr = UA_MethodAttributes_default;
72906attr.executable = true;
72907attr.userExecutable = true;
72908attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddDataSetReader");
72909retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
72910requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21082LU),
72911parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17999LU),
72912referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
72913browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddDataSetReader"),
72914 typeDefinition: UA_NODEID_NULL,
72915attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
72916if (retVal != UA_STATUSCODE_GOOD) return retVal;
72917return retVal;
72918#else
72919return UA_STATUSCODE_GOOD;
72920#endif /* UA_ENABLE_METHODCALLS */
72921}
72922
72923static UA_StatusCode function_namespace0_generated_180_finish(UA_Server *server, UA_UInt16* ns) {
72924#ifdef UA_ENABLE_METHODCALLS
72925return UA_Server_addMethodNode_finish(server,
72926nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21082LU)
72927, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
72928#else
72929return UA_STATUSCODE_GOOD;
72930#endif /* UA_ENABLE_METHODCALLS */
72931}
72932
72933/* OutputArguments - ns=0;i=21084 */
72934
72935static UA_StatusCode function_namespace0_generated_181_begin(UA_Server *server, UA_UInt16* ns) {
72936#ifdef UA_ENABLE_METHODCALLS
72937UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72938UA_VariableAttributes attr = UA_VariableAttributes_default;
72939attr.minimumSamplingInterval = 0.000000;
72940attr.userAccessLevel = 1;
72941attr.accessLevel = 1;
72942attr.valueRank = 1;
72943attr.arrayDimensionsSize = 1;
72944UA_UInt32 arrayDimensions[1];
72945arrayDimensions[0] = 0;
72946attr.arrayDimensions = &arrayDimensions[0];
72947attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
72948UA_Argument variablenode_ns_0_i_21084_variant_DataContents[1];
72949
72950UA_init(p: &variablenode_ns_0_i_21084_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72951variablenode_ns_0_i_21084_variant_DataContents[0].name = UA_STRING(chars: "DataSetReaderNodeId");
72952variablenode_ns_0_i_21084_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
72953variablenode_ns_0_i_21084_variant_DataContents[0].valueRank = (UA_Int32) -1;
72954UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_21084_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72955attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
72956retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
72957requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21084LU),
72958parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21082LU),
72959referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
72960browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
72961typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
72962attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
72963if (retVal != UA_STATUSCODE_GOOD) return retVal;
72964
72965return retVal;
72966#else
72967return UA_STATUSCODE_GOOD;
72968#endif /* UA_ENABLE_METHODCALLS */
72969}
72970
72971static UA_StatusCode function_namespace0_generated_181_finish(UA_Server *server, UA_UInt16* ns) {
72972#ifdef UA_ENABLE_METHODCALLS
72973return UA_Server_addNode_finish(server,
72974nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21084LU)
72975);
72976#else
72977return UA_STATUSCODE_GOOD;
72978#endif /* UA_ENABLE_METHODCALLS */
72979}
72980
72981/* InputArguments - ns=0;i=21083 */
72982
72983static UA_StatusCode function_namespace0_generated_182_begin(UA_Server *server, UA_UInt16* ns) {
72984#ifdef UA_ENABLE_METHODCALLS
72985UA_StatusCode retVal = UA_STATUSCODE_GOOD;
72986UA_VariableAttributes attr = UA_VariableAttributes_default;
72987attr.minimumSamplingInterval = 0.000000;
72988attr.userAccessLevel = 1;
72989attr.accessLevel = 1;
72990attr.valueRank = 1;
72991attr.arrayDimensionsSize = 1;
72992UA_UInt32 arrayDimensions[1];
72993arrayDimensions[0] = 0;
72994attr.arrayDimensions = &arrayDimensions[0];
72995attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
72996UA_Argument variablenode_ns_0_i_21083_variant_DataContents[1];
72997
72998UA_init(p: &variablenode_ns_0_i_21083_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
72999variablenode_ns_0_i_21083_variant_DataContents[0].name = UA_STRING(chars: "Configuration");
73000variablenode_ns_0_i_21083_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15623LU);
73001variablenode_ns_0_i_21083_variant_DataContents[0].valueRank = (UA_Int32) -1;
73002UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_21083_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
73003attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
73004retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73005requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21083LU),
73006parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21082LU),
73007referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73008browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
73009typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73010attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73011if (retVal != UA_STATUSCODE_GOOD) return retVal;
73012
73013return retVal;
73014#else
73015return UA_STATUSCODE_GOOD;
73016#endif /* UA_ENABLE_METHODCALLS */
73017}
73018
73019static UA_StatusCode function_namespace0_generated_182_finish(UA_Server *server, UA_UInt16* ns) {
73020#ifdef UA_ENABLE_METHODCALLS
73021return UA_Server_addNode_finish(server,
73022nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21083LU)
73023);
73024#else
73025return UA_STATUSCODE_GOOD;
73026#endif /* UA_ENABLE_METHODCALLS */
73027}
73028
73029/* <DataSetReaderName> - ns=0;i=18076 */
73030
73031static UA_StatusCode function_namespace0_generated_183_begin(UA_Server *server, UA_UInt16* ns) {
73032UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73033UA_ObjectAttributes attr = UA_ObjectAttributes_default;
73034attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "<DataSetReaderName>");
73035retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
73036requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 18076LU),
73037parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17999LU),
73038referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15297LU),
73039browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "<DataSetReaderName>"),
73040typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15306LU),
73041attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
73042if (retVal != UA_STATUSCODE_GOOD) return retVal;
73043return retVal;
73044}
73045
73046static UA_StatusCode function_namespace0_generated_183_finish(UA_Server *server, UA_UInt16* ns) {
73047return UA_Server_addNode_finish(server,
73048nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 18076LU)
73049);
73050}
73051
73052/* WriterGroupType - ns=0;i=17725 */
73053
73054static UA_StatusCode function_namespace0_generated_184_begin(UA_Server *server, UA_UInt16* ns) {
73055UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73056UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
73057attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "WriterGroupType");
73058retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
73059requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17725LU),
73060parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14232LU),
73061referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
73062browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "WriterGroupType"),
73063 typeDefinition: UA_NODEID_NULL,
73064attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
73065if (retVal != UA_STATUSCODE_GOOD) return retVal;
73066return retVal;
73067}
73068
73069static UA_StatusCode function_namespace0_generated_184_finish(UA_Server *server, UA_UInt16* ns) {
73070return UA_Server_addNode_finish(server,
73071nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17725LU)
73072);
73073}
73074
73075/* RemoveDataSetWriter - ns=0;i=17992 */
73076
73077static UA_StatusCode function_namespace0_generated_185_begin(UA_Server *server, UA_UInt16* ns) {
73078#ifdef UA_ENABLE_METHODCALLS
73079UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73080UA_MethodAttributes attr = UA_MethodAttributes_default;
73081attr.executable = true;
73082attr.userExecutable = true;
73083attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RemoveDataSetWriter");
73084retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
73085requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17992LU),
73086parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17725LU),
73087referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
73088browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RemoveDataSetWriter"),
73089 typeDefinition: UA_NODEID_NULL,
73090attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
73091if (retVal != UA_STATUSCODE_GOOD) return retVal;
73092return retVal;
73093#else
73094return UA_STATUSCODE_GOOD;
73095#endif /* UA_ENABLE_METHODCALLS */
73096}
73097
73098static UA_StatusCode function_namespace0_generated_185_finish(UA_Server *server, UA_UInt16* ns) {
73099#ifdef UA_ENABLE_METHODCALLS
73100return UA_Server_addMethodNode_finish(server,
73101nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17992LU)
73102, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
73103#else
73104return UA_STATUSCODE_GOOD;
73105#endif /* UA_ENABLE_METHODCALLS */
73106}
73107
73108/* InputArguments - ns=0;i=17993 */
73109
73110static UA_StatusCode function_namespace0_generated_186_begin(UA_Server *server, UA_UInt16* ns) {
73111#ifdef UA_ENABLE_METHODCALLS
73112UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73113UA_VariableAttributes attr = UA_VariableAttributes_default;
73114attr.minimumSamplingInterval = 0.000000;
73115attr.userAccessLevel = 1;
73116attr.accessLevel = 1;
73117attr.valueRank = 1;
73118attr.arrayDimensionsSize = 1;
73119UA_UInt32 arrayDimensions[1];
73120arrayDimensions[0] = 0;
73121attr.arrayDimensions = &arrayDimensions[0];
73122attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
73123UA_Argument variablenode_ns_0_i_17993_variant_DataContents[1];
73124
73125UA_init(p: &variablenode_ns_0_i_17993_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
73126variablenode_ns_0_i_17993_variant_DataContents[0].name = UA_STRING(chars: "DataSetWriterNodeId");
73127variablenode_ns_0_i_17993_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
73128variablenode_ns_0_i_17993_variant_DataContents[0].valueRank = (UA_Int32) -1;
73129UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_17993_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
73130attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
73131retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73132requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17993LU),
73133parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17992LU),
73134referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73135browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
73136typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73137attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73138if (retVal != UA_STATUSCODE_GOOD) return retVal;
73139
73140return retVal;
73141#else
73142return UA_STATUSCODE_GOOD;
73143#endif /* UA_ENABLE_METHODCALLS */
73144}
73145
73146static UA_StatusCode function_namespace0_generated_186_finish(UA_Server *server, UA_UInt16* ns) {
73147#ifdef UA_ENABLE_METHODCALLS
73148return UA_Server_addNode_finish(server,
73149nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17993LU)
73150);
73151#else
73152return UA_STATUSCODE_GOOD;
73153#endif /* UA_ENABLE_METHODCALLS */
73154}
73155
73156/* AddDataSetWriter - ns=0;i=17969 */
73157
73158static UA_StatusCode function_namespace0_generated_187_begin(UA_Server *server, UA_UInt16* ns) {
73159#ifdef UA_ENABLE_METHODCALLS
73160UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73161UA_MethodAttributes attr = UA_MethodAttributes_default;
73162attr.executable = true;
73163attr.userExecutable = true;
73164attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddDataSetWriter");
73165retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
73166requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17969LU),
73167parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17725LU),
73168referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
73169browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddDataSetWriter"),
73170 typeDefinition: UA_NODEID_NULL,
73171attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
73172if (retVal != UA_STATUSCODE_GOOD) return retVal;
73173return retVal;
73174#else
73175return UA_STATUSCODE_GOOD;
73176#endif /* UA_ENABLE_METHODCALLS */
73177}
73178
73179static UA_StatusCode function_namespace0_generated_187_finish(UA_Server *server, UA_UInt16* ns) {
73180#ifdef UA_ENABLE_METHODCALLS
73181return UA_Server_addMethodNode_finish(server,
73182nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17969LU)
73183, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
73184#else
73185return UA_STATUSCODE_GOOD;
73186#endif /* UA_ENABLE_METHODCALLS */
73187}
73188
73189/* OutputArguments - ns=0;i=17987 */
73190
73191static UA_StatusCode function_namespace0_generated_188_begin(UA_Server *server, UA_UInt16* ns) {
73192#ifdef UA_ENABLE_METHODCALLS
73193UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73194UA_VariableAttributes attr = UA_VariableAttributes_default;
73195attr.minimumSamplingInterval = 0.000000;
73196attr.userAccessLevel = 1;
73197attr.accessLevel = 1;
73198attr.valueRank = 1;
73199attr.arrayDimensionsSize = 1;
73200UA_UInt32 arrayDimensions[1];
73201arrayDimensions[0] = 0;
73202attr.arrayDimensions = &arrayDimensions[0];
73203attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
73204UA_Argument variablenode_ns_0_i_17987_variant_DataContents[1];
73205
73206UA_init(p: &variablenode_ns_0_i_17987_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
73207variablenode_ns_0_i_17987_variant_DataContents[0].name = UA_STRING(chars: "DataSetWriterNodeId");
73208variablenode_ns_0_i_17987_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
73209variablenode_ns_0_i_17987_variant_DataContents[0].valueRank = (UA_Int32) -1;
73210UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_17987_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
73211attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
73212retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73213requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17987LU),
73214parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17969LU),
73215referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73216browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
73217typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73218attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73219if (retVal != UA_STATUSCODE_GOOD) return retVal;
73220
73221return retVal;
73222#else
73223return UA_STATUSCODE_GOOD;
73224#endif /* UA_ENABLE_METHODCALLS */
73225}
73226
73227static UA_StatusCode function_namespace0_generated_188_finish(UA_Server *server, UA_UInt16* ns) {
73228#ifdef UA_ENABLE_METHODCALLS
73229return UA_Server_addNode_finish(server,
73230nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17987LU)
73231);
73232#else
73233return UA_STATUSCODE_GOOD;
73234#endif /* UA_ENABLE_METHODCALLS */
73235}
73236
73237/* InputArguments - ns=0;i=17976 */
73238
73239static UA_StatusCode function_namespace0_generated_189_begin(UA_Server *server, UA_UInt16* ns) {
73240#ifdef UA_ENABLE_METHODCALLS
73241UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73242UA_VariableAttributes attr = UA_VariableAttributes_default;
73243attr.minimumSamplingInterval = 0.000000;
73244attr.userAccessLevel = 1;
73245attr.accessLevel = 1;
73246attr.valueRank = 1;
73247attr.arrayDimensionsSize = 1;
73248UA_UInt32 arrayDimensions[1];
73249arrayDimensions[0] = 0;
73250attr.arrayDimensions = &arrayDimensions[0];
73251attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
73252UA_Argument variablenode_ns_0_i_17976_variant_DataContents[1];
73253
73254UA_init(p: &variablenode_ns_0_i_17976_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
73255variablenode_ns_0_i_17976_variant_DataContents[0].name = UA_STRING(chars: "Configuration");
73256variablenode_ns_0_i_17976_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15597LU);
73257variablenode_ns_0_i_17976_variant_DataContents[0].valueRank = (UA_Int32) -1;
73258UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_17976_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
73259attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
73260retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73261requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17976LU),
73262parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17969LU),
73263referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73264browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
73265typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73266attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73267if (retVal != UA_STATUSCODE_GOOD) return retVal;
73268
73269return retVal;
73270#else
73271return UA_STATUSCODE_GOOD;
73272#endif /* UA_ENABLE_METHODCALLS */
73273}
73274
73275static UA_StatusCode function_namespace0_generated_189_finish(UA_Server *server, UA_UInt16* ns) {
73276#ifdef UA_ENABLE_METHODCALLS
73277return UA_Server_addNode_finish(server,
73278nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17976LU)
73279);
73280#else
73281return UA_STATUSCODE_GOOD;
73282#endif /* UA_ENABLE_METHODCALLS */
73283}
73284
73285/* <DataSetWriterName> - ns=0;i=17743 */
73286
73287static UA_StatusCode function_namespace0_generated_190_begin(UA_Server *server, UA_UInt16* ns) {
73288UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73289UA_ObjectAttributes attr = UA_ObjectAttributes_default;
73290attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "<DataSetWriterName>");
73291retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
73292requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17743LU),
73293parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17725LU),
73294referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15296LU),
73295browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "<DataSetWriterName>"),
73296typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15298LU),
73297attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
73298if (retVal != UA_STATUSCODE_GOOD) return retVal;
73299return retVal;
73300}
73301
73302static UA_StatusCode function_namespace0_generated_190_finish(UA_Server *server, UA_UInt16* ns) {
73303return UA_Server_addNode_finish(server,
73304nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17743LU)
73305);
73306}
73307
73308/* Status - ns=0;i=17749 */
73309
73310static UA_StatusCode function_namespace0_generated_191_begin(UA_Server *server, UA_UInt16* ns) {
73311UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73312UA_ObjectAttributes attr = UA_ObjectAttributes_default;
73313attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Status");
73314retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
73315requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17749LU),
73316parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17743LU),
73317referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
73318browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Status"),
73319typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14643LU),
73320attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
73321if (retVal != UA_STATUSCODE_GOOD) return retVal;
73322return retVal;
73323}
73324
73325static UA_StatusCode function_namespace0_generated_191_finish(UA_Server *server, UA_UInt16* ns) {
73326return UA_Server_addNode_finish(server,
73327nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17749LU)
73328);
73329}
73330
73331/* State - ns=0;i=17750 */
73332
73333static UA_StatusCode function_namespace0_generated_192_begin(UA_Server *server, UA_UInt16* ns) {
73334UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73335UA_VariableAttributes attr = UA_VariableAttributes_default;
73336attr.minimumSamplingInterval = 0.000000;
73337attr.userAccessLevel = 1;
73338attr.accessLevel = 1;
73339/* Value rank inherited */
73340attr.valueRank = -2;
73341attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14647LU);
73342attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "State");
73343retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73344requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17750LU),
73345parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17749LU),
73346referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
73347browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "State"),
73348typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
73349attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73350if (retVal != UA_STATUSCODE_GOOD) return retVal;
73351return retVal;
73352}
73353
73354static UA_StatusCode function_namespace0_generated_192_finish(UA_Server *server, UA_UInt16* ns) {
73355return UA_Server_addNode_finish(server,
73356nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17750LU)
73357);
73358}
73359
73360/* DataSetFieldContentMask - ns=0;i=17745 */
73361
73362static UA_StatusCode function_namespace0_generated_193_begin(UA_Server *server, UA_UInt16* ns) {
73363UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73364UA_VariableAttributes attr = UA_VariableAttributes_default;
73365attr.minimumSamplingInterval = 0.000000;
73366attr.userAccessLevel = 1;
73367attr.accessLevel = 1;
73368/* Value rank inherited */
73369attr.valueRank = -2;
73370attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15583LU);
73371attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetFieldContentMask");
73372retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73373requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17745LU),
73374parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17743LU),
73375referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73376browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetFieldContentMask"),
73377typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73378attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73379if (retVal != UA_STATUSCODE_GOOD) return retVal;
73380return retVal;
73381}
73382
73383static UA_StatusCode function_namespace0_generated_193_finish(UA_Server *server, UA_UInt16* ns) {
73384return UA_Server_addNode_finish(server,
73385nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17745LU)
73386);
73387}
73388
73389/* DataSetWriterId - ns=0;i=17744 */
73390
73391static UA_StatusCode function_namespace0_generated_194_begin(UA_Server *server, UA_UInt16* ns) {
73392UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73393UA_VariableAttributes attr = UA_VariableAttributes_default;
73394attr.minimumSamplingInterval = 0.000000;
73395attr.userAccessLevel = 1;
73396attr.accessLevel = 1;
73397/* Value rank inherited */
73398attr.valueRank = -2;
73399attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
73400attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetWriterId");
73401retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73402requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17744LU),
73403parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17743LU),
73404referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73405browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetWriterId"),
73406typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73407attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73408if (retVal != UA_STATUSCODE_GOOD) return retVal;
73409return retVal;
73410}
73411
73412static UA_StatusCode function_namespace0_generated_194_finish(UA_Server *server, UA_UInt16* ns) {
73413return UA_Server_addNode_finish(server,
73414nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17744LU)
73415);
73416}
73417
73418/* DataSetWriterProperties - ns=0;i=17490 */
73419
73420static UA_StatusCode function_namespace0_generated_195_begin(UA_Server *server, UA_UInt16* ns) {
73421UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73422UA_VariableAttributes attr = UA_VariableAttributes_default;
73423attr.minimumSamplingInterval = 0.000000;
73424attr.userAccessLevel = 1;
73425attr.accessLevel = 1;
73426attr.valueRank = 1;
73427attr.arrayDimensionsSize = 1;
73428UA_UInt32 arrayDimensions[1];
73429arrayDimensions[0] = 0;
73430attr.arrayDimensions = &arrayDimensions[0];
73431attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14533LU);
73432attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetWriterProperties");
73433retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73434requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17490LU),
73435parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17743LU),
73436referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73437browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetWriterProperties"),
73438typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73439attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73440if (retVal != UA_STATUSCODE_GOOD) return retVal;
73441return retVal;
73442}
73443
73444static UA_StatusCode function_namespace0_generated_195_finish(UA_Server *server, UA_UInt16* ns) {
73445return UA_Server_addNode_finish(server,
73446nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17490LU)
73447);
73448}
73449
73450/* LocaleIds - ns=0;i=17740 */
73451
73452static UA_StatusCode function_namespace0_generated_196_begin(UA_Server *server, UA_UInt16* ns) {
73453UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73454UA_VariableAttributes attr = UA_VariableAttributes_default;
73455attr.minimumSamplingInterval = 0.000000;
73456attr.userAccessLevel = 1;
73457attr.accessLevel = 1;
73458attr.valueRank = 1;
73459attr.arrayDimensionsSize = 1;
73460UA_UInt32 arrayDimensions[1];
73461arrayDimensions[0] = 0;
73462attr.arrayDimensions = &arrayDimensions[0];
73463attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 295LU);
73464attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "LocaleIds");
73465retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73466requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17740LU),
73467parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17725LU),
73468referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73469browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "LocaleIds"),
73470typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73471attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73472if (retVal != UA_STATUSCODE_GOOD) return retVal;
73473return retVal;
73474}
73475
73476static UA_StatusCode function_namespace0_generated_196_finish(UA_Server *server, UA_UInt16* ns) {
73477return UA_Server_addNode_finish(server,
73478nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17740LU)
73479);
73480}
73481
73482/* Priority - ns=0;i=17739 */
73483
73484static UA_StatusCode function_namespace0_generated_197_begin(UA_Server *server, UA_UInt16* ns) {
73485UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73486UA_VariableAttributes attr = UA_VariableAttributes_default;
73487attr.minimumSamplingInterval = 0.000000;
73488attr.userAccessLevel = 1;
73489attr.accessLevel = 1;
73490/* Value rank inherited */
73491attr.valueRank = -2;
73492attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3LU);
73493attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Priority");
73494retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73495requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17739LU),
73496parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17725LU),
73497referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73498browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Priority"),
73499typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73500attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73501if (retVal != UA_STATUSCODE_GOOD) return retVal;
73502return retVal;
73503}
73504
73505static UA_StatusCode function_namespace0_generated_197_finish(UA_Server *server, UA_UInt16* ns) {
73506return UA_Server_addNode_finish(server,
73507nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17739LU)
73508);
73509}
73510
73511/* KeepAliveTime - ns=0;i=17738 */
73512
73513static UA_StatusCode function_namespace0_generated_198_begin(UA_Server *server, UA_UInt16* ns) {
73514UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73515UA_VariableAttributes attr = UA_VariableAttributes_default;
73516attr.minimumSamplingInterval = 0.000000;
73517attr.userAccessLevel = 1;
73518attr.accessLevel = 1;
73519/* Value rank inherited */
73520attr.valueRank = -2;
73521attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU);
73522attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "KeepAliveTime");
73523retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73524requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17738LU),
73525parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17725LU),
73526referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73527browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "KeepAliveTime"),
73528typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73529attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73530if (retVal != UA_STATUSCODE_GOOD) return retVal;
73531return retVal;
73532}
73533
73534static UA_StatusCode function_namespace0_generated_198_finish(UA_Server *server, UA_UInt16* ns) {
73535return UA_Server_addNode_finish(server,
73536nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17738LU)
73537);
73538}
73539
73540/* PublishingInterval - ns=0;i=17737 */
73541
73542static UA_StatusCode function_namespace0_generated_199_begin(UA_Server *server, UA_UInt16* ns) {
73543UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73544UA_VariableAttributes attr = UA_VariableAttributes_default;
73545attr.minimumSamplingInterval = 0.000000;
73546attr.userAccessLevel = 1;
73547attr.accessLevel = 1;
73548/* Value rank inherited */
73549attr.valueRank = -2;
73550attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU);
73551attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishingInterval");
73552retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73553requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17737LU),
73554parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17725LU),
73555referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73556browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishingInterval"),
73557typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73558attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73559if (retVal != UA_STATUSCODE_GOOD) return retVal;
73560return retVal;
73561}
73562
73563static UA_StatusCode function_namespace0_generated_199_finish(UA_Server *server, UA_UInt16* ns) {
73564return UA_Server_addNode_finish(server,
73565nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17737LU)
73566);
73567}
73568
73569/* WriterGroupId - ns=0;i=17736 */
73570
73571static UA_StatusCode function_namespace0_generated_200_begin(UA_Server *server, UA_UInt16* ns) {
73572UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73573UA_VariableAttributes attr = UA_VariableAttributes_default;
73574attr.minimumSamplingInterval = 0.000000;
73575attr.userAccessLevel = 1;
73576attr.accessLevel = 1;
73577/* Value rank inherited */
73578attr.valueRank = -2;
73579attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
73580attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "WriterGroupId");
73581retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73582requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17736LU),
73583parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17725LU),
73584referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73585browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "WriterGroupId"),
73586typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73587attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73588if (retVal != UA_STATUSCODE_GOOD) return retVal;
73589return retVal;
73590}
73591
73592static UA_StatusCode function_namespace0_generated_200_finish(UA_Server *server, UA_UInt16* ns) {
73593return UA_Server_addNode_finish(server,
73594nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17736LU)
73595);
73596}
73597
73598/* MaxNetworkMessageSize - ns=0;i=17724 */
73599
73600static UA_StatusCode function_namespace0_generated_201_begin(UA_Server *server, UA_UInt16* ns) {
73601UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73602UA_VariableAttributes attr = UA_VariableAttributes_default;
73603attr.minimumSamplingInterval = 0.000000;
73604attr.userAccessLevel = 1;
73605attr.accessLevel = 1;
73606/* Value rank inherited */
73607attr.valueRank = -2;
73608attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
73609attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNetworkMessageSize");
73610retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73611requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17724LU),
73612parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14232LU),
73613referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73614browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNetworkMessageSize"),
73615typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73616attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73617if (retVal != UA_STATUSCODE_GOOD) return retVal;
73618return retVal;
73619}
73620
73621static UA_StatusCode function_namespace0_generated_201_finish(UA_Server *server, UA_UInt16* ns) {
73622return UA_Server_addNode_finish(server,
73623nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17724LU)
73624);
73625}
73626
73627/* SecurityGroupId - ns=0;i=15927 */
73628
73629static UA_StatusCode function_namespace0_generated_202_begin(UA_Server *server, UA_UInt16* ns) {
73630UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73631UA_VariableAttributes attr = UA_VariableAttributes_default;
73632attr.minimumSamplingInterval = 0.000000;
73633attr.userAccessLevel = 1;
73634attr.accessLevel = 1;
73635/* Value rank inherited */
73636attr.valueRank = -2;
73637attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
73638attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityGroupId");
73639retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73640requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15927LU),
73641parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14232LU),
73642referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73643browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityGroupId"),
73644typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73645attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73646if (retVal != UA_STATUSCODE_GOOD) return retVal;
73647return retVal;
73648}
73649
73650static UA_StatusCode function_namespace0_generated_202_finish(UA_Server *server, UA_UInt16* ns) {
73651return UA_Server_addNode_finish(server,
73652nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15927LU)
73653);
73654}
73655
73656/* ConnectionTransportType - ns=0;i=17721 */
73657
73658static UA_StatusCode function_namespace0_generated_203_begin(UA_Server *server, UA_UInt16* ns) {
73659UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73660UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
73661attr.isAbstract = true;
73662attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ConnectionTransportType");
73663retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
73664requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17721LU),
73665parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
73666referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
73667browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ConnectionTransportType"),
73668 typeDefinition: UA_NODEID_NULL,
73669attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
73670if (retVal != UA_STATUSCODE_GOOD) return retVal;
73671return retVal;
73672}
73673
73674static UA_StatusCode function_namespace0_generated_203_finish(UA_Server *server, UA_UInt16* ns) {
73675return UA_Server_addNode_finish(server,
73676nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17721LU)
73677);
73678}
73679
73680/* NetworkAddressType - ns=0;i=21145 */
73681
73682static UA_StatusCode function_namespace0_generated_204_begin(UA_Server *server, UA_UInt16* ns) {
73683UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73684UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
73685attr.isAbstract = true;
73686attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NetworkAddressType");
73687retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
73688requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21145LU),
73689parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
73690referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
73691browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NetworkAddressType"),
73692 typeDefinition: UA_NODEID_NULL,
73693attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
73694if (retVal != UA_STATUSCODE_GOOD) return retVal;
73695return retVal;
73696}
73697
73698static UA_StatusCode function_namespace0_generated_204_finish(UA_Server *server, UA_UInt16* ns) {
73699return UA_Server_addNode_finish(server,
73700nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21145LU)
73701);
73702}
73703
73704/* NetworkAddressUrlType - ns=0;i=21147 */
73705
73706static UA_StatusCode function_namespace0_generated_205_begin(UA_Server *server, UA_UInt16* ns) {
73707UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73708UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
73709attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NetworkAddressUrlType");
73710retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
73711requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21147LU),
73712parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21145LU),
73713referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
73714browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NetworkAddressUrlType"),
73715 typeDefinition: UA_NODEID_NULL,
73716attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
73717if (retVal != UA_STATUSCODE_GOOD) return retVal;
73718return retVal;
73719}
73720
73721static UA_StatusCode function_namespace0_generated_205_finish(UA_Server *server, UA_UInt16* ns) {
73722return UA_Server_addNode_finish(server,
73723nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21147LU)
73724);
73725}
73726
73727/* Url - ns=0;i=21149 */
73728
73729static UA_StatusCode function_namespace0_generated_206_begin(UA_Server *server, UA_UInt16* ns) {
73730UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73731UA_VariableAttributes attr = UA_VariableAttributes_default;
73732attr.minimumSamplingInterval = 0.000000;
73733attr.userAccessLevel = 1;
73734attr.accessLevel = 1;
73735/* Value rank inherited */
73736attr.valueRank = -2;
73737attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
73738attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Url");
73739retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73740requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21149LU),
73741parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21147LU),
73742referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
73743browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Url"),
73744typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
73745attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73746if (retVal != UA_STATUSCODE_GOOD) return retVal;
73747return retVal;
73748}
73749
73750static UA_StatusCode function_namespace0_generated_206_finish(UA_Server *server, UA_UInt16* ns) {
73751return UA_Server_addNode_finish(server,
73752nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21149LU)
73753);
73754}
73755
73756/* NetworkInterface - ns=0;i=21146 */
73757
73758static UA_StatusCode function_namespace0_generated_207_begin(UA_Server *server, UA_UInt16* ns) {
73759UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73760UA_VariableAttributes attr = UA_VariableAttributes_default;
73761attr.minimumSamplingInterval = 0.000000;
73762attr.userAccessLevel = 1;
73763attr.accessLevel = 1;
73764/* Value rank inherited */
73765attr.valueRank = -2;
73766attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
73767attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NetworkInterface");
73768retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73769requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21146LU),
73770parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21145LU),
73771referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
73772browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NetworkInterface"),
73773typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
73774attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73775if (retVal != UA_STATUSCODE_GOOD) return retVal;
73776return retVal;
73777}
73778
73779static UA_StatusCode function_namespace0_generated_207_finish(UA_Server *server, UA_UInt16* ns) {
73780return UA_Server_addNode_finish(server,
73781nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21146LU)
73782);
73783}
73784
73785/* PubSubConnectionType - ns=0;i=14209 */
73786
73787static UA_StatusCode function_namespace0_generated_208_begin(UA_Server *server, UA_UInt16* ns) {
73788UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73789UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
73790attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PubSubConnectionType");
73791retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
73792requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU),
73793parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
73794referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
73795browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PubSubConnectionType"),
73796 typeDefinition: UA_NODEID_NULL,
73797attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
73798if (retVal != UA_STATUSCODE_GOOD) return retVal;
73799return retVal;
73800}
73801
73802static UA_StatusCode function_namespace0_generated_208_finish(UA_Server *server, UA_UInt16* ns) {
73803return UA_Server_addNode_finish(server,
73804nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU)
73805);
73806}
73807
73808/* ConnectionProperties - ns=0;i=17485 */
73809
73810static UA_StatusCode function_namespace0_generated_209_begin(UA_Server *server, UA_UInt16* ns) {
73811UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73812UA_VariableAttributes attr = UA_VariableAttributes_default;
73813attr.minimumSamplingInterval = 0.000000;
73814attr.userAccessLevel = 1;
73815attr.accessLevel = 1;
73816attr.valueRank = 1;
73817attr.arrayDimensionsSize = 1;
73818UA_UInt32 arrayDimensions[1];
73819arrayDimensions[0] = 0;
73820attr.arrayDimensions = &arrayDimensions[0];
73821attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14533LU);
73822attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ConnectionProperties");
73823retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73824requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17485LU),
73825parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU),
73826referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73827browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ConnectionProperties"),
73828typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73829attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73830if (retVal != UA_STATUSCODE_GOOD) return retVal;
73831return retVal;
73832}
73833
73834static UA_StatusCode function_namespace0_generated_209_finish(UA_Server *server, UA_UInt16* ns) {
73835return UA_Server_addNode_finish(server,
73836nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17485LU)
73837);
73838}
73839
73840/* AddReaderGroup - ns=0;i=17465 */
73841
73842static UA_StatusCode function_namespace0_generated_210_begin(UA_Server *server, UA_UInt16* ns) {
73843#ifdef UA_ENABLE_METHODCALLS
73844UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73845UA_MethodAttributes attr = UA_MethodAttributes_default;
73846attr.executable = true;
73847attr.userExecutable = true;
73848attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddReaderGroup");
73849retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
73850requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17465LU),
73851parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU),
73852referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
73853browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddReaderGroup"),
73854 typeDefinition: UA_NODEID_NULL,
73855attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
73856if (retVal != UA_STATUSCODE_GOOD) return retVal;
73857return retVal;
73858#else
73859return UA_STATUSCODE_GOOD;
73860#endif /* UA_ENABLE_METHODCALLS */
73861}
73862
73863static UA_StatusCode function_namespace0_generated_210_finish(UA_Server *server, UA_UInt16* ns) {
73864#ifdef UA_ENABLE_METHODCALLS
73865return UA_Server_addMethodNode_finish(server,
73866nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17465LU)
73867, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
73868#else
73869return UA_STATUSCODE_GOOD;
73870#endif /* UA_ENABLE_METHODCALLS */
73871}
73872
73873/* OutputArguments - ns=0;i=17508 */
73874
73875static UA_StatusCode function_namespace0_generated_211_begin(UA_Server *server, UA_UInt16* ns) {
73876#ifdef UA_ENABLE_METHODCALLS
73877UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73878UA_VariableAttributes attr = UA_VariableAttributes_default;
73879attr.minimumSamplingInterval = 0.000000;
73880attr.userAccessLevel = 1;
73881attr.accessLevel = 1;
73882attr.valueRank = 1;
73883attr.arrayDimensionsSize = 1;
73884UA_UInt32 arrayDimensions[1];
73885arrayDimensions[0] = 0;
73886attr.arrayDimensions = &arrayDimensions[0];
73887attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
73888UA_Argument variablenode_ns_0_i_17508_variant_DataContents[1];
73889
73890UA_init(p: &variablenode_ns_0_i_17508_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
73891variablenode_ns_0_i_17508_variant_DataContents[0].name = UA_STRING(chars: "GroupId");
73892variablenode_ns_0_i_17508_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
73893variablenode_ns_0_i_17508_variant_DataContents[0].valueRank = (UA_Int32) -1;
73894UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_17508_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
73895attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
73896retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73897requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17508LU),
73898parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17465LU),
73899referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73900browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
73901typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73902attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73903if (retVal != UA_STATUSCODE_GOOD) return retVal;
73904
73905return retVal;
73906#else
73907return UA_STATUSCODE_GOOD;
73908#endif /* UA_ENABLE_METHODCALLS */
73909}
73910
73911static UA_StatusCode function_namespace0_generated_211_finish(UA_Server *server, UA_UInt16* ns) {
73912#ifdef UA_ENABLE_METHODCALLS
73913return UA_Server_addNode_finish(server,
73914nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17508LU)
73915);
73916#else
73917return UA_STATUSCODE_GOOD;
73918#endif /* UA_ENABLE_METHODCALLS */
73919}
73920
73921/* InputArguments - ns=0;i=17507 */
73922
73923static UA_StatusCode function_namespace0_generated_212_begin(UA_Server *server, UA_UInt16* ns) {
73924#ifdef UA_ENABLE_METHODCALLS
73925UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73926UA_VariableAttributes attr = UA_VariableAttributes_default;
73927attr.minimumSamplingInterval = 0.000000;
73928attr.userAccessLevel = 1;
73929attr.accessLevel = 1;
73930attr.valueRank = 1;
73931attr.arrayDimensionsSize = 1;
73932UA_UInt32 arrayDimensions[1];
73933arrayDimensions[0] = 0;
73934attr.arrayDimensions = &arrayDimensions[0];
73935attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
73936UA_Argument variablenode_ns_0_i_17507_variant_DataContents[1];
73937
73938UA_init(p: &variablenode_ns_0_i_17507_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
73939variablenode_ns_0_i_17507_variant_DataContents[0].name = UA_STRING(chars: "Configuration");
73940variablenode_ns_0_i_17507_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15520LU);
73941variablenode_ns_0_i_17507_variant_DataContents[0].valueRank = (UA_Int32) -1;
73942UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_17507_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
73943attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
73944retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
73945requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17507LU),
73946parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17465LU),
73947referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
73948browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
73949typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
73950attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
73951if (retVal != UA_STATUSCODE_GOOD) return retVal;
73952
73953return retVal;
73954#else
73955return UA_STATUSCODE_GOOD;
73956#endif /* UA_ENABLE_METHODCALLS */
73957}
73958
73959static UA_StatusCode function_namespace0_generated_212_finish(UA_Server *server, UA_UInt16* ns) {
73960#ifdef UA_ENABLE_METHODCALLS
73961return UA_Server_addNode_finish(server,
73962nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17507LU)
73963);
73964#else
73965return UA_STATUSCODE_GOOD;
73966#endif /* UA_ENABLE_METHODCALLS */
73967}
73968
73969/* AddWriterGroup - ns=0;i=17427 */
73970
73971static UA_StatusCode function_namespace0_generated_213_begin(UA_Server *server, UA_UInt16* ns) {
73972#ifdef UA_ENABLE_METHODCALLS
73973UA_StatusCode retVal = UA_STATUSCODE_GOOD;
73974UA_MethodAttributes attr = UA_MethodAttributes_default;
73975attr.executable = true;
73976attr.userExecutable = true;
73977attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddWriterGroup");
73978retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
73979requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17427LU),
73980parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU),
73981referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
73982browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddWriterGroup"),
73983 typeDefinition: UA_NODEID_NULL,
73984attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
73985if (retVal != UA_STATUSCODE_GOOD) return retVal;
73986return retVal;
73987#else
73988return UA_STATUSCODE_GOOD;
73989#endif /* UA_ENABLE_METHODCALLS */
73990}
73991
73992static UA_StatusCode function_namespace0_generated_213_finish(UA_Server *server, UA_UInt16* ns) {
73993#ifdef UA_ENABLE_METHODCALLS
73994return UA_Server_addMethodNode_finish(server,
73995nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17427LU)
73996, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
73997#else
73998return UA_STATUSCODE_GOOD;
73999#endif /* UA_ENABLE_METHODCALLS */
74000}
74001
74002/* OutputArguments - ns=0;i=17456 */
74003
74004static UA_StatusCode function_namespace0_generated_214_begin(UA_Server *server, UA_UInt16* ns) {
74005#ifdef UA_ENABLE_METHODCALLS
74006UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74007UA_VariableAttributes attr = UA_VariableAttributes_default;
74008attr.minimumSamplingInterval = 0.000000;
74009attr.userAccessLevel = 1;
74010attr.accessLevel = 1;
74011attr.valueRank = 1;
74012attr.arrayDimensionsSize = 1;
74013UA_UInt32 arrayDimensions[1];
74014arrayDimensions[0] = 0;
74015attr.arrayDimensions = &arrayDimensions[0];
74016attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
74017UA_Argument variablenode_ns_0_i_17456_variant_DataContents[1];
74018
74019UA_init(p: &variablenode_ns_0_i_17456_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74020variablenode_ns_0_i_17456_variant_DataContents[0].name = UA_STRING(chars: "GroupId");
74021variablenode_ns_0_i_17456_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
74022variablenode_ns_0_i_17456_variant_DataContents[0].valueRank = (UA_Int32) -1;
74023UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_17456_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74024attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
74025retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74026requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17456LU),
74027parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17427LU),
74028referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74029browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
74030typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74031attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74032if (retVal != UA_STATUSCODE_GOOD) return retVal;
74033
74034return retVal;
74035#else
74036return UA_STATUSCODE_GOOD;
74037#endif /* UA_ENABLE_METHODCALLS */
74038}
74039
74040static UA_StatusCode function_namespace0_generated_214_finish(UA_Server *server, UA_UInt16* ns) {
74041#ifdef UA_ENABLE_METHODCALLS
74042return UA_Server_addNode_finish(server,
74043nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17456LU)
74044);
74045#else
74046return UA_STATUSCODE_GOOD;
74047#endif /* UA_ENABLE_METHODCALLS */
74048}
74049
74050/* InputArguments - ns=0;i=17428 */
74051
74052static UA_StatusCode function_namespace0_generated_215_begin(UA_Server *server, UA_UInt16* ns) {
74053#ifdef UA_ENABLE_METHODCALLS
74054UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74055UA_VariableAttributes attr = UA_VariableAttributes_default;
74056attr.minimumSamplingInterval = 0.000000;
74057attr.userAccessLevel = 1;
74058attr.accessLevel = 1;
74059attr.valueRank = 1;
74060attr.arrayDimensionsSize = 1;
74061UA_UInt32 arrayDimensions[1];
74062arrayDimensions[0] = 0;
74063attr.arrayDimensions = &arrayDimensions[0];
74064attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
74065UA_Argument variablenode_ns_0_i_17428_variant_DataContents[1];
74066
74067UA_init(p: &variablenode_ns_0_i_17428_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74068variablenode_ns_0_i_17428_variant_DataContents[0].name = UA_STRING(chars: "Configuration");
74069variablenode_ns_0_i_17428_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15480LU);
74070variablenode_ns_0_i_17428_variant_DataContents[0].valueRank = (UA_Int32) -1;
74071UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_17428_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74072attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
74073retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74074requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17428LU),
74075parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17427LU),
74076referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74077browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
74078typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74079attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74080if (retVal != UA_STATUSCODE_GOOD) return retVal;
74081
74082return retVal;
74083#else
74084return UA_STATUSCODE_GOOD;
74085#endif /* UA_ENABLE_METHODCALLS */
74086}
74087
74088static UA_StatusCode function_namespace0_generated_215_finish(UA_Server *server, UA_UInt16* ns) {
74089#ifdef UA_ENABLE_METHODCALLS
74090return UA_Server_addNode_finish(server,
74091nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17428LU)
74092);
74093#else
74094return UA_STATUSCODE_GOOD;
74095#endif /* UA_ENABLE_METHODCALLS */
74096}
74097
74098/* <ReaderGroupName> - ns=0;i=17325 */
74099
74100static UA_StatusCode function_namespace0_generated_216_begin(UA_Server *server, UA_UInt16* ns) {
74101UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74102UA_ObjectAttributes attr = UA_ObjectAttributes_default;
74103attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "<ReaderGroupName>");
74104retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
74105requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17325LU),
74106parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU),
74107referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
74108browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "<ReaderGroupName>"),
74109typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17999LU),
74110attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
74111if (retVal != UA_STATUSCODE_GOOD) return retVal;
74112return retVal;
74113}
74114
74115static UA_StatusCode function_namespace0_generated_216_finish(UA_Server *server, UA_UInt16* ns) {
74116return UA_Server_addNode_finish(server,
74117nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17325LU)
74118);
74119}
74120
74121/* <WriterGroupName> - ns=0;i=17310 */
74122
74123static UA_StatusCode function_namespace0_generated_217_begin(UA_Server *server, UA_UInt16* ns) {
74124UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74125UA_ObjectAttributes attr = UA_ObjectAttributes_default;
74126attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "<WriterGroupName>");
74127retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
74128requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17310LU),
74129parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU),
74130referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
74131browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "<WriterGroupName>"),
74132typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17725LU),
74133attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
74134if (retVal != UA_STATUSCODE_GOOD) return retVal;
74135return retVal;
74136}
74137
74138static UA_StatusCode function_namespace0_generated_217_finish(UA_Server *server, UA_UInt16* ns) {
74139return UA_Server_addNode_finish(server,
74140nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17310LU)
74141);
74142}
74143
74144/* TransportProfileUri - ns=0;i=17306 */
74145
74146static UA_StatusCode function_namespace0_generated_218_begin(UA_Server *server, UA_UInt16* ns) {
74147UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74148UA_VariableAttributes attr = UA_VariableAttributes_default;
74149attr.minimumSamplingInterval = 0.000000;
74150attr.userAccessLevel = 1;
74151attr.accessLevel = 1;
74152/* Value rank inherited */
74153attr.valueRank = -2;
74154attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
74155attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransportProfileUri");
74156retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74157requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17306LU),
74158parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU),
74159referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
74160browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransportProfileUri"),
74161typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16309LU),
74162attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74163if (retVal != UA_STATUSCODE_GOOD) return retVal;
74164return retVal;
74165}
74166
74167static UA_StatusCode function_namespace0_generated_218_finish(UA_Server *server, UA_UInt16* ns) {
74168return UA_Server_addNode_finish(server,
74169nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17306LU)
74170);
74171}
74172
74173/* Selections - ns=0;i=17710 */
74174
74175static UA_StatusCode function_namespace0_generated_219_begin(UA_Server *server, UA_UInt16* ns) {
74176UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74177UA_VariableAttributes attr = UA_VariableAttributes_default;
74178attr.minimumSamplingInterval = 0.000000;
74179attr.userAccessLevel = 1;
74180attr.accessLevel = 1;
74181attr.valueRank = 1;
74182attr.arrayDimensionsSize = 1;
74183UA_UInt32 arrayDimensions[1];
74184arrayDimensions[0] = 0;
74185attr.arrayDimensions = &arrayDimensions[0];
74186/* DataType inherited */
74187attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
74188attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Selections");
74189retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74190requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17710LU),
74191parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17306LU),
74192referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74193browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Selections"),
74194typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74195attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74196if (retVal != UA_STATUSCODE_GOOD) return retVal;
74197return retVal;
74198}
74199
74200static UA_StatusCode function_namespace0_generated_219_finish(UA_Server *server, UA_UInt16* ns) {
74201return UA_Server_addNode_finish(server,
74202nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17710LU)
74203);
74204}
74205
74206/* TransportSettings - ns=0;i=17203 */
74207
74208static UA_StatusCode function_namespace0_generated_220_begin(UA_Server *server, UA_UInt16* ns) {
74209UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74210UA_ObjectAttributes attr = UA_ObjectAttributes_default;
74211attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransportSettings");
74212retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
74213requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17203LU),
74214parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU),
74215referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
74216browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransportSettings"),
74217typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17721LU),
74218attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
74219if (retVal != UA_STATUSCODE_GOOD) return retVal;
74220return retVal;
74221}
74222
74223static UA_StatusCode function_namespace0_generated_220_finish(UA_Server *server, UA_UInt16* ns) {
74224return UA_Server_addNode_finish(server,
74225nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17203LU)
74226);
74227}
74228
74229/* Status - ns=0;i=14600 */
74230
74231static UA_StatusCode function_namespace0_generated_221_begin(UA_Server *server, UA_UInt16* ns) {
74232UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74233UA_ObjectAttributes attr = UA_ObjectAttributes_default;
74234attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Status");
74235retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
74236requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14600LU),
74237parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU),
74238referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
74239browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Status"),
74240typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14643LU),
74241attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
74242if (retVal != UA_STATUSCODE_GOOD) return retVal;
74243return retVal;
74244}
74245
74246static UA_StatusCode function_namespace0_generated_221_finish(UA_Server *server, UA_UInt16* ns) {
74247return UA_Server_addNode_finish(server,
74248nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14600LU)
74249);
74250}
74251
74252/* State - ns=0;i=14601 */
74253
74254static UA_StatusCode function_namespace0_generated_222_begin(UA_Server *server, UA_UInt16* ns) {
74255UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74256UA_VariableAttributes attr = UA_VariableAttributes_default;
74257attr.minimumSamplingInterval = 0.000000;
74258attr.userAccessLevel = 1;
74259attr.accessLevel = 1;
74260/* Value rank inherited */
74261attr.valueRank = -2;
74262attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14647LU);
74263attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "State");
74264retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74265requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14601LU),
74266parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14600LU),
74267referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
74268browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "State"),
74269typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
74270attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74271if (retVal != UA_STATUSCODE_GOOD) return retVal;
74272return retVal;
74273}
74274
74275static UA_StatusCode function_namespace0_generated_222_finish(UA_Server *server, UA_UInt16* ns) {
74276return UA_Server_addNode_finish(server,
74277nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14601LU)
74278);
74279}
74280
74281/* PublisherId - ns=0;i=14595 */
74282
74283static UA_StatusCode function_namespace0_generated_223_begin(UA_Server *server, UA_UInt16* ns) {
74284UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74285UA_VariableAttributes attr = UA_VariableAttributes_default;
74286attr.minimumSamplingInterval = 0.000000;
74287attr.userAccessLevel = 1;
74288attr.accessLevel = 1;
74289/* Value rank inherited */
74290attr.valueRank = -2;
74291/* DataType inherited */
74292attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
74293attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublisherId");
74294retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74295requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14595LU),
74296parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU),
74297referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74298browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublisherId"),
74299typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74300attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74301if (retVal != UA_STATUSCODE_GOOD) return retVal;
74302return retVal;
74303}
74304
74305static UA_StatusCode function_namespace0_generated_223_finish(UA_Server *server, UA_UInt16* ns) {
74306return UA_Server_addNode_finish(server,
74307nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14595LU)
74308);
74309}
74310
74311/* RemoveGroup - ns=0;i=14225 */
74312
74313static UA_StatusCode function_namespace0_generated_224_begin(UA_Server *server, UA_UInt16* ns) {
74314#ifdef UA_ENABLE_METHODCALLS
74315UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74316UA_MethodAttributes attr = UA_MethodAttributes_default;
74317attr.executable = true;
74318attr.userExecutable = true;
74319attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RemoveGroup");
74320retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
74321requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14225LU),
74322parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU),
74323referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
74324browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RemoveGroup"),
74325 typeDefinition: UA_NODEID_NULL,
74326attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
74327if (retVal != UA_STATUSCODE_GOOD) return retVal;
74328return retVal;
74329#else
74330return UA_STATUSCODE_GOOD;
74331#endif /* UA_ENABLE_METHODCALLS */
74332}
74333
74334static UA_StatusCode function_namespace0_generated_224_finish(UA_Server *server, UA_UInt16* ns) {
74335#ifdef UA_ENABLE_METHODCALLS
74336return UA_Server_addMethodNode_finish(server,
74337nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14225LU)
74338, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
74339#else
74340return UA_STATUSCODE_GOOD;
74341#endif /* UA_ENABLE_METHODCALLS */
74342}
74343
74344/* InputArguments - ns=0;i=14226 */
74345
74346static UA_StatusCode function_namespace0_generated_225_begin(UA_Server *server, UA_UInt16* ns) {
74347#ifdef UA_ENABLE_METHODCALLS
74348UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74349UA_VariableAttributes attr = UA_VariableAttributes_default;
74350attr.minimumSamplingInterval = 0.000000;
74351attr.userAccessLevel = 1;
74352attr.accessLevel = 1;
74353attr.valueRank = 1;
74354attr.arrayDimensionsSize = 1;
74355UA_UInt32 arrayDimensions[1];
74356arrayDimensions[0] = 0;
74357attr.arrayDimensions = &arrayDimensions[0];
74358attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
74359UA_Argument variablenode_ns_0_i_14226_variant_DataContents[1];
74360
74361UA_init(p: &variablenode_ns_0_i_14226_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74362variablenode_ns_0_i_14226_variant_DataContents[0].name = UA_STRING(chars: "GroupId");
74363variablenode_ns_0_i_14226_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
74364variablenode_ns_0_i_14226_variant_DataContents[0].valueRank = (UA_Int32) -1;
74365UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_14226_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74366attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
74367retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74368requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14226LU),
74369parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14225LU),
74370referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74371browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
74372typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74373attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74374if (retVal != UA_STATUSCODE_GOOD) return retVal;
74375
74376return retVal;
74377#else
74378return UA_STATUSCODE_GOOD;
74379#endif /* UA_ENABLE_METHODCALLS */
74380}
74381
74382static UA_StatusCode function_namespace0_generated_225_finish(UA_Server *server, UA_UInt16* ns) {
74383#ifdef UA_ENABLE_METHODCALLS
74384return UA_Server_addNode_finish(server,
74385nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14226LU)
74386);
74387#else
74388return UA_STATUSCODE_GOOD;
74389#endif /* UA_ENABLE_METHODCALLS */
74390}
74391
74392/* Address - ns=0;i=14221 */
74393
74394static UA_StatusCode function_namespace0_generated_226_begin(UA_Server *server, UA_UInt16* ns) {
74395UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74396UA_ObjectAttributes attr = UA_ObjectAttributes_default;
74397attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Address");
74398retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
74399requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14221LU),
74400parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU),
74401referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
74402browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Address"),
74403typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21145LU),
74404attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
74405if (retVal != UA_STATUSCODE_GOOD) return retVal;
74406return retVal;
74407}
74408
74409static UA_StatusCode function_namespace0_generated_226_finish(UA_Server *server, UA_UInt16* ns) {
74410return UA_Server_addNode_finish(server,
74411nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14221LU)
74412);
74413}
74414
74415/* NetworkInterface - ns=0;i=17202 */
74416
74417static UA_StatusCode function_namespace0_generated_227_begin(UA_Server *server, UA_UInt16* ns) {
74418UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74419UA_VariableAttributes attr = UA_VariableAttributes_default;
74420attr.minimumSamplingInterval = 0.000000;
74421attr.userAccessLevel = 1;
74422attr.accessLevel = 1;
74423/* Value rank inherited */
74424attr.valueRank = -2;
74425attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
74426attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NetworkInterface");
74427retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74428requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17202LU),
74429parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14221LU),
74430referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
74431browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NetworkInterface"),
74432typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
74433attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74434if (retVal != UA_STATUSCODE_GOOD) return retVal;
74435return retVal;
74436}
74437
74438static UA_StatusCode function_namespace0_generated_227_finish(UA_Server *server, UA_UInt16* ns) {
74439return UA_Server_addNode_finish(server,
74440nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17202LU)
74441);
74442}
74443
74444/* PublishedDataSetType - ns=0;i=14509 */
74445
74446static UA_StatusCode function_namespace0_generated_228_begin(UA_Server *server, UA_UInt16* ns) {
74447UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74448UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
74449attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishedDataSetType");
74450retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
74451requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14509LU),
74452parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
74453referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
74454browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishedDataSetType"),
74455 typeDefinition: UA_NODEID_NULL,
74456attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
74457if (retVal != UA_STATUSCODE_GOOD) return retVal;
74458return retVal;
74459}
74460
74461static UA_StatusCode function_namespace0_generated_228_finish(UA_Server *server, UA_UInt16* ns) {
74462return UA_Server_addNode_finish(server,
74463nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14509LU)
74464);
74465}
74466
74467/* DataSetClassId - ns=0;i=16759 */
74468
74469static UA_StatusCode function_namespace0_generated_229_begin(UA_Server *server, UA_UInt16* ns) {
74470UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74471UA_VariableAttributes attr = UA_VariableAttributes_default;
74472attr.minimumSamplingInterval = 0.000000;
74473attr.userAccessLevel = 1;
74474attr.accessLevel = 1;
74475/* Value rank inherited */
74476attr.valueRank = -2;
74477attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14LU);
74478attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetClassId");
74479retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74480requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16759LU),
74481parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14509LU),
74482referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74483browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetClassId"),
74484typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74485attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74486if (retVal != UA_STATUSCODE_GOOD) return retVal;
74487return retVal;
74488}
74489
74490static UA_StatusCode function_namespace0_generated_229_finish(UA_Server *server, UA_UInt16* ns) {
74491return UA_Server_addNode_finish(server,
74492nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16759LU)
74493);
74494}
74495
74496/* DataSetMetaData - ns=0;i=15229 */
74497
74498static UA_StatusCode function_namespace0_generated_230_begin(UA_Server *server, UA_UInt16* ns) {
74499UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74500UA_VariableAttributes attr = UA_VariableAttributes_default;
74501attr.minimumSamplingInterval = 0.000000;
74502attr.userAccessLevel = 1;
74503attr.accessLevel = 1;
74504/* Value rank inherited */
74505attr.valueRank = -2;
74506attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14523LU);
74507attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetMetaData");
74508retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74509requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15229LU),
74510parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14509LU),
74511referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74512browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetMetaData"),
74513typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74514attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74515if (retVal != UA_STATUSCODE_GOOD) return retVal;
74516return retVal;
74517}
74518
74519static UA_StatusCode function_namespace0_generated_230_finish(UA_Server *server, UA_UInt16* ns) {
74520return UA_Server_addNode_finish(server,
74521nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15229LU)
74522);
74523}
74524
74525/* PublishedDataItemsType - ns=0;i=14534 */
74526
74527static UA_StatusCode function_namespace0_generated_231_begin(UA_Server *server, UA_UInt16* ns) {
74528UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74529UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
74530attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishedDataItemsType");
74531retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
74532requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14534LU),
74533parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14509LU),
74534referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
74535browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishedDataItemsType"),
74536 typeDefinition: UA_NODEID_NULL,
74537attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
74538if (retVal != UA_STATUSCODE_GOOD) return retVal;
74539return retVal;
74540}
74541
74542static UA_StatusCode function_namespace0_generated_231_finish(UA_Server *server, UA_UInt16* ns) {
74543return UA_Server_addNode_finish(server,
74544nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14534LU)
74545);
74546}
74547
74548/* RemoveVariables - ns=0;i=14558 */
74549
74550static UA_StatusCode function_namespace0_generated_232_begin(UA_Server *server, UA_UInt16* ns) {
74551#ifdef UA_ENABLE_METHODCALLS
74552UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74553UA_MethodAttributes attr = UA_MethodAttributes_default;
74554attr.executable = true;
74555attr.userExecutable = true;
74556attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RemoveVariables");
74557retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
74558requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14558LU),
74559parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14534LU),
74560referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
74561browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RemoveVariables"),
74562 typeDefinition: UA_NODEID_NULL,
74563attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
74564if (retVal != UA_STATUSCODE_GOOD) return retVal;
74565return retVal;
74566#else
74567return UA_STATUSCODE_GOOD;
74568#endif /* UA_ENABLE_METHODCALLS */
74569}
74570
74571static UA_StatusCode function_namespace0_generated_232_finish(UA_Server *server, UA_UInt16* ns) {
74572#ifdef UA_ENABLE_METHODCALLS
74573return UA_Server_addMethodNode_finish(server,
74574nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14558LU)
74575, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
74576#else
74577return UA_STATUSCODE_GOOD;
74578#endif /* UA_ENABLE_METHODCALLS */
74579}
74580
74581/* OutputArguments - ns=0;i=14560 */
74582
74583static UA_StatusCode function_namespace0_generated_233_begin(UA_Server *server, UA_UInt16* ns) {
74584#ifdef UA_ENABLE_METHODCALLS
74585UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74586UA_VariableAttributes attr = UA_VariableAttributes_default;
74587attr.minimumSamplingInterval = 0.000000;
74588attr.userAccessLevel = 1;
74589attr.accessLevel = 1;
74590attr.valueRank = 1;
74591attr.arrayDimensionsSize = 1;
74592UA_UInt32 arrayDimensions[1];
74593arrayDimensions[0] = 0;
74594attr.arrayDimensions = &arrayDimensions[0];
74595attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
74596UA_Argument variablenode_ns_0_i_14560_variant_DataContents[2];
74597
74598UA_init(p: &variablenode_ns_0_i_14560_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74599variablenode_ns_0_i_14560_variant_DataContents[0].name = UA_STRING(chars: "NewConfigurationVersion");
74600variablenode_ns_0_i_14560_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14593LU);
74601variablenode_ns_0_i_14560_variant_DataContents[0].valueRank = (UA_Int32) -1;
74602
74603UA_init(p: &variablenode_ns_0_i_14560_variant_DataContents[1], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74604variablenode_ns_0_i_14560_variant_DataContents[1].name = UA_STRING(chars: "RemoveResults");
74605variablenode_ns_0_i_14560_variant_DataContents[1].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 19LU);
74606variablenode_ns_0_i_14560_variant_DataContents[1].valueRank = (UA_Int32) 1;
74607UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_14560_variant_DataContents, arraySize: (UA_Int32) 2, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74608attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
74609retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74610requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14560LU),
74611parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14558LU),
74612referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74613browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
74614typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74615attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74616if (retVal != UA_STATUSCODE_GOOD) return retVal;
74617
74618
74619return retVal;
74620#else
74621return UA_STATUSCODE_GOOD;
74622#endif /* UA_ENABLE_METHODCALLS */
74623}
74624
74625static UA_StatusCode function_namespace0_generated_233_finish(UA_Server *server, UA_UInt16* ns) {
74626#ifdef UA_ENABLE_METHODCALLS
74627return UA_Server_addNode_finish(server,
74628nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14560LU)
74629);
74630#else
74631return UA_STATUSCODE_GOOD;
74632#endif /* UA_ENABLE_METHODCALLS */
74633}
74634
74635/* InputArguments - ns=0;i=14559 */
74636
74637static UA_StatusCode function_namespace0_generated_234_begin(UA_Server *server, UA_UInt16* ns) {
74638#ifdef UA_ENABLE_METHODCALLS
74639UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74640UA_VariableAttributes attr = UA_VariableAttributes_default;
74641attr.minimumSamplingInterval = 0.000000;
74642attr.userAccessLevel = 1;
74643attr.accessLevel = 1;
74644attr.valueRank = 1;
74645attr.arrayDimensionsSize = 1;
74646UA_UInt32 arrayDimensions[1];
74647arrayDimensions[0] = 0;
74648attr.arrayDimensions = &arrayDimensions[0];
74649attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
74650UA_Argument variablenode_ns_0_i_14559_variant_DataContents[2];
74651
74652UA_init(p: &variablenode_ns_0_i_14559_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74653variablenode_ns_0_i_14559_variant_DataContents[0].name = UA_STRING(chars: "ConfigurationVersion");
74654variablenode_ns_0_i_14559_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14593LU);
74655variablenode_ns_0_i_14559_variant_DataContents[0].valueRank = (UA_Int32) -1;
74656
74657UA_init(p: &variablenode_ns_0_i_14559_variant_DataContents[1], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74658variablenode_ns_0_i_14559_variant_DataContents[1].name = UA_STRING(chars: "VariablesToRemove");
74659variablenode_ns_0_i_14559_variant_DataContents[1].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
74660variablenode_ns_0_i_14559_variant_DataContents[1].valueRank = (UA_Int32) 1;
74661UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_14559_variant_DataContents, arraySize: (UA_Int32) 2, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74662attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
74663retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74664requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14559LU),
74665parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14558LU),
74666referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74667browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
74668typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74669attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74670if (retVal != UA_STATUSCODE_GOOD) return retVal;
74671
74672
74673return retVal;
74674#else
74675return UA_STATUSCODE_GOOD;
74676#endif /* UA_ENABLE_METHODCALLS */
74677}
74678
74679static UA_StatusCode function_namespace0_generated_234_finish(UA_Server *server, UA_UInt16* ns) {
74680#ifdef UA_ENABLE_METHODCALLS
74681return UA_Server_addNode_finish(server,
74682nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14559LU)
74683);
74684#else
74685return UA_STATUSCODE_GOOD;
74686#endif /* UA_ENABLE_METHODCALLS */
74687}
74688
74689/* AddVariables - ns=0;i=14555 */
74690
74691static UA_StatusCode function_namespace0_generated_235_begin(UA_Server *server, UA_UInt16* ns) {
74692#ifdef UA_ENABLE_METHODCALLS
74693UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74694UA_MethodAttributes attr = UA_MethodAttributes_default;
74695attr.executable = true;
74696attr.userExecutable = true;
74697attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddVariables");
74698retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
74699requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14555LU),
74700parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14534LU),
74701referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
74702browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddVariables"),
74703 typeDefinition: UA_NODEID_NULL,
74704attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
74705if (retVal != UA_STATUSCODE_GOOD) return retVal;
74706return retVal;
74707#else
74708return UA_STATUSCODE_GOOD;
74709#endif /* UA_ENABLE_METHODCALLS */
74710}
74711
74712static UA_StatusCode function_namespace0_generated_235_finish(UA_Server *server, UA_UInt16* ns) {
74713#ifdef UA_ENABLE_METHODCALLS
74714return UA_Server_addMethodNode_finish(server,
74715nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14555LU)
74716, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
74717#else
74718return UA_STATUSCODE_GOOD;
74719#endif /* UA_ENABLE_METHODCALLS */
74720}
74721
74722/* OutputArguments - ns=0;i=14557 */
74723
74724static UA_StatusCode function_namespace0_generated_236_begin(UA_Server *server, UA_UInt16* ns) {
74725#ifdef UA_ENABLE_METHODCALLS
74726UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74727UA_VariableAttributes attr = UA_VariableAttributes_default;
74728attr.minimumSamplingInterval = 0.000000;
74729attr.userAccessLevel = 1;
74730attr.accessLevel = 1;
74731attr.valueRank = 1;
74732attr.arrayDimensionsSize = 1;
74733UA_UInt32 arrayDimensions[1];
74734arrayDimensions[0] = 0;
74735attr.arrayDimensions = &arrayDimensions[0];
74736attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
74737UA_Argument variablenode_ns_0_i_14557_variant_DataContents[2];
74738
74739UA_init(p: &variablenode_ns_0_i_14557_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74740variablenode_ns_0_i_14557_variant_DataContents[0].name = UA_STRING(chars: "NewConfigurationVersion");
74741variablenode_ns_0_i_14557_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14593LU);
74742variablenode_ns_0_i_14557_variant_DataContents[0].valueRank = (UA_Int32) -1;
74743
74744UA_init(p: &variablenode_ns_0_i_14557_variant_DataContents[1], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74745variablenode_ns_0_i_14557_variant_DataContents[1].name = UA_STRING(chars: "AddResults");
74746variablenode_ns_0_i_14557_variant_DataContents[1].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 19LU);
74747variablenode_ns_0_i_14557_variant_DataContents[1].valueRank = (UA_Int32) 1;
74748UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_14557_variant_DataContents, arraySize: (UA_Int32) 2, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74749attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
74750retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74751requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14557LU),
74752parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14555LU),
74753referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74754browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
74755typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74756attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74757if (retVal != UA_STATUSCODE_GOOD) return retVal;
74758
74759
74760return retVal;
74761#else
74762return UA_STATUSCODE_GOOD;
74763#endif /* UA_ENABLE_METHODCALLS */
74764}
74765
74766static UA_StatusCode function_namespace0_generated_236_finish(UA_Server *server, UA_UInt16* ns) {
74767#ifdef UA_ENABLE_METHODCALLS
74768return UA_Server_addNode_finish(server,
74769nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14557LU)
74770);
74771#else
74772return UA_STATUSCODE_GOOD;
74773#endif /* UA_ENABLE_METHODCALLS */
74774}
74775
74776/* InputArguments - ns=0;i=14556 */
74777
74778static UA_StatusCode function_namespace0_generated_237_begin(UA_Server *server, UA_UInt16* ns) {
74779#ifdef UA_ENABLE_METHODCALLS
74780UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74781UA_VariableAttributes attr = UA_VariableAttributes_default;
74782attr.minimumSamplingInterval = 0.000000;
74783attr.userAccessLevel = 1;
74784attr.accessLevel = 1;
74785attr.valueRank = 1;
74786attr.arrayDimensionsSize = 1;
74787UA_UInt32 arrayDimensions[1];
74788arrayDimensions[0] = 0;
74789attr.arrayDimensions = &arrayDimensions[0];
74790attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
74791UA_Argument variablenode_ns_0_i_14556_variant_DataContents[4];
74792
74793UA_init(p: &variablenode_ns_0_i_14556_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74794variablenode_ns_0_i_14556_variant_DataContents[0].name = UA_STRING(chars: "ConfigurationVersion");
74795variablenode_ns_0_i_14556_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14593LU);
74796variablenode_ns_0_i_14556_variant_DataContents[0].valueRank = (UA_Int32) -1;
74797
74798UA_init(p: &variablenode_ns_0_i_14556_variant_DataContents[1], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74799variablenode_ns_0_i_14556_variant_DataContents[1].name = UA_STRING(chars: "FieldNameAliases");
74800variablenode_ns_0_i_14556_variant_DataContents[1].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
74801variablenode_ns_0_i_14556_variant_DataContents[1].valueRank = (UA_Int32) 1;
74802
74803UA_init(p: &variablenode_ns_0_i_14556_variant_DataContents[2], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74804variablenode_ns_0_i_14556_variant_DataContents[2].name = UA_STRING(chars: "PromotedFields");
74805variablenode_ns_0_i_14556_variant_DataContents[2].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
74806variablenode_ns_0_i_14556_variant_DataContents[2].valueRank = (UA_Int32) 1;
74807
74808UA_init(p: &variablenode_ns_0_i_14556_variant_DataContents[3], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74809variablenode_ns_0_i_14556_variant_DataContents[3].name = UA_STRING(chars: "VariablesToAdd");
74810variablenode_ns_0_i_14556_variant_DataContents[3].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14273LU);
74811variablenode_ns_0_i_14556_variant_DataContents[3].valueRank = (UA_Int32) 1;
74812UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_14556_variant_DataContents, arraySize: (UA_Int32) 4, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74813attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
74814retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74815requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14556LU),
74816parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14555LU),
74817referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74818browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
74819typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74820attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74821if (retVal != UA_STATUSCODE_GOOD) return retVal;
74822
74823
74824
74825
74826return retVal;
74827#else
74828return UA_STATUSCODE_GOOD;
74829#endif /* UA_ENABLE_METHODCALLS */
74830}
74831
74832static UA_StatusCode function_namespace0_generated_237_finish(UA_Server *server, UA_UInt16* ns) {
74833#ifdef UA_ENABLE_METHODCALLS
74834return UA_Server_addNode_finish(server,
74835nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14556LU)
74836);
74837#else
74838return UA_STATUSCODE_GOOD;
74839#endif /* UA_ENABLE_METHODCALLS */
74840}
74841
74842/* PublishedData - ns=0;i=14548 */
74843
74844static UA_StatusCode function_namespace0_generated_238_begin(UA_Server *server, UA_UInt16* ns) {
74845UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74846UA_VariableAttributes attr = UA_VariableAttributes_default;
74847attr.minimumSamplingInterval = 0.000000;
74848attr.userAccessLevel = 1;
74849attr.accessLevel = 1;
74850attr.valueRank = 1;
74851attr.arrayDimensionsSize = 1;
74852UA_UInt32 arrayDimensions[1];
74853arrayDimensions[0] = 0;
74854attr.arrayDimensions = &arrayDimensions[0];
74855attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14273LU);
74856attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishedData");
74857retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74858requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14548LU),
74859parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14534LU),
74860referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74861browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishedData"),
74862typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74863attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74864if (retVal != UA_STATUSCODE_GOOD) return retVal;
74865return retVal;
74866}
74867
74868static UA_StatusCode function_namespace0_generated_238_finish(UA_Server *server, UA_UInt16* ns) {
74869return UA_Server_addNode_finish(server,
74870nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14548LU)
74871);
74872}
74873
74874/* ConfigurationVersion - ns=0;i=14519 */
74875
74876static UA_StatusCode function_namespace0_generated_239_begin(UA_Server *server, UA_UInt16* ns) {
74877UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74878UA_VariableAttributes attr = UA_VariableAttributes_default;
74879attr.minimumSamplingInterval = 0.000000;
74880attr.userAccessLevel = 1;
74881attr.accessLevel = 1;
74882/* Value rank inherited */
74883attr.valueRank = -2;
74884attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14593LU);
74885attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ConfigurationVersion");
74886retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74887requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14519LU),
74888parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14509LU),
74889referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74890browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ConfigurationVersion"),
74891typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74892attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74893if (retVal != UA_STATUSCODE_GOOD) return retVal;
74894return retVal;
74895}
74896
74897static UA_StatusCode function_namespace0_generated_239_finish(UA_Server *server, UA_UInt16* ns) {
74898return UA_Server_addNode_finish(server,
74899nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14519LU)
74900);
74901}
74902
74903/* DataSetFolderType - ns=0;i=14477 */
74904
74905static UA_StatusCode function_namespace0_generated_240_begin(UA_Server *server, UA_UInt16* ns) {
74906UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74907UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
74908attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataSetFolderType");
74909retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
74910requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14477LU),
74911parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 61LU),
74912referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
74913browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataSetFolderType"),
74914 typeDefinition: UA_NODEID_NULL,
74915attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
74916if (retVal != UA_STATUSCODE_GOOD) return retVal;
74917return retVal;
74918}
74919
74920static UA_StatusCode function_namespace0_generated_240_finish(UA_Server *server, UA_UInt16* ns) {
74921return UA_Server_addNode_finish(server,
74922nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14477LU)
74923);
74924}
74925
74926/* RemoveDataSetFolder - ns=0;i=16997 */
74927
74928static UA_StatusCode function_namespace0_generated_241_begin(UA_Server *server, UA_UInt16* ns) {
74929#ifdef UA_ENABLE_METHODCALLS
74930UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74931UA_MethodAttributes attr = UA_MethodAttributes_default;
74932attr.executable = true;
74933attr.userExecutable = true;
74934attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RemoveDataSetFolder");
74935retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
74936requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16997LU),
74937parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14477LU),
74938referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
74939browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RemoveDataSetFolder"),
74940 typeDefinition: UA_NODEID_NULL,
74941attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
74942if (retVal != UA_STATUSCODE_GOOD) return retVal;
74943return retVal;
74944#else
74945return UA_STATUSCODE_GOOD;
74946#endif /* UA_ENABLE_METHODCALLS */
74947}
74948
74949static UA_StatusCode function_namespace0_generated_241_finish(UA_Server *server, UA_UInt16* ns) {
74950#ifdef UA_ENABLE_METHODCALLS
74951return UA_Server_addMethodNode_finish(server,
74952nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16997LU)
74953, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
74954#else
74955return UA_STATUSCODE_GOOD;
74956#endif /* UA_ENABLE_METHODCALLS */
74957}
74958
74959/* InputArguments - ns=0;i=17007 */
74960
74961static UA_StatusCode function_namespace0_generated_242_begin(UA_Server *server, UA_UInt16* ns) {
74962#ifdef UA_ENABLE_METHODCALLS
74963UA_StatusCode retVal = UA_STATUSCODE_GOOD;
74964UA_VariableAttributes attr = UA_VariableAttributes_default;
74965attr.minimumSamplingInterval = 0.000000;
74966attr.userAccessLevel = 1;
74967attr.accessLevel = 1;
74968attr.valueRank = 1;
74969attr.arrayDimensionsSize = 1;
74970UA_UInt32 arrayDimensions[1];
74971arrayDimensions[0] = 0;
74972attr.arrayDimensions = &arrayDimensions[0];
74973attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
74974UA_Argument variablenode_ns_0_i_17007_variant_DataContents[1];
74975
74976UA_init(p: &variablenode_ns_0_i_17007_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74977variablenode_ns_0_i_17007_variant_DataContents[0].name = UA_STRING(chars: "DataSetFolderNodeId");
74978variablenode_ns_0_i_17007_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
74979variablenode_ns_0_i_17007_variant_DataContents[0].valueRank = (UA_Int32) -1;
74980UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_17007_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
74981attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
74982retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
74983requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17007LU),
74984parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16997LU),
74985referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
74986browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
74987typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
74988attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
74989if (retVal != UA_STATUSCODE_GOOD) return retVal;
74990
74991return retVal;
74992#else
74993return UA_STATUSCODE_GOOD;
74994#endif /* UA_ENABLE_METHODCALLS */
74995}
74996
74997static UA_StatusCode function_namespace0_generated_242_finish(UA_Server *server, UA_UInt16* ns) {
74998#ifdef UA_ENABLE_METHODCALLS
74999return UA_Server_addNode_finish(server,
75000nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17007LU)
75001);
75002#else
75003return UA_STATUSCODE_GOOD;
75004#endif /* UA_ENABLE_METHODCALLS */
75005}
75006
75007/* AddDataSetFolder - ns=0;i=16994 */
75008
75009static UA_StatusCode function_namespace0_generated_243_begin(UA_Server *server, UA_UInt16* ns) {
75010#ifdef UA_ENABLE_METHODCALLS
75011UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75012UA_MethodAttributes attr = UA_MethodAttributes_default;
75013attr.executable = true;
75014attr.userExecutable = true;
75015attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddDataSetFolder");
75016retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
75017requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16994LU),
75018parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14477LU),
75019referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
75020browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddDataSetFolder"),
75021 typeDefinition: UA_NODEID_NULL,
75022attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
75023if (retVal != UA_STATUSCODE_GOOD) return retVal;
75024return retVal;
75025#else
75026return UA_STATUSCODE_GOOD;
75027#endif /* UA_ENABLE_METHODCALLS */
75028}
75029
75030static UA_StatusCode function_namespace0_generated_243_finish(UA_Server *server, UA_UInt16* ns) {
75031#ifdef UA_ENABLE_METHODCALLS
75032return UA_Server_addMethodNode_finish(server,
75033nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16994LU)
75034, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
75035#else
75036return UA_STATUSCODE_GOOD;
75037#endif /* UA_ENABLE_METHODCALLS */
75038}
75039
75040/* OutputArguments - ns=0;i=16996 */
75041
75042static UA_StatusCode function_namespace0_generated_244_begin(UA_Server *server, UA_UInt16* ns) {
75043#ifdef UA_ENABLE_METHODCALLS
75044UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75045UA_VariableAttributes attr = UA_VariableAttributes_default;
75046attr.minimumSamplingInterval = 0.000000;
75047attr.userAccessLevel = 1;
75048attr.accessLevel = 1;
75049attr.valueRank = 1;
75050attr.arrayDimensionsSize = 1;
75051UA_UInt32 arrayDimensions[1];
75052arrayDimensions[0] = 0;
75053attr.arrayDimensions = &arrayDimensions[0];
75054attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
75055UA_Argument variablenode_ns_0_i_16996_variant_DataContents[1];
75056
75057UA_init(p: &variablenode_ns_0_i_16996_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75058variablenode_ns_0_i_16996_variant_DataContents[0].name = UA_STRING(chars: "DataSetFolderNodeId");
75059variablenode_ns_0_i_16996_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
75060variablenode_ns_0_i_16996_variant_DataContents[0].valueRank = (UA_Int32) -1;
75061UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_16996_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75062attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
75063retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75064requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16996LU),
75065parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16994LU),
75066referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
75067browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
75068typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
75069attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75070if (retVal != UA_STATUSCODE_GOOD) return retVal;
75071
75072return retVal;
75073#else
75074return UA_STATUSCODE_GOOD;
75075#endif /* UA_ENABLE_METHODCALLS */
75076}
75077
75078static UA_StatusCode function_namespace0_generated_244_finish(UA_Server *server, UA_UInt16* ns) {
75079#ifdef UA_ENABLE_METHODCALLS
75080return UA_Server_addNode_finish(server,
75081nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16996LU)
75082);
75083#else
75084return UA_STATUSCODE_GOOD;
75085#endif /* UA_ENABLE_METHODCALLS */
75086}
75087
75088/* InputArguments - ns=0;i=16995 */
75089
75090static UA_StatusCode function_namespace0_generated_245_begin(UA_Server *server, UA_UInt16* ns) {
75091#ifdef UA_ENABLE_METHODCALLS
75092UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75093UA_VariableAttributes attr = UA_VariableAttributes_default;
75094attr.minimumSamplingInterval = 0.000000;
75095attr.userAccessLevel = 1;
75096attr.accessLevel = 1;
75097attr.valueRank = 1;
75098attr.arrayDimensionsSize = 1;
75099UA_UInt32 arrayDimensions[1];
75100arrayDimensions[0] = 0;
75101attr.arrayDimensions = &arrayDimensions[0];
75102attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
75103UA_Argument variablenode_ns_0_i_16995_variant_DataContents[1];
75104
75105UA_init(p: &variablenode_ns_0_i_16995_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75106variablenode_ns_0_i_16995_variant_DataContents[0].name = UA_STRING(chars: "Name");
75107variablenode_ns_0_i_16995_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
75108variablenode_ns_0_i_16995_variant_DataContents[0].valueRank = (UA_Int32) -1;
75109UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_16995_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75110attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
75111retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75112requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16995LU),
75113parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16994LU),
75114referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
75115browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
75116typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
75117attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75118if (retVal != UA_STATUSCODE_GOOD) return retVal;
75119
75120return retVal;
75121#else
75122return UA_STATUSCODE_GOOD;
75123#endif /* UA_ENABLE_METHODCALLS */
75124}
75125
75126static UA_StatusCode function_namespace0_generated_245_finish(UA_Server *server, UA_UInt16* ns) {
75127#ifdef UA_ENABLE_METHODCALLS
75128return UA_Server_addNode_finish(server,
75129nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16995LU)
75130);
75131#else
75132return UA_STATUSCODE_GOOD;
75133#endif /* UA_ENABLE_METHODCALLS */
75134}
75135
75136/* RemovePublishedDataSet - ns=0;i=14499 */
75137
75138static UA_StatusCode function_namespace0_generated_246_begin(UA_Server *server, UA_UInt16* ns) {
75139#ifdef UA_ENABLE_METHODCALLS
75140UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75141UA_MethodAttributes attr = UA_MethodAttributes_default;
75142attr.executable = true;
75143attr.userExecutable = true;
75144attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RemovePublishedDataSet");
75145retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
75146requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14499LU),
75147parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14477LU),
75148referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
75149browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RemovePublishedDataSet"),
75150 typeDefinition: UA_NODEID_NULL,
75151attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
75152if (retVal != UA_STATUSCODE_GOOD) return retVal;
75153return retVal;
75154#else
75155return UA_STATUSCODE_GOOD;
75156#endif /* UA_ENABLE_METHODCALLS */
75157}
75158
75159static UA_StatusCode function_namespace0_generated_246_finish(UA_Server *server, UA_UInt16* ns) {
75160#ifdef UA_ENABLE_METHODCALLS
75161return UA_Server_addMethodNode_finish(server,
75162nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14499LU)
75163, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
75164#else
75165return UA_STATUSCODE_GOOD;
75166#endif /* UA_ENABLE_METHODCALLS */
75167}
75168
75169/* InputArguments - ns=0;i=14500 */
75170
75171static UA_StatusCode function_namespace0_generated_247_begin(UA_Server *server, UA_UInt16* ns) {
75172#ifdef UA_ENABLE_METHODCALLS
75173UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75174UA_VariableAttributes attr = UA_VariableAttributes_default;
75175attr.minimumSamplingInterval = 0.000000;
75176attr.userAccessLevel = 1;
75177attr.accessLevel = 1;
75178attr.valueRank = 1;
75179attr.arrayDimensionsSize = 1;
75180UA_UInt32 arrayDimensions[1];
75181arrayDimensions[0] = 0;
75182attr.arrayDimensions = &arrayDimensions[0];
75183attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
75184UA_Argument variablenode_ns_0_i_14500_variant_DataContents[1];
75185
75186UA_init(p: &variablenode_ns_0_i_14500_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75187variablenode_ns_0_i_14500_variant_DataContents[0].name = UA_STRING(chars: "DataSetNodeId");
75188variablenode_ns_0_i_14500_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
75189variablenode_ns_0_i_14500_variant_DataContents[0].valueRank = (UA_Int32) -1;
75190UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_14500_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75191attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
75192retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75193requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14500LU),
75194parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14499LU),
75195referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
75196browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
75197typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
75198attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75199if (retVal != UA_STATUSCODE_GOOD) return retVal;
75200
75201return retVal;
75202#else
75203return UA_STATUSCODE_GOOD;
75204#endif /* UA_ENABLE_METHODCALLS */
75205}
75206
75207static UA_StatusCode function_namespace0_generated_247_finish(UA_Server *server, UA_UInt16* ns) {
75208#ifdef UA_ENABLE_METHODCALLS
75209return UA_Server_addNode_finish(server,
75210nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14500LU)
75211);
75212#else
75213return UA_STATUSCODE_GOOD;
75214#endif /* UA_ENABLE_METHODCALLS */
75215}
75216
75217/* AddPublishedDataItems - ns=0;i=14493 */
75218
75219static UA_StatusCode function_namespace0_generated_248_begin(UA_Server *server, UA_UInt16* ns) {
75220#ifdef UA_ENABLE_METHODCALLS
75221UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75222UA_MethodAttributes attr = UA_MethodAttributes_default;
75223attr.executable = true;
75224attr.userExecutable = true;
75225attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddPublishedDataItems");
75226retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
75227requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14493LU),
75228parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14477LU),
75229referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
75230browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddPublishedDataItems"),
75231 typeDefinition: UA_NODEID_NULL,
75232attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
75233if (retVal != UA_STATUSCODE_GOOD) return retVal;
75234return retVal;
75235#else
75236return UA_STATUSCODE_GOOD;
75237#endif /* UA_ENABLE_METHODCALLS */
75238}
75239
75240static UA_StatusCode function_namespace0_generated_248_finish(UA_Server *server, UA_UInt16* ns) {
75241#ifdef UA_ENABLE_METHODCALLS
75242return UA_Server_addMethodNode_finish(server,
75243nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14493LU)
75244, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
75245#else
75246return UA_STATUSCODE_GOOD;
75247#endif /* UA_ENABLE_METHODCALLS */
75248}
75249
75250/* OutputArguments - ns=0;i=14495 */
75251
75252static UA_StatusCode function_namespace0_generated_249_begin(UA_Server *server, UA_UInt16* ns) {
75253#ifdef UA_ENABLE_METHODCALLS
75254UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75255UA_VariableAttributes attr = UA_VariableAttributes_default;
75256attr.minimumSamplingInterval = 0.000000;
75257attr.userAccessLevel = 1;
75258attr.accessLevel = 1;
75259attr.valueRank = 1;
75260attr.arrayDimensionsSize = 1;
75261UA_UInt32 arrayDimensions[1];
75262arrayDimensions[0] = 0;
75263attr.arrayDimensions = &arrayDimensions[0];
75264attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
75265UA_Argument variablenode_ns_0_i_14495_variant_DataContents[3];
75266
75267UA_init(p: &variablenode_ns_0_i_14495_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75268variablenode_ns_0_i_14495_variant_DataContents[0].name = UA_STRING(chars: "DataSetNodeId");
75269variablenode_ns_0_i_14495_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
75270variablenode_ns_0_i_14495_variant_DataContents[0].valueRank = (UA_Int32) -1;
75271
75272UA_init(p: &variablenode_ns_0_i_14495_variant_DataContents[1], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75273variablenode_ns_0_i_14495_variant_DataContents[1].name = UA_STRING(chars: "ConfigurationVersion");
75274variablenode_ns_0_i_14495_variant_DataContents[1].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14593LU);
75275variablenode_ns_0_i_14495_variant_DataContents[1].valueRank = (UA_Int32) -1;
75276
75277UA_init(p: &variablenode_ns_0_i_14495_variant_DataContents[2], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75278variablenode_ns_0_i_14495_variant_DataContents[2].name = UA_STRING(chars: "AddResults");
75279variablenode_ns_0_i_14495_variant_DataContents[2].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 19LU);
75280variablenode_ns_0_i_14495_variant_DataContents[2].valueRank = (UA_Int32) 1;
75281UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_14495_variant_DataContents, arraySize: (UA_Int32) 3, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75282attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
75283retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75284requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14495LU),
75285parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14493LU),
75286referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
75287browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
75288typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
75289attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75290if (retVal != UA_STATUSCODE_GOOD) return retVal;
75291
75292
75293
75294return retVal;
75295#else
75296return UA_STATUSCODE_GOOD;
75297#endif /* UA_ENABLE_METHODCALLS */
75298}
75299
75300static UA_StatusCode function_namespace0_generated_249_finish(UA_Server *server, UA_UInt16* ns) {
75301#ifdef UA_ENABLE_METHODCALLS
75302return UA_Server_addNode_finish(server,
75303nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14495LU)
75304);
75305#else
75306return UA_STATUSCODE_GOOD;
75307#endif /* UA_ENABLE_METHODCALLS */
75308}
75309
75310/* InputArguments - ns=0;i=14494 */
75311
75312static UA_StatusCode function_namespace0_generated_250_begin(UA_Server *server, UA_UInt16* ns) {
75313#ifdef UA_ENABLE_METHODCALLS
75314UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75315UA_VariableAttributes attr = UA_VariableAttributes_default;
75316attr.minimumSamplingInterval = 0.000000;
75317attr.userAccessLevel = 1;
75318attr.accessLevel = 1;
75319attr.valueRank = 1;
75320attr.arrayDimensionsSize = 1;
75321UA_UInt32 arrayDimensions[1];
75322arrayDimensions[0] = 0;
75323attr.arrayDimensions = &arrayDimensions[0];
75324attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
75325UA_Argument variablenode_ns_0_i_14494_variant_DataContents[4];
75326
75327UA_init(p: &variablenode_ns_0_i_14494_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75328variablenode_ns_0_i_14494_variant_DataContents[0].name = UA_STRING(chars: "Name");
75329variablenode_ns_0_i_14494_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
75330variablenode_ns_0_i_14494_variant_DataContents[0].valueRank = (UA_Int32) -1;
75331
75332UA_init(p: &variablenode_ns_0_i_14494_variant_DataContents[1], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75333variablenode_ns_0_i_14494_variant_DataContents[1].name = UA_STRING(chars: "FieldNameAliases");
75334variablenode_ns_0_i_14494_variant_DataContents[1].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
75335variablenode_ns_0_i_14494_variant_DataContents[1].valueRank = (UA_Int32) 1;
75336
75337UA_init(p: &variablenode_ns_0_i_14494_variant_DataContents[2], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75338variablenode_ns_0_i_14494_variant_DataContents[2].name = UA_STRING(chars: "FieldFlags");
75339variablenode_ns_0_i_14494_variant_DataContents[2].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15904LU);
75340variablenode_ns_0_i_14494_variant_DataContents[2].valueRank = (UA_Int32) 1;
75341
75342UA_init(p: &variablenode_ns_0_i_14494_variant_DataContents[3], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75343variablenode_ns_0_i_14494_variant_DataContents[3].name = UA_STRING(chars: "VariablesToAdd");
75344variablenode_ns_0_i_14494_variant_DataContents[3].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14273LU);
75345variablenode_ns_0_i_14494_variant_DataContents[3].valueRank = (UA_Int32) 1;
75346UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_14494_variant_DataContents, arraySize: (UA_Int32) 4, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75347attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
75348retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75349requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14494LU),
75350parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14493LU),
75351referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
75352browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
75353typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
75354attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75355if (retVal != UA_STATUSCODE_GOOD) return retVal;
75356
75357
75358
75359
75360return retVal;
75361#else
75362return UA_STATUSCODE_GOOD;
75363#endif /* UA_ENABLE_METHODCALLS */
75364}
75365
75366static UA_StatusCode function_namespace0_generated_250_finish(UA_Server *server, UA_UInt16* ns) {
75367#ifdef UA_ENABLE_METHODCALLS
75368return UA_Server_addNode_finish(server,
75369nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14494LU)
75370);
75371#else
75372return UA_STATUSCODE_GOOD;
75373#endif /* UA_ENABLE_METHODCALLS */
75374}
75375
75376/* <DataSetFolderName> - ns=0;i=14478 */
75377
75378static UA_StatusCode function_namespace0_generated_251_begin(UA_Server *server, UA_UInt16* ns) {
75379UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75380UA_ObjectAttributes attr = UA_ObjectAttributes_default;
75381attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "<DataSetFolderName>");
75382retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
75383requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14478LU),
75384parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14477LU),
75385referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 35LU),
75386browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "<DataSetFolderName>"),
75387typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14477LU),
75388attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
75389if (retVal != UA_STATUSCODE_GOOD) return retVal;
75390return retVal;
75391}
75392
75393static UA_StatusCode function_namespace0_generated_251_finish(UA_Server *server, UA_UInt16* ns) {
75394return UA_Server_addNode_finish(server,
75395nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14478LU)
75396);
75397}
75398
75399/* PubSubKeyServiceType - ns=0;i=15906 */
75400
75401static UA_StatusCode function_namespace0_generated_252_begin(UA_Server *server, UA_UInt16* ns) {
75402UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75403UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
75404attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PubSubKeyServiceType");
75405retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
75406requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15906LU),
75407parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
75408referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
75409browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PubSubKeyServiceType"),
75410 typeDefinition: UA_NODEID_NULL,
75411attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
75412if (retVal != UA_STATUSCODE_GOOD) return retVal;
75413return retVal;
75414}
75415
75416static UA_StatusCode function_namespace0_generated_252_finish(UA_Server *server, UA_UInt16* ns) {
75417return UA_Server_addNode_finish(server,
75418nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15906LU)
75419);
75420}
75421
75422/* PublishSubscribeType - ns=0;i=14416 */
75423
75424static UA_StatusCode function_namespace0_generated_253_begin(UA_Server *server, UA_UInt16* ns) {
75425UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75426UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
75427attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishSubscribeType");
75428retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
75429requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14416LU),
75430parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15906LU),
75431referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
75432browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishSubscribeType"),
75433 typeDefinition: UA_NODEID_NULL,
75434attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
75435if (retVal != UA_STATUSCODE_GOOD) return retVal;
75436return retVal;
75437}
75438
75439static UA_StatusCode function_namespace0_generated_253_finish(UA_Server *server, UA_UInt16* ns) {
75440return UA_Server_addNode_finish(server,
75441nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14416LU)
75442);
75443}
75444
75445/* DefaultDatagramPublisherId - ns=0;i=25432 */
75446
75447static UA_StatusCode function_namespace0_generated_254_begin(UA_Server *server, UA_UInt16* ns) {
75448UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75449UA_VariableAttributes attr = UA_VariableAttributes_default;
75450attr.minimumSamplingInterval = 0.000000;
75451attr.userAccessLevel = 1;
75452attr.accessLevel = 1;
75453/* Value rank inherited */
75454attr.valueRank = -2;
75455attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9LU);
75456attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DefaultDatagramPublisherId");
75457retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75458requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25432LU),
75459parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14416LU),
75460referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
75461browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DefaultDatagramPublisherId"),
75462typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
75463attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75464if (retVal != UA_STATUSCODE_GOOD) return retVal;
75465return retVal;
75466}
75467
75468static UA_StatusCode function_namespace0_generated_254_finish(UA_Server *server, UA_UInt16* ns) {
75469return UA_Server_addNode_finish(server,
75470nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25432LU)
75471);
75472}
75473
75474/* SubscribedDataSets - ns=0;i=23622 */
75475
75476static UA_StatusCode function_namespace0_generated_255_begin(UA_Server *server, UA_UInt16* ns) {
75477UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75478UA_ObjectAttributes attr = UA_ObjectAttributes_default;
75479attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscribedDataSets");
75480retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
75481requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23622LU),
75482parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14416LU),
75483referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
75484browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscribedDataSets"),
75485typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23795LU),
75486attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
75487if (retVal != UA_STATUSCODE_GOOD) return retVal;
75488return retVal;
75489}
75490
75491static UA_StatusCode function_namespace0_generated_255_finish(UA_Server *server, UA_UInt16* ns) {
75492return UA_Server_addNode_finish(server,
75493nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23622LU)
75494);
75495}
75496
75497/* SupportedTransportProfiles - ns=0;i=17479 */
75498
75499static UA_StatusCode function_namespace0_generated_256_begin(UA_Server *server, UA_UInt16* ns) {
75500UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75501UA_VariableAttributes attr = UA_VariableAttributes_default;
75502attr.minimumSamplingInterval = 0.000000;
75503attr.userAccessLevel = 1;
75504attr.accessLevel = 1;
75505attr.valueRank = 1;
75506attr.arrayDimensionsSize = 1;
75507UA_UInt32 arrayDimensions[1];
75508arrayDimensions[0] = 0;
75509attr.arrayDimensions = &arrayDimensions[0];
75510attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
75511attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SupportedTransportProfiles");
75512retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75513requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17479LU),
75514parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14416LU),
75515referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
75516browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SupportedTransportProfiles"),
75517typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
75518attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75519if (retVal != UA_STATUSCODE_GOOD) return retVal;
75520return retVal;
75521}
75522
75523static UA_StatusCode function_namespace0_generated_256_finish(UA_Server *server, UA_UInt16* ns) {
75524return UA_Server_addNode_finish(server,
75525nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17479LU)
75526);
75527}
75528
75529/* AddConnection - ns=0;i=16598 */
75530
75531static UA_StatusCode function_namespace0_generated_257_begin(UA_Server *server, UA_UInt16* ns) {
75532#ifdef UA_ENABLE_METHODCALLS
75533UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75534UA_MethodAttributes attr = UA_MethodAttributes_default;
75535attr.executable = true;
75536attr.userExecutable = true;
75537attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddConnection");
75538retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
75539requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16598LU),
75540parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14416LU),
75541referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
75542browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddConnection"),
75543 typeDefinition: UA_NODEID_NULL,
75544attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
75545if (retVal != UA_STATUSCODE_GOOD) return retVal;
75546return retVal;
75547#else
75548return UA_STATUSCODE_GOOD;
75549#endif /* UA_ENABLE_METHODCALLS */
75550}
75551
75552static UA_StatusCode function_namespace0_generated_257_finish(UA_Server *server, UA_UInt16* ns) {
75553#ifdef UA_ENABLE_METHODCALLS
75554return UA_Server_addMethodNode_finish(server,
75555nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16598LU)
75556, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
75557#else
75558return UA_STATUSCODE_GOOD;
75559#endif /* UA_ENABLE_METHODCALLS */
75560}
75561
75562/* OutputArguments - ns=0;i=16600 */
75563
75564static UA_StatusCode function_namespace0_generated_258_begin(UA_Server *server, UA_UInt16* ns) {
75565#ifdef UA_ENABLE_METHODCALLS
75566UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75567UA_VariableAttributes attr = UA_VariableAttributes_default;
75568attr.minimumSamplingInterval = 0.000000;
75569attr.userAccessLevel = 1;
75570attr.accessLevel = 1;
75571attr.valueRank = 1;
75572attr.arrayDimensionsSize = 1;
75573UA_UInt32 arrayDimensions[1];
75574arrayDimensions[0] = 0;
75575attr.arrayDimensions = &arrayDimensions[0];
75576attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
75577UA_Argument variablenode_ns_0_i_16600_variant_DataContents[1];
75578
75579UA_init(p: &variablenode_ns_0_i_16600_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75580variablenode_ns_0_i_16600_variant_DataContents[0].name = UA_STRING(chars: "ConnectionId");
75581variablenode_ns_0_i_16600_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
75582variablenode_ns_0_i_16600_variant_DataContents[0].valueRank = (UA_Int32) -1;
75583UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_16600_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75584attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
75585retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75586requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16600LU),
75587parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16598LU),
75588referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
75589browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
75590typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
75591attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75592if (retVal != UA_STATUSCODE_GOOD) return retVal;
75593
75594return retVal;
75595#else
75596return UA_STATUSCODE_GOOD;
75597#endif /* UA_ENABLE_METHODCALLS */
75598}
75599
75600static UA_StatusCode function_namespace0_generated_258_finish(UA_Server *server, UA_UInt16* ns) {
75601#ifdef UA_ENABLE_METHODCALLS
75602return UA_Server_addNode_finish(server,
75603nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16600LU)
75604);
75605#else
75606return UA_STATUSCODE_GOOD;
75607#endif /* UA_ENABLE_METHODCALLS */
75608}
75609
75610/* InputArguments - ns=0;i=16599 */
75611
75612static UA_StatusCode function_namespace0_generated_259_begin(UA_Server *server, UA_UInt16* ns) {
75613#ifdef UA_ENABLE_METHODCALLS
75614UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75615UA_VariableAttributes attr = UA_VariableAttributes_default;
75616attr.minimumSamplingInterval = 0.000000;
75617attr.userAccessLevel = 1;
75618attr.accessLevel = 1;
75619attr.valueRank = 1;
75620attr.arrayDimensionsSize = 1;
75621UA_UInt32 arrayDimensions[1];
75622arrayDimensions[0] = 0;
75623attr.arrayDimensions = &arrayDimensions[0];
75624attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
75625UA_Argument variablenode_ns_0_i_16599_variant_DataContents[1];
75626
75627UA_init(p: &variablenode_ns_0_i_16599_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75628variablenode_ns_0_i_16599_variant_DataContents[0].name = UA_STRING(chars: "Configuration");
75629variablenode_ns_0_i_16599_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15617LU);
75630variablenode_ns_0_i_16599_variant_DataContents[0].valueRank = (UA_Int32) -1;
75631UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_16599_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75632attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
75633retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75634requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16599LU),
75635parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16598LU),
75636referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
75637browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
75638typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
75639attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75640if (retVal != UA_STATUSCODE_GOOD) return retVal;
75641
75642return retVal;
75643#else
75644return UA_STATUSCODE_GOOD;
75645#endif /* UA_ENABLE_METHODCALLS */
75646}
75647
75648static UA_StatusCode function_namespace0_generated_259_finish(UA_Server *server, UA_UInt16* ns) {
75649#ifdef UA_ENABLE_METHODCALLS
75650return UA_Server_addNode_finish(server,
75651nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16599LU)
75652);
75653#else
75654return UA_STATUSCODE_GOOD;
75655#endif /* UA_ENABLE_METHODCALLS */
75656}
75657
75658/* Status - ns=0;i=15844 */
75659
75660static UA_StatusCode function_namespace0_generated_260_begin(UA_Server *server, UA_UInt16* ns) {
75661UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75662UA_ObjectAttributes attr = UA_ObjectAttributes_default;
75663attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Status");
75664retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
75665requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15844LU),
75666parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14416LU),
75667referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
75668browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Status"),
75669typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14643LU),
75670attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
75671if (retVal != UA_STATUSCODE_GOOD) return retVal;
75672return retVal;
75673}
75674
75675static UA_StatusCode function_namespace0_generated_260_finish(UA_Server *server, UA_UInt16* ns) {
75676return UA_Server_addNode_finish(server,
75677nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15844LU)
75678);
75679}
75680
75681/* State - ns=0;i=15845 */
75682
75683static UA_StatusCode function_namespace0_generated_261_begin(UA_Server *server, UA_UInt16* ns) {
75684UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75685UA_VariableAttributes attr = UA_VariableAttributes_default;
75686attr.minimumSamplingInterval = 0.000000;
75687attr.userAccessLevel = 1;
75688attr.accessLevel = 1;
75689/* Value rank inherited */
75690attr.valueRank = -2;
75691attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14647LU);
75692attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "State");
75693retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75694requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15845LU),
75695parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15844LU),
75696referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
75697browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "State"),
75698typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
75699attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75700if (retVal != UA_STATUSCODE_GOOD) return retVal;
75701return retVal;
75702}
75703
75704static UA_StatusCode function_namespace0_generated_261_finish(UA_Server *server, UA_UInt16* ns) {
75705return UA_Server_addNode_finish(server,
75706nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15845LU)
75707);
75708}
75709
75710/* PublishedDataSets - ns=0;i=14434 */
75711
75712static UA_StatusCode function_namespace0_generated_262_begin(UA_Server *server, UA_UInt16* ns) {
75713UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75714UA_ObjectAttributes attr = UA_ObjectAttributes_default;
75715attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishedDataSets");
75716retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
75717requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14434LU),
75718parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14416LU),
75719referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
75720browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishedDataSets"),
75721typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14477LU),
75722attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
75723if (retVal != UA_STATUSCODE_GOOD) return retVal;
75724return retVal;
75725}
75726
75727static UA_StatusCode function_namespace0_generated_262_finish(UA_Server *server, UA_UInt16* ns) {
75728return UA_Server_addNode_finish(server,
75729nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14434LU)
75730);
75731}
75732
75733/* RemoveConnection - ns=0;i=14432 */
75734
75735static UA_StatusCode function_namespace0_generated_263_begin(UA_Server *server, UA_UInt16* ns) {
75736#ifdef UA_ENABLE_METHODCALLS
75737UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75738UA_MethodAttributes attr = UA_MethodAttributes_default;
75739attr.executable = true;
75740attr.userExecutable = true;
75741attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RemoveConnection");
75742retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
75743requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14432LU),
75744parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14416LU),
75745referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
75746browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RemoveConnection"),
75747 typeDefinition: UA_NODEID_NULL,
75748attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
75749if (retVal != UA_STATUSCODE_GOOD) return retVal;
75750return retVal;
75751#else
75752return UA_STATUSCODE_GOOD;
75753#endif /* UA_ENABLE_METHODCALLS */
75754}
75755
75756static UA_StatusCode function_namespace0_generated_263_finish(UA_Server *server, UA_UInt16* ns) {
75757#ifdef UA_ENABLE_METHODCALLS
75758return UA_Server_addMethodNode_finish(server,
75759nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14432LU)
75760, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
75761#else
75762return UA_STATUSCODE_GOOD;
75763#endif /* UA_ENABLE_METHODCALLS */
75764}
75765
75766/* InputArguments - ns=0;i=14433 */
75767
75768static UA_StatusCode function_namespace0_generated_264_begin(UA_Server *server, UA_UInt16* ns) {
75769#ifdef UA_ENABLE_METHODCALLS
75770UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75771UA_VariableAttributes attr = UA_VariableAttributes_default;
75772attr.minimumSamplingInterval = 0.000000;
75773attr.userAccessLevel = 1;
75774attr.accessLevel = 1;
75775attr.valueRank = 1;
75776attr.arrayDimensionsSize = 1;
75777UA_UInt32 arrayDimensions[1];
75778arrayDimensions[0] = 0;
75779attr.arrayDimensions = &arrayDimensions[0];
75780attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
75781UA_Argument variablenode_ns_0_i_14433_variant_DataContents[1];
75782
75783UA_init(p: &variablenode_ns_0_i_14433_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75784variablenode_ns_0_i_14433_variant_DataContents[0].name = UA_STRING(chars: "ConnectionId");
75785variablenode_ns_0_i_14433_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
75786variablenode_ns_0_i_14433_variant_DataContents[0].valueRank = (UA_Int32) -1;
75787UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_14433_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
75788attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
75789retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75790requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14433LU),
75791parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14432LU),
75792referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
75793browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
75794typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
75795attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75796if (retVal != UA_STATUSCODE_GOOD) return retVal;
75797
75798return retVal;
75799#else
75800return UA_STATUSCODE_GOOD;
75801#endif /* UA_ENABLE_METHODCALLS */
75802}
75803
75804static UA_StatusCode function_namespace0_generated_264_finish(UA_Server *server, UA_UInt16* ns) {
75805#ifdef UA_ENABLE_METHODCALLS
75806return UA_Server_addNode_finish(server,
75807nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14433LU)
75808);
75809#else
75810return UA_STATUSCODE_GOOD;
75811#endif /* UA_ENABLE_METHODCALLS */
75812}
75813
75814/* <ConnectionName> - ns=0;i=14417 */
75815
75816static UA_StatusCode function_namespace0_generated_265_begin(UA_Server *server, UA_UInt16* ns) {
75817UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75818UA_ObjectAttributes attr = UA_ObjectAttributes_default;
75819attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "<ConnectionName>");
75820retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
75821requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14417LU),
75822parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14416LU),
75823referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14476LU),
75824browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "<ConnectionName>"),
75825typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14209LU),
75826attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
75827if (retVal != UA_STATUSCODE_GOOD) return retVal;
75828return retVal;
75829}
75830
75831static UA_StatusCode function_namespace0_generated_265_finish(UA_Server *server, UA_UInt16* ns) {
75832return UA_Server_addNode_finish(server,
75833nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14417LU)
75834);
75835}
75836
75837/* ConnectionProperties - ns=0;i=17478 */
75838
75839static UA_StatusCode function_namespace0_generated_266_begin(UA_Server *server, UA_UInt16* ns) {
75840UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75841UA_VariableAttributes attr = UA_VariableAttributes_default;
75842attr.minimumSamplingInterval = 0.000000;
75843attr.userAccessLevel = 1;
75844attr.accessLevel = 1;
75845attr.valueRank = 1;
75846attr.arrayDimensionsSize = 1;
75847UA_UInt32 arrayDimensions[1];
75848arrayDimensions[0] = 0;
75849attr.arrayDimensions = &arrayDimensions[0];
75850attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14533LU);
75851attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ConnectionProperties");
75852retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75853requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17478LU),
75854parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14417LU),
75855referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
75856browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ConnectionProperties"),
75857typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
75858attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75859if (retVal != UA_STATUSCODE_GOOD) return retVal;
75860return retVal;
75861}
75862
75863static UA_StatusCode function_namespace0_generated_266_finish(UA_Server *server, UA_UInt16* ns) {
75864return UA_Server_addNode_finish(server,
75865nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17478LU)
75866);
75867}
75868
75869/* TransportProfileUri - ns=0;i=17292 */
75870
75871static UA_StatusCode function_namespace0_generated_267_begin(UA_Server *server, UA_UInt16* ns) {
75872UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75873UA_VariableAttributes attr = UA_VariableAttributes_default;
75874attr.minimumSamplingInterval = 0.000000;
75875attr.userAccessLevel = 1;
75876attr.accessLevel = 1;
75877/* Value rank inherited */
75878attr.valueRank = -2;
75879attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
75880attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransportProfileUri");
75881retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75882requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17292LU),
75883parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14417LU),
75884referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
75885browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransportProfileUri"),
75886typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 16309LU),
75887attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75888if (retVal != UA_STATUSCODE_GOOD) return retVal;
75889return retVal;
75890}
75891
75892static UA_StatusCode function_namespace0_generated_267_finish(UA_Server *server, UA_UInt16* ns) {
75893return UA_Server_addNode_finish(server,
75894nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17292LU)
75895);
75896}
75897
75898/* Selections - ns=0;i=17706 */
75899
75900static UA_StatusCode function_namespace0_generated_268_begin(UA_Server *server, UA_UInt16* ns) {
75901UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75902UA_VariableAttributes attr = UA_VariableAttributes_default;
75903attr.minimumSamplingInterval = 0.000000;
75904attr.userAccessLevel = 1;
75905attr.accessLevel = 1;
75906attr.valueRank = 1;
75907attr.arrayDimensionsSize = 1;
75908UA_UInt32 arrayDimensions[1];
75909arrayDimensions[0] = 0;
75910attr.arrayDimensions = &arrayDimensions[0];
75911/* DataType inherited */
75912attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
75913attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Selections");
75914retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75915requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17706LU),
75916parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17292LU),
75917referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
75918browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Selections"),
75919typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
75920attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75921if (retVal != UA_STATUSCODE_GOOD) return retVal;
75922return retVal;
75923}
75924
75925static UA_StatusCode function_namespace0_generated_268_finish(UA_Server *server, UA_UInt16* ns) {
75926return UA_Server_addNode_finish(server,
75927nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17706LU)
75928);
75929}
75930
75931/* Address - ns=0;i=14423 */
75932
75933static UA_StatusCode function_namespace0_generated_269_begin(UA_Server *server, UA_UInt16* ns) {
75934UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75935UA_ObjectAttributes attr = UA_ObjectAttributes_default;
75936attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Address");
75937retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
75938requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14423LU),
75939parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14417LU),
75940referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
75941browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Address"),
75942typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21145LU),
75943attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
75944if (retVal != UA_STATUSCODE_GOOD) return retVal;
75945return retVal;
75946}
75947
75948static UA_StatusCode function_namespace0_generated_269_finish(UA_Server *server, UA_UInt16* ns) {
75949return UA_Server_addNode_finish(server,
75950nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14423LU)
75951);
75952}
75953
75954/* NetworkInterface - ns=0;i=15533 */
75955
75956static UA_StatusCode function_namespace0_generated_270_begin(UA_Server *server, UA_UInt16* ns) {
75957UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75958UA_VariableAttributes attr = UA_VariableAttributes_default;
75959attr.minimumSamplingInterval = 0.000000;
75960attr.userAccessLevel = 1;
75961attr.accessLevel = 1;
75962/* Value rank inherited */
75963attr.valueRank = -2;
75964attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
75965attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NetworkInterface");
75966retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75967requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15533LU),
75968parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14423LU),
75969referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
75970browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NetworkInterface"),
75971typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
75972attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
75973if (retVal != UA_STATUSCODE_GOOD) return retVal;
75974return retVal;
75975}
75976
75977static UA_StatusCode function_namespace0_generated_270_finish(UA_Server *server, UA_UInt16* ns) {
75978return UA_Server_addNode_finish(server,
75979nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15533LU)
75980);
75981}
75982
75983/* PublisherId - ns=0;i=14418 */
75984
75985static UA_StatusCode function_namespace0_generated_271_begin(UA_Server *server, UA_UInt16* ns) {
75986UA_StatusCode retVal = UA_STATUSCODE_GOOD;
75987UA_VariableAttributes attr = UA_VariableAttributes_default;
75988attr.minimumSamplingInterval = 0.000000;
75989attr.userAccessLevel = 1;
75990attr.accessLevel = 1;
75991/* Value rank inherited */
75992attr.valueRank = -2;
75993/* DataType inherited */
75994attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
75995attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublisherId");
75996retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
75997requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14418LU),
75998parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14417LU),
75999referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76000browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublisherId"),
76001typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76002attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76003if (retVal != UA_STATUSCODE_GOOD) return retVal;
76004return retVal;
76005}
76006
76007static UA_StatusCode function_namespace0_generated_271_finish(UA_Server *server, UA_UInt16* ns) {
76008return UA_Server_addNode_finish(server,
76009nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14418LU)
76010);
76011}
76012
76013/* HistoryServerCapabilitiesType - ns=0;i=2330 */
76014
76015static UA_StatusCode function_namespace0_generated_272_begin(UA_Server *server, UA_UInt16* ns) {
76016UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76017UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
76018attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HistoryServerCapabilitiesType");
76019retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
76020requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2330LU),
76021parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
76022referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
76023browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HistoryServerCapabilitiesType"),
76024 typeDefinition: UA_NODEID_NULL,
76025attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
76026if (retVal != UA_STATUSCODE_GOOD) return retVal;
76027return retVal;
76028}
76029
76030static UA_StatusCode function_namespace0_generated_272_finish(UA_Server *server, UA_UInt16* ns) {
76031return UA_Server_addNode_finish(server,
76032nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2330LU)
76033);
76034}
76035
76036/* ConditionType - ns=0;i=2782 */
76037
76038static UA_StatusCode function_namespace0_generated_273_begin(UA_Server *server, UA_UInt16* ns) {
76039UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76040UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
76041attr.isAbstract = true;
76042attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ConditionType");
76043retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
76044requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76045parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
76046referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
76047browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ConditionType"),
76048 typeDefinition: UA_NODEID_NULL,
76049attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
76050if (retVal != UA_STATUSCODE_GOOD) return retVal;
76051return retVal;
76052}
76053
76054static UA_StatusCode function_namespace0_generated_273_finish(UA_Server *server, UA_UInt16* ns) {
76055return UA_Server_addNode_finish(server,
76056nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU)
76057);
76058}
76059
76060/* AddComment - ns=0;i=9029 */
76061
76062static UA_StatusCode function_namespace0_generated_274_begin(UA_Server *server, UA_UInt16* ns) {
76063#ifdef UA_ENABLE_METHODCALLS
76064UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76065UA_MethodAttributes attr = UA_MethodAttributes_default;
76066attr.executable = true;
76067attr.userExecutable = true;
76068attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddComment");
76069retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
76070requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9029LU),
76071parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76072referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
76073browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddComment"),
76074 typeDefinition: UA_NODEID_NULL,
76075attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
76076if (retVal != UA_STATUSCODE_GOOD) return retVal;
76077return retVal;
76078#else
76079return UA_STATUSCODE_GOOD;
76080#endif /* UA_ENABLE_METHODCALLS */
76081}
76082
76083static UA_StatusCode function_namespace0_generated_274_finish(UA_Server *server, UA_UInt16* ns) {
76084#ifdef UA_ENABLE_METHODCALLS
76085return UA_Server_addMethodNode_finish(server,
76086nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9029LU)
76087, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
76088#else
76089return UA_STATUSCODE_GOOD;
76090#endif /* UA_ENABLE_METHODCALLS */
76091}
76092
76093/* InputArguments - ns=0;i=9030 */
76094
76095static UA_StatusCode function_namespace0_generated_275_begin(UA_Server *server, UA_UInt16* ns) {
76096#ifdef UA_ENABLE_METHODCALLS
76097UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76098UA_VariableAttributes attr = UA_VariableAttributes_default;
76099attr.minimumSamplingInterval = 0.000000;
76100attr.userAccessLevel = 1;
76101attr.accessLevel = 1;
76102attr.valueRank = 1;
76103attr.arrayDimensionsSize = 1;
76104UA_UInt32 arrayDimensions[1];
76105arrayDimensions[0] = 2;
76106attr.arrayDimensions = &arrayDimensions[0];
76107attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
76108UA_Argument variablenode_ns_0_i_9030_variant_DataContents[2];
76109
76110UA_init(p: &variablenode_ns_0_i_9030_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
76111variablenode_ns_0_i_9030_variant_DataContents[0].name = UA_STRING(chars: "EventId");
76112variablenode_ns_0_i_9030_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15LU);
76113variablenode_ns_0_i_9030_variant_DataContents[0].valueRank = (UA_Int32) -1;
76114variablenode_ns_0_i_9030_variant_DataContents[0].description = UA_LOCALIZEDTEXT(locale: "", text: "");
76115
76116UA_init(p: &variablenode_ns_0_i_9030_variant_DataContents[1], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
76117variablenode_ns_0_i_9030_variant_DataContents[1].name = UA_STRING(chars: "Comment");
76118variablenode_ns_0_i_9030_variant_DataContents[1].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
76119variablenode_ns_0_i_9030_variant_DataContents[1].valueRank = (UA_Int32) -1;
76120variablenode_ns_0_i_9030_variant_DataContents[1].description = UA_LOCALIZEDTEXT(locale: "", text: "");
76121UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_9030_variant_DataContents, arraySize: (UA_Int32) 2, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
76122attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
76123retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76124requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9030LU),
76125parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9029LU),
76126referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76127browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
76128typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76129attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76130if (retVal != UA_STATUSCODE_GOOD) return retVal;
76131
76132
76133return retVal;
76134#else
76135return UA_STATUSCODE_GOOD;
76136#endif /* UA_ENABLE_METHODCALLS */
76137}
76138
76139static UA_StatusCode function_namespace0_generated_275_finish(UA_Server *server, UA_UInt16* ns) {
76140#ifdef UA_ENABLE_METHODCALLS
76141return UA_Server_addNode_finish(server,
76142nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9030LU)
76143);
76144#else
76145return UA_STATUSCODE_GOOD;
76146#endif /* UA_ENABLE_METHODCALLS */
76147}
76148
76149/* Disable - ns=0;i=9028 */
76150
76151static UA_StatusCode function_namespace0_generated_276_begin(UA_Server *server, UA_UInt16* ns) {
76152#ifdef UA_ENABLE_METHODCALLS
76153UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76154UA_MethodAttributes attr = UA_MethodAttributes_default;
76155attr.executable = true;
76156attr.userExecutable = true;
76157attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Disable");
76158retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
76159requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9028LU),
76160parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76161referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
76162browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Disable"),
76163 typeDefinition: UA_NODEID_NULL,
76164attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
76165if (retVal != UA_STATUSCODE_GOOD) return retVal;
76166return retVal;
76167#else
76168return UA_STATUSCODE_GOOD;
76169#endif /* UA_ENABLE_METHODCALLS */
76170}
76171
76172static UA_StatusCode function_namespace0_generated_276_finish(UA_Server *server, UA_UInt16* ns) {
76173#ifdef UA_ENABLE_METHODCALLS
76174return UA_Server_addMethodNode_finish(server,
76175nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9028LU)
76176, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
76177#else
76178return UA_STATUSCODE_GOOD;
76179#endif /* UA_ENABLE_METHODCALLS */
76180}
76181
76182/* Enable - ns=0;i=9027 */
76183
76184static UA_StatusCode function_namespace0_generated_277_begin(UA_Server *server, UA_UInt16* ns) {
76185#ifdef UA_ENABLE_METHODCALLS
76186UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76187UA_MethodAttributes attr = UA_MethodAttributes_default;
76188attr.executable = true;
76189attr.userExecutable = true;
76190attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Enable");
76191retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
76192requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9027LU),
76193parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76194referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
76195browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Enable"),
76196 typeDefinition: UA_NODEID_NULL,
76197attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
76198if (retVal != UA_STATUSCODE_GOOD) return retVal;
76199return retVal;
76200#else
76201return UA_STATUSCODE_GOOD;
76202#endif /* UA_ENABLE_METHODCALLS */
76203}
76204
76205static UA_StatusCode function_namespace0_generated_277_finish(UA_Server *server, UA_UInt16* ns) {
76206#ifdef UA_ENABLE_METHODCALLS
76207return UA_Server_addMethodNode_finish(server,
76208nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9027LU)
76209, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
76210#else
76211return UA_STATUSCODE_GOOD;
76212#endif /* UA_ENABLE_METHODCALLS */
76213}
76214
76215/* ClientUserId - ns=0;i=9026 */
76216
76217static UA_StatusCode function_namespace0_generated_278_begin(UA_Server *server, UA_UInt16* ns) {
76218UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76219UA_VariableAttributes attr = UA_VariableAttributes_default;
76220attr.minimumSamplingInterval = 0.000000;
76221attr.userAccessLevel = 1;
76222attr.accessLevel = 1;
76223/* Value rank inherited */
76224attr.valueRank = -2;
76225attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
76226attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientUserId");
76227retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76228requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9026LU),
76229parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76230referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76231browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientUserId"),
76232typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76233attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76234if (retVal != UA_STATUSCODE_GOOD) return retVal;
76235return retVal;
76236}
76237
76238static UA_StatusCode function_namespace0_generated_278_finish(UA_Server *server, UA_UInt16* ns) {
76239return UA_Server_addNode_finish(server,
76240nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9026LU)
76241);
76242}
76243
76244/* BranchId - ns=0;i=9010 */
76245
76246static UA_StatusCode function_namespace0_generated_279_begin(UA_Server *server, UA_UInt16* ns) {
76247UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76248UA_VariableAttributes attr = UA_VariableAttributes_default;
76249attr.minimumSamplingInterval = 0.000000;
76250attr.userAccessLevel = 1;
76251attr.accessLevel = 1;
76252/* Value rank inherited */
76253attr.valueRank = -2;
76254attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
76255attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BranchId");
76256retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76257requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9010LU),
76258parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76259referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76260browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BranchId"),
76261typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76262attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76263if (retVal != UA_STATUSCODE_GOOD) return retVal;
76264return retVal;
76265}
76266
76267static UA_StatusCode function_namespace0_generated_279_finish(UA_Server *server, UA_UInt16* ns) {
76268return UA_Server_addNode_finish(server,
76269nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9010LU)
76270);
76271}
76272
76273/* ConditionName - ns=0;i=9009 */
76274
76275static UA_StatusCode function_namespace0_generated_280_begin(UA_Server *server, UA_UInt16* ns) {
76276UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76277UA_VariableAttributes attr = UA_VariableAttributes_default;
76278attr.minimumSamplingInterval = 0.000000;
76279attr.userAccessLevel = 1;
76280attr.accessLevel = 1;
76281/* Value rank inherited */
76282attr.valueRank = -2;
76283attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
76284attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ConditionName");
76285retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76286requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9009LU),
76287parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76288referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76289browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ConditionName"),
76290typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76291attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76292if (retVal != UA_STATUSCODE_GOOD) return retVal;
76293return retVal;
76294}
76295
76296static UA_StatusCode function_namespace0_generated_280_finish(UA_Server *server, UA_UInt16* ns) {
76297return UA_Server_addNode_finish(server,
76298nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9009LU)
76299);
76300}
76301
76302/* ConditionRefresh - ns=0;i=3875 */
76303
76304static UA_StatusCode function_namespace0_generated_281_begin(UA_Server *server, UA_UInt16* ns) {
76305#ifdef UA_ENABLE_METHODCALLS
76306UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76307UA_MethodAttributes attr = UA_MethodAttributes_default;
76308attr.executable = true;
76309attr.userExecutable = true;
76310attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ConditionRefresh");
76311retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
76312requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3875LU),
76313parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76314referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
76315browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ConditionRefresh"),
76316 typeDefinition: UA_NODEID_NULL,
76317attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
76318if (retVal != UA_STATUSCODE_GOOD) return retVal;
76319return retVal;
76320#else
76321return UA_STATUSCODE_GOOD;
76322#endif /* UA_ENABLE_METHODCALLS */
76323}
76324
76325static UA_StatusCode function_namespace0_generated_281_finish(UA_Server *server, UA_UInt16* ns) {
76326#ifdef UA_ENABLE_METHODCALLS
76327return UA_Server_addMethodNode_finish(server,
76328nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3875LU)
76329, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
76330#else
76331return UA_STATUSCODE_GOOD;
76332#endif /* UA_ENABLE_METHODCALLS */
76333}
76334
76335/* InputArguments - ns=0;i=3876 */
76336
76337static UA_StatusCode function_namespace0_generated_282_begin(UA_Server *server, UA_UInt16* ns) {
76338#ifdef UA_ENABLE_METHODCALLS
76339UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76340UA_VariableAttributes attr = UA_VariableAttributes_default;
76341attr.minimumSamplingInterval = 0.000000;
76342attr.userAccessLevel = 1;
76343attr.accessLevel = 1;
76344attr.valueRank = 1;
76345attr.arrayDimensionsSize = 1;
76346UA_UInt32 arrayDimensions[1];
76347arrayDimensions[0] = 1;
76348attr.arrayDimensions = &arrayDimensions[0];
76349attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
76350UA_Argument variablenode_ns_0_i_3876_variant_DataContents[1];
76351
76352UA_init(p: &variablenode_ns_0_i_3876_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
76353variablenode_ns_0_i_3876_variant_DataContents[0].name = UA_STRING(chars: "SubscriptionId");
76354variablenode_ns_0_i_3876_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 288LU);
76355variablenode_ns_0_i_3876_variant_DataContents[0].valueRank = (UA_Int32) -1;
76356variablenode_ns_0_i_3876_variant_DataContents[0].description = UA_LOCALIZEDTEXT(locale: "", text: "");
76357UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_3876_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
76358attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
76359retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76360requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3876LU),
76361parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3875LU),
76362referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76363browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
76364typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76365attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76366if (retVal != UA_STATUSCODE_GOOD) return retVal;
76367
76368return retVal;
76369#else
76370return UA_STATUSCODE_GOOD;
76371#endif /* UA_ENABLE_METHODCALLS */
76372}
76373
76374static UA_StatusCode function_namespace0_generated_282_finish(UA_Server *server, UA_UInt16* ns) {
76375#ifdef UA_ENABLE_METHODCALLS
76376return UA_Server_addNode_finish(server,
76377nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3876LU)
76378);
76379#else
76380return UA_STATUSCODE_GOOD;
76381#endif /* UA_ENABLE_METHODCALLS */
76382}
76383
76384/* Retain - ns=0;i=3874 */
76385
76386static UA_StatusCode function_namespace0_generated_283_begin(UA_Server *server, UA_UInt16* ns) {
76387UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76388UA_VariableAttributes attr = UA_VariableAttributes_default;
76389attr.minimumSamplingInterval = 0.000000;
76390attr.userAccessLevel = 1;
76391attr.accessLevel = 1;
76392/* Value rank inherited */
76393attr.valueRank = -2;
76394attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
76395attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Retain");
76396retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76397requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3874LU),
76398parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76399referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76400browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Retain"),
76401typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76402attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76403if (retVal != UA_STATUSCODE_GOOD) return retVal;
76404return retVal;
76405}
76406
76407static UA_StatusCode function_namespace0_generated_283_finish(UA_Server *server, UA_UInt16* ns) {
76408return UA_Server_addNode_finish(server,
76409nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3874LU)
76410);
76411}
76412
76413/* SupportsFilteredRetain - ns=0;i=32060 */
76414
76415static UA_StatusCode function_namespace0_generated_284_begin(UA_Server *server, UA_UInt16* ns) {
76416UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76417UA_VariableAttributes attr = UA_VariableAttributes_default;
76418attr.minimumSamplingInterval = 0.000000;
76419attr.userAccessLevel = 1;
76420attr.accessLevel = 1;
76421/* Value rank inherited */
76422attr.valueRank = -2;
76423attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
76424attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SupportsFilteredRetain");
76425retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76426requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 32060LU),
76427parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76428referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76429browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SupportsFilteredRetain"),
76430typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76431attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76432if (retVal != UA_STATUSCODE_GOOD) return retVal;
76433return retVal;
76434}
76435
76436static UA_StatusCode function_namespace0_generated_284_finish(UA_Server *server, UA_UInt16* ns) {
76437return UA_Server_addNode_finish(server,
76438nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 32060LU)
76439);
76440}
76441
76442/* ConditionRefresh2 - ns=0;i=12912 */
76443
76444static UA_StatusCode function_namespace0_generated_285_begin(UA_Server *server, UA_UInt16* ns) {
76445#ifdef UA_ENABLE_METHODCALLS
76446UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76447UA_MethodAttributes attr = UA_MethodAttributes_default;
76448attr.executable = true;
76449attr.userExecutable = true;
76450attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ConditionRefresh2");
76451retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
76452requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12912LU),
76453parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76454referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
76455browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ConditionRefresh2"),
76456 typeDefinition: UA_NODEID_NULL,
76457attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
76458if (retVal != UA_STATUSCODE_GOOD) return retVal;
76459return retVal;
76460#else
76461return UA_STATUSCODE_GOOD;
76462#endif /* UA_ENABLE_METHODCALLS */
76463}
76464
76465static UA_StatusCode function_namespace0_generated_285_finish(UA_Server *server, UA_UInt16* ns) {
76466#ifdef UA_ENABLE_METHODCALLS
76467return UA_Server_addMethodNode_finish(server,
76468nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12912LU)
76469, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
76470#else
76471return UA_STATUSCODE_GOOD;
76472#endif /* UA_ENABLE_METHODCALLS */
76473}
76474
76475/* InputArguments - ns=0;i=12913 */
76476
76477static UA_StatusCode function_namespace0_generated_286_begin(UA_Server *server, UA_UInt16* ns) {
76478#ifdef UA_ENABLE_METHODCALLS
76479UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76480UA_VariableAttributes attr = UA_VariableAttributes_default;
76481attr.minimumSamplingInterval = 0.000000;
76482attr.userAccessLevel = 1;
76483attr.accessLevel = 1;
76484attr.valueRank = 1;
76485attr.arrayDimensionsSize = 1;
76486UA_UInt32 arrayDimensions[1];
76487arrayDimensions[0] = 2;
76488attr.arrayDimensions = &arrayDimensions[0];
76489attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
76490UA_Argument variablenode_ns_0_i_12913_variant_DataContents[2];
76491
76492UA_init(p: &variablenode_ns_0_i_12913_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
76493variablenode_ns_0_i_12913_variant_DataContents[0].name = UA_STRING(chars: "SubscriptionId");
76494variablenode_ns_0_i_12913_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 288LU);
76495variablenode_ns_0_i_12913_variant_DataContents[0].valueRank = (UA_Int32) -1;
76496variablenode_ns_0_i_12913_variant_DataContents[0].description = UA_LOCALIZEDTEXT(locale: "", text: "");
76497
76498UA_init(p: &variablenode_ns_0_i_12913_variant_DataContents[1], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
76499variablenode_ns_0_i_12913_variant_DataContents[1].name = UA_STRING(chars: "MonitoredItemId");
76500variablenode_ns_0_i_12913_variant_DataContents[1].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 288LU);
76501variablenode_ns_0_i_12913_variant_DataContents[1].valueRank = (UA_Int32) -1;
76502variablenode_ns_0_i_12913_variant_DataContents[1].description = UA_LOCALIZEDTEXT(locale: "", text: "");
76503UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_12913_variant_DataContents, arraySize: (UA_Int32) 2, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
76504attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
76505retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76506requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12913LU),
76507parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12912LU),
76508referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76509browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
76510typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76511attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76512if (retVal != UA_STATUSCODE_GOOD) return retVal;
76513
76514
76515return retVal;
76516#else
76517return UA_STATUSCODE_GOOD;
76518#endif /* UA_ENABLE_METHODCALLS */
76519}
76520
76521static UA_StatusCode function_namespace0_generated_286_finish(UA_Server *server, UA_UInt16* ns) {
76522#ifdef UA_ENABLE_METHODCALLS
76523return UA_Server_addNode_finish(server,
76524nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12913LU)
76525);
76526#else
76527return UA_STATUSCODE_GOOD;
76528#endif /* UA_ENABLE_METHODCALLS */
76529}
76530
76531/* ConditionClassName - ns=0;i=11113 */
76532
76533static UA_StatusCode function_namespace0_generated_287_begin(UA_Server *server, UA_UInt16* ns) {
76534UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76535UA_VariableAttributes attr = UA_VariableAttributes_default;
76536attr.minimumSamplingInterval = 0.000000;
76537attr.userAccessLevel = 1;
76538attr.accessLevel = 1;
76539/* Value rank inherited */
76540attr.valueRank = -2;
76541attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
76542attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ConditionClassName");
76543retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76544requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11113LU),
76545parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76546referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76547browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ConditionClassName"),
76548typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76549attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76550if (retVal != UA_STATUSCODE_GOOD) return retVal;
76551return retVal;
76552}
76553
76554static UA_StatusCode function_namespace0_generated_287_finish(UA_Server *server, UA_UInt16* ns) {
76555return UA_Server_addNode_finish(server,
76556nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11113LU)
76557);
76558}
76559
76560/* ConditionClassId - ns=0;i=11112 */
76561
76562static UA_StatusCode function_namespace0_generated_288_begin(UA_Server *server, UA_UInt16* ns) {
76563UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76564UA_VariableAttributes attr = UA_VariableAttributes_default;
76565attr.minimumSamplingInterval = 0.000000;
76566attr.userAccessLevel = 1;
76567attr.accessLevel = 1;
76568/* Value rank inherited */
76569attr.valueRank = -2;
76570attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
76571attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ConditionClassId");
76572retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76573requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11112LU),
76574parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76575referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76576browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ConditionClassId"),
76577typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76578attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76579if (retVal != UA_STATUSCODE_GOOD) return retVal;
76580return retVal;
76581}
76582
76583static UA_StatusCode function_namespace0_generated_288_finish(UA_Server *server, UA_UInt16* ns) {
76584return UA_Server_addNode_finish(server,
76585nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11112LU)
76586);
76587}
76588
76589/* StateVariableType - ns=0;i=2755 */
76590
76591static UA_StatusCode function_namespace0_generated_289_begin(UA_Server *server, UA_UInt16* ns) {
76592UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76593UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
76594/* Value rank inherited */
76595attr.valueRank = -2;
76596attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
76597attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "StateVariableType");
76598retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
76599requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2755LU),
76600parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
76601referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
76602browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "StateVariableType"),
76603typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
76604attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
76605if (retVal != UA_STATUSCODE_GOOD) return retVal;
76606return retVal;
76607}
76608
76609static UA_StatusCode function_namespace0_generated_289_finish(UA_Server *server, UA_UInt16* ns) {
76610return UA_Server_addNode_finish(server,
76611nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2755LU)
76612);
76613}
76614
76615/* TwoStateVariableType - ns=0;i=8995 */
76616
76617static UA_StatusCode function_namespace0_generated_290_begin(UA_Server *server, UA_UInt16* ns) {
76618UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76619UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
76620/* Value rank inherited */
76621attr.valueRank = -2;
76622attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
76623attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TwoStateVariableType");
76624retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
76625requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8995LU),
76626parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2755LU),
76627referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
76628browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TwoStateVariableType"),
76629typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
76630attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
76631if (retVal != UA_STATUSCODE_GOOD) return retVal;
76632return retVal;
76633}
76634
76635static UA_StatusCode function_namespace0_generated_290_finish(UA_Server *server, UA_UInt16* ns) {
76636return UA_Server_addNode_finish(server,
76637nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8995LU)
76638);
76639}
76640
76641/* EnabledState - ns=0;i=9011 */
76642
76643static UA_StatusCode function_namespace0_generated_291_begin(UA_Server *server, UA_UInt16* ns) {
76644UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76645UA_VariableAttributes attr = UA_VariableAttributes_default;
76646attr.minimumSamplingInterval = 0.000000;
76647attr.userAccessLevel = 1;
76648attr.accessLevel = 1;
76649/* Value rank inherited */
76650attr.valueRank = -2;
76651attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
76652attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnabledState");
76653retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76654requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9011LU),
76655parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
76656referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
76657browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnabledState"),
76658typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8995LU),
76659attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76660if (retVal != UA_STATUSCODE_GOOD) return retVal;
76661return retVal;
76662}
76663
76664static UA_StatusCode function_namespace0_generated_291_finish(UA_Server *server, UA_UInt16* ns) {
76665return UA_Server_addNode_finish(server,
76666nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9011LU)
76667);
76668}
76669
76670/* FalseState - ns=0;i=9019 */
76671
76672static UA_StatusCode function_namespace0_generated_292_begin(UA_Server *server, UA_UInt16* ns) {
76673UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76674UA_VariableAttributes attr = UA_VariableAttributes_default;
76675attr.minimumSamplingInterval = 0.000000;
76676attr.userAccessLevel = 1;
76677attr.accessLevel = 1;
76678/* Value rank inherited */
76679attr.valueRank = -2;
76680attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
76681UA_LocalizedText *variablenode_ns_0_i_9019_variant_DataContents = UA_LocalizedText_new();
76682if (!variablenode_ns_0_i_9019_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY;
76683UA_LocalizedText_init(p: variablenode_ns_0_i_9019_variant_DataContents);
76684*variablenode_ns_0_i_9019_variant_DataContents = UA_LOCALIZEDTEXT_ALLOC(locale: "en", text: "");
76685UA_Variant_setScalar(v: &attr.value, p: variablenode_ns_0_i_9019_variant_DataContents, type: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
76686attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "FalseState");
76687retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76688requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9019LU),
76689parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9011LU),
76690referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76691browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "FalseState"),
76692typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76693attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76694if (retVal != UA_STATUSCODE_GOOD) return retVal;
76695UA_LocalizedText_delete(p: variablenode_ns_0_i_9019_variant_DataContents);
76696return retVal;
76697}
76698
76699static UA_StatusCode function_namespace0_generated_292_finish(UA_Server *server, UA_UInt16* ns) {
76700return UA_Server_addNode_finish(server,
76701nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9019LU)
76702);
76703}
76704
76705/* TrueState - ns=0;i=9018 */
76706
76707static UA_StatusCode function_namespace0_generated_293_begin(UA_Server *server, UA_UInt16* ns) {
76708UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76709UA_VariableAttributes attr = UA_VariableAttributes_default;
76710attr.minimumSamplingInterval = 0.000000;
76711attr.userAccessLevel = 1;
76712attr.accessLevel = 1;
76713/* Value rank inherited */
76714attr.valueRank = -2;
76715attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
76716UA_LocalizedText *variablenode_ns_0_i_9018_variant_DataContents = UA_LocalizedText_new();
76717if (!variablenode_ns_0_i_9018_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY;
76718UA_LocalizedText_init(p: variablenode_ns_0_i_9018_variant_DataContents);
76719*variablenode_ns_0_i_9018_variant_DataContents = UA_LOCALIZEDTEXT_ALLOC(locale: "en", text: "");
76720UA_Variant_setScalar(v: &attr.value, p: variablenode_ns_0_i_9018_variant_DataContents, type: &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
76721attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TrueState");
76722retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76723requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9018LU),
76724parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9011LU),
76725referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76726browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TrueState"),
76727typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76728attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76729if (retVal != UA_STATUSCODE_GOOD) return retVal;
76730UA_LocalizedText_delete(p: variablenode_ns_0_i_9018_variant_DataContents);
76731return retVal;
76732}
76733
76734static UA_StatusCode function_namespace0_generated_293_finish(UA_Server *server, UA_UInt16* ns) {
76735return UA_Server_addNode_finish(server,
76736nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9018LU)
76737);
76738}
76739
76740/* EffectiveTransitionTime - ns=0;i=9017 */
76741
76742static UA_StatusCode function_namespace0_generated_294_begin(UA_Server *server, UA_UInt16* ns) {
76743UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76744UA_VariableAttributes attr = UA_VariableAttributes_default;
76745attr.minimumSamplingInterval = 0.000000;
76746attr.userAccessLevel = 1;
76747attr.accessLevel = 1;
76748/* Value rank inherited */
76749attr.valueRank = -2;
76750attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
76751attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EffectiveTransitionTime");
76752retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76753requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9017LU),
76754parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9011LU),
76755referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76756browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EffectiveTransitionTime"),
76757typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76758attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76759if (retVal != UA_STATUSCODE_GOOD) return retVal;
76760return retVal;
76761}
76762
76763static UA_StatusCode function_namespace0_generated_294_finish(UA_Server *server, UA_UInt16* ns) {
76764return UA_Server_addNode_finish(server,
76765nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9017LU)
76766);
76767}
76768
76769/* TransitionTime - ns=0;i=9016 */
76770
76771static UA_StatusCode function_namespace0_generated_295_begin(UA_Server *server, UA_UInt16* ns) {
76772UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76773UA_VariableAttributes attr = UA_VariableAttributes_default;
76774attr.minimumSamplingInterval = 0.000000;
76775attr.userAccessLevel = 1;
76776attr.accessLevel = 1;
76777/* Value rank inherited */
76778attr.valueRank = -2;
76779attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
76780attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransitionTime");
76781retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76782requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9016LU),
76783parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9011LU),
76784referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76785browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransitionTime"),
76786typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76787attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76788if (retVal != UA_STATUSCODE_GOOD) return retVal;
76789return retVal;
76790}
76791
76792static UA_StatusCode function_namespace0_generated_295_finish(UA_Server *server, UA_UInt16* ns) {
76793return UA_Server_addNode_finish(server,
76794nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9016LU)
76795);
76796}
76797
76798/* EffectiveDisplayName - ns=0;i=9015 */
76799
76800static UA_StatusCode function_namespace0_generated_296_begin(UA_Server *server, UA_UInt16* ns) {
76801UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76802UA_VariableAttributes attr = UA_VariableAttributes_default;
76803attr.minimumSamplingInterval = 0.000000;
76804attr.userAccessLevel = 1;
76805attr.accessLevel = 1;
76806/* Value rank inherited */
76807attr.valueRank = -2;
76808attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
76809attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EffectiveDisplayName");
76810retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76811requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9015LU),
76812parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9011LU),
76813referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76814browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EffectiveDisplayName"),
76815typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76816attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76817if (retVal != UA_STATUSCODE_GOOD) return retVal;
76818return retVal;
76819}
76820
76821static UA_StatusCode function_namespace0_generated_296_finish(UA_Server *server, UA_UInt16* ns) {
76822return UA_Server_addNode_finish(server,
76823nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9015LU)
76824);
76825}
76826
76827/* Id - ns=0;i=9012 */
76828
76829static UA_StatusCode function_namespace0_generated_297_begin(UA_Server *server, UA_UInt16* ns) {
76830UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76831UA_VariableAttributes attr = UA_VariableAttributes_default;
76832attr.minimumSamplingInterval = 0.000000;
76833attr.userAccessLevel = 1;
76834attr.accessLevel = 1;
76835/* Value rank inherited */
76836attr.valueRank = -2;
76837attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
76838attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Id");
76839retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76840requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9012LU),
76841parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9011LU),
76842referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76843browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Id"),
76844typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76845attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76846if (retVal != UA_STATUSCODE_GOOD) return retVal;
76847return retVal;
76848}
76849
76850static UA_StatusCode function_namespace0_generated_297_finish(UA_Server *server, UA_UInt16* ns) {
76851return UA_Server_addNode_finish(server,
76852nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9012LU)
76853);
76854}
76855
76856/* EffectiveTransitionTime - ns=0;i=9001 */
76857
76858static UA_StatusCode function_namespace0_generated_298_begin(UA_Server *server, UA_UInt16* ns) {
76859UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76860UA_VariableAttributes attr = UA_VariableAttributes_default;
76861attr.minimumSamplingInterval = 0.000000;
76862attr.userAccessLevel = 1;
76863attr.accessLevel = 1;
76864/* Value rank inherited */
76865attr.valueRank = -2;
76866attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
76867attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EffectiveTransitionTime");
76868retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76869requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9001LU),
76870parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8995LU),
76871referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76872browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EffectiveTransitionTime"),
76873typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76874attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76875if (retVal != UA_STATUSCODE_GOOD) return retVal;
76876return retVal;
76877}
76878
76879static UA_StatusCode function_namespace0_generated_298_finish(UA_Server *server, UA_UInt16* ns) {
76880return UA_Server_addNode_finish(server,
76881nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9001LU)
76882);
76883}
76884
76885/* TransitionTime - ns=0;i=9000 */
76886
76887static UA_StatusCode function_namespace0_generated_299_begin(UA_Server *server, UA_UInt16* ns) {
76888UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76889UA_VariableAttributes attr = UA_VariableAttributes_default;
76890attr.minimumSamplingInterval = 0.000000;
76891attr.userAccessLevel = 1;
76892attr.accessLevel = 1;
76893/* Value rank inherited */
76894attr.valueRank = -2;
76895attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
76896attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransitionTime");
76897retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76898requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9000LU),
76899parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8995LU),
76900referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76901browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransitionTime"),
76902typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76903attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76904if (retVal != UA_STATUSCODE_GOOD) return retVal;
76905return retVal;
76906}
76907
76908static UA_StatusCode function_namespace0_generated_299_finish(UA_Server *server, UA_UInt16* ns) {
76909return UA_Server_addNode_finish(server,
76910nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9000LU)
76911);
76912}
76913
76914/* Id - ns=0;i=8996 */
76915
76916static UA_StatusCode function_namespace0_generated_300_begin(UA_Server *server, UA_UInt16* ns) {
76917UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76918UA_VariableAttributes attr = UA_VariableAttributes_default;
76919attr.minimumSamplingInterval = 0.000000;
76920attr.userAccessLevel = 1;
76921attr.accessLevel = 1;
76922/* Value rank inherited */
76923attr.valueRank = -2;
76924attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
76925attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Id");
76926retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76927requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8996LU),
76928parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8995LU),
76929referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76930browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Id"),
76931typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76932attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76933if (retVal != UA_STATUSCODE_GOOD) return retVal;
76934return retVal;
76935}
76936
76937static UA_StatusCode function_namespace0_generated_300_finish(UA_Server *server, UA_UInt16* ns) {
76938return UA_Server_addNode_finish(server,
76939nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8996LU)
76940);
76941}
76942
76943/* FalseState - ns=0;i=11111 */
76944
76945static UA_StatusCode function_namespace0_generated_301_begin(UA_Server *server, UA_UInt16* ns) {
76946UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76947UA_VariableAttributes attr = UA_VariableAttributes_default;
76948attr.minimumSamplingInterval = 0.000000;
76949attr.userAccessLevel = 1;
76950attr.accessLevel = 1;
76951/* Value rank inherited */
76952attr.valueRank = -2;
76953attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
76954attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "FalseState");
76955retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76956requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11111LU),
76957parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8995LU),
76958referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76959browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "FalseState"),
76960typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76961attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76962if (retVal != UA_STATUSCODE_GOOD) return retVal;
76963return retVal;
76964}
76965
76966static UA_StatusCode function_namespace0_generated_301_finish(UA_Server *server, UA_UInt16* ns) {
76967return UA_Server_addNode_finish(server,
76968nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11111LU)
76969);
76970}
76971
76972/* TrueState - ns=0;i=11110 */
76973
76974static UA_StatusCode function_namespace0_generated_302_begin(UA_Server *server, UA_UInt16* ns) {
76975UA_StatusCode retVal = UA_STATUSCODE_GOOD;
76976UA_VariableAttributes attr = UA_VariableAttributes_default;
76977attr.minimumSamplingInterval = 0.000000;
76978attr.userAccessLevel = 1;
76979attr.accessLevel = 1;
76980/* Value rank inherited */
76981attr.valueRank = -2;
76982attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
76983attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TrueState");
76984retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
76985requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11110LU),
76986parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8995LU),
76987referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
76988browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TrueState"),
76989typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
76990attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
76991if (retVal != UA_STATUSCODE_GOOD) return retVal;
76992return retVal;
76993}
76994
76995static UA_StatusCode function_namespace0_generated_302_finish(UA_Server *server, UA_UInt16* ns) {
76996return UA_Server_addNode_finish(server,
76997nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11110LU)
76998);
76999}
77000
77001/* EffectiveDisplayName - ns=0;i=2759 */
77002
77003static UA_StatusCode function_namespace0_generated_303_begin(UA_Server *server, UA_UInt16* ns) {
77004UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77005UA_VariableAttributes attr = UA_VariableAttributes_default;
77006attr.minimumSamplingInterval = 0.000000;
77007attr.userAccessLevel = 1;
77008attr.accessLevel = 1;
77009/* Value rank inherited */
77010attr.valueRank = -2;
77011attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
77012attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EffectiveDisplayName");
77013retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77014requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2759LU),
77015parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2755LU),
77016referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77017browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EffectiveDisplayName"),
77018typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77019attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77020if (retVal != UA_STATUSCODE_GOOD) return retVal;
77021return retVal;
77022}
77023
77024static UA_StatusCode function_namespace0_generated_303_finish(UA_Server *server, UA_UInt16* ns) {
77025return UA_Server_addNode_finish(server,
77026nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2759LU)
77027);
77028}
77029
77030/* Number - ns=0;i=2758 */
77031
77032static UA_StatusCode function_namespace0_generated_304_begin(UA_Server *server, UA_UInt16* ns) {
77033UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77034UA_VariableAttributes attr = UA_VariableAttributes_default;
77035attr.minimumSamplingInterval = 0.000000;
77036attr.userAccessLevel = 1;
77037attr.accessLevel = 1;
77038/* Value rank inherited */
77039attr.valueRank = -2;
77040attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
77041attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Number");
77042retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77043requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2758LU),
77044parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2755LU),
77045referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77046browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Number"),
77047typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77048attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77049if (retVal != UA_STATUSCODE_GOOD) return retVal;
77050return retVal;
77051}
77052
77053static UA_StatusCode function_namespace0_generated_304_finish(UA_Server *server, UA_UInt16* ns) {
77054return UA_Server_addNode_finish(server,
77055nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2758LU)
77056);
77057}
77058
77059/* Name - ns=0;i=2757 */
77060
77061static UA_StatusCode function_namespace0_generated_305_begin(UA_Server *server, UA_UInt16* ns) {
77062UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77063UA_VariableAttributes attr = UA_VariableAttributes_default;
77064attr.minimumSamplingInterval = 0.000000;
77065attr.userAccessLevel = 1;
77066attr.accessLevel = 1;
77067/* Value rank inherited */
77068attr.valueRank = -2;
77069attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 20LU);
77070attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Name");
77071retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77072requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2757LU),
77073parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2755LU),
77074referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77075browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Name"),
77076typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77077attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77078if (retVal != UA_STATUSCODE_GOOD) return retVal;
77079return retVal;
77080}
77081
77082static UA_StatusCode function_namespace0_generated_305_finish(UA_Server *server, UA_UInt16* ns) {
77083return UA_Server_addNode_finish(server,
77084nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2757LU)
77085);
77086}
77087
77088/* Id - ns=0;i=2756 */
77089
77090static UA_StatusCode function_namespace0_generated_306_begin(UA_Server *server, UA_UInt16* ns) {
77091UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77092UA_VariableAttributes attr = UA_VariableAttributes_default;
77093attr.minimumSamplingInterval = 0.000000;
77094attr.userAccessLevel = 1;
77095attr.accessLevel = 1;
77096/* Value rank inherited */
77097attr.valueRank = -2;
77098/* DataType inherited */
77099attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
77100attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Id");
77101retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77102requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2756LU),
77103parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2755LU),
77104referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77105browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Id"),
77106typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77107attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77108if (retVal != UA_STATUSCODE_GOOD) return retVal;
77109return retVal;
77110}
77111
77112static UA_StatusCode function_namespace0_generated_306_finish(UA_Server *server, UA_UInt16* ns) {
77113return UA_Server_addNode_finish(server,
77114nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2756LU)
77115);
77116}
77117
77118/* ConditionVariableType - ns=0;i=9002 */
77119
77120static UA_StatusCode function_namespace0_generated_307_begin(UA_Server *server, UA_UInt16* ns) {
77121UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77122UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
77123attr.valueRank = -2;
77124/* DataType inherited */
77125attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
77126attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ConditionVariableType");
77127retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
77128requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9002LU),
77129parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
77130referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
77131browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ConditionVariableType"),
77132typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
77133attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
77134if (retVal != UA_STATUSCODE_GOOD) return retVal;
77135return retVal;
77136}
77137
77138static UA_StatusCode function_namespace0_generated_307_finish(UA_Server *server, UA_UInt16* ns) {
77139return UA_Server_addNode_finish(server,
77140nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9002LU)
77141);
77142}
77143
77144/* Comment - ns=0;i=9024 */
77145
77146static UA_StatusCode function_namespace0_generated_308_begin(UA_Server *server, UA_UInt16* ns) {
77147UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77148UA_VariableAttributes attr = UA_VariableAttributes_default;
77149attr.minimumSamplingInterval = 0.000000;
77150attr.userAccessLevel = 1;
77151attr.accessLevel = 1;
77152/* Value rank inherited */
77153attr.valueRank = -2;
77154attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
77155attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Comment");
77156retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77157requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9024LU),
77158parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
77159referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
77160browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Comment"),
77161typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9002LU),
77162attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77163if (retVal != UA_STATUSCODE_GOOD) return retVal;
77164return retVal;
77165}
77166
77167static UA_StatusCode function_namespace0_generated_308_finish(UA_Server *server, UA_UInt16* ns) {
77168return UA_Server_addNode_finish(server,
77169nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9024LU)
77170);
77171}
77172
77173/* SourceTimestamp - ns=0;i=9025 */
77174
77175static UA_StatusCode function_namespace0_generated_309_begin(UA_Server *server, UA_UInt16* ns) {
77176UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77177UA_VariableAttributes attr = UA_VariableAttributes_default;
77178attr.minimumSamplingInterval = 0.000000;
77179attr.userAccessLevel = 1;
77180attr.accessLevel = 1;
77181/* Value rank inherited */
77182attr.valueRank = -2;
77183attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
77184attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SourceTimestamp");
77185retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77186requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9025LU),
77187parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9024LU),
77188referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77189browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SourceTimestamp"),
77190typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77191attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77192if (retVal != UA_STATUSCODE_GOOD) return retVal;
77193return retVal;
77194}
77195
77196static UA_StatusCode function_namespace0_generated_309_finish(UA_Server *server, UA_UInt16* ns) {
77197return UA_Server_addNode_finish(server,
77198nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9025LU)
77199);
77200}
77201
77202/* LastSeverity - ns=0;i=9022 */
77203
77204static UA_StatusCode function_namespace0_generated_310_begin(UA_Server *server, UA_UInt16* ns) {
77205UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77206UA_VariableAttributes attr = UA_VariableAttributes_default;
77207attr.minimumSamplingInterval = 0.000000;
77208attr.userAccessLevel = 1;
77209attr.accessLevel = 1;
77210/* Value rank inherited */
77211attr.valueRank = -2;
77212attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
77213attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "LastSeverity");
77214retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77215requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9022LU),
77216parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
77217referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
77218browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "LastSeverity"),
77219typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9002LU),
77220attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77221if (retVal != UA_STATUSCODE_GOOD) return retVal;
77222return retVal;
77223}
77224
77225static UA_StatusCode function_namespace0_generated_310_finish(UA_Server *server, UA_UInt16* ns) {
77226return UA_Server_addNode_finish(server,
77227nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9022LU)
77228);
77229}
77230
77231/* SourceTimestamp - ns=0;i=9023 */
77232
77233static UA_StatusCode function_namespace0_generated_311_begin(UA_Server *server, UA_UInt16* ns) {
77234UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77235UA_VariableAttributes attr = UA_VariableAttributes_default;
77236attr.minimumSamplingInterval = 0.000000;
77237attr.userAccessLevel = 1;
77238attr.accessLevel = 1;
77239/* Value rank inherited */
77240attr.valueRank = -2;
77241attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
77242attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SourceTimestamp");
77243retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77244requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9023LU),
77245parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9022LU),
77246referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77247browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SourceTimestamp"),
77248typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77249attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77250if (retVal != UA_STATUSCODE_GOOD) return retVal;
77251return retVal;
77252}
77253
77254static UA_StatusCode function_namespace0_generated_311_finish(UA_Server *server, UA_UInt16* ns) {
77255return UA_Server_addNode_finish(server,
77256nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9023LU)
77257);
77258}
77259
77260/* Quality - ns=0;i=9020 */
77261
77262static UA_StatusCode function_namespace0_generated_312_begin(UA_Server *server, UA_UInt16* ns) {
77263UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77264UA_VariableAttributes attr = UA_VariableAttributes_default;
77265attr.minimumSamplingInterval = 0.000000;
77266attr.userAccessLevel = 1;
77267attr.accessLevel = 1;
77268/* Value rank inherited */
77269attr.valueRank = -2;
77270attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 19LU);
77271attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Quality");
77272retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77273requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9020LU),
77274parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2782LU),
77275referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
77276browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Quality"),
77277typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9002LU),
77278attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77279if (retVal != UA_STATUSCODE_GOOD) return retVal;
77280return retVal;
77281}
77282
77283static UA_StatusCode function_namespace0_generated_312_finish(UA_Server *server, UA_UInt16* ns) {
77284return UA_Server_addNode_finish(server,
77285nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9020LU)
77286);
77287}
77288
77289/* SourceTimestamp - ns=0;i=9021 */
77290
77291static UA_StatusCode function_namespace0_generated_313_begin(UA_Server *server, UA_UInt16* ns) {
77292UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77293UA_VariableAttributes attr = UA_VariableAttributes_default;
77294attr.minimumSamplingInterval = 0.000000;
77295attr.userAccessLevel = 1;
77296attr.accessLevel = 1;
77297/* Value rank inherited */
77298attr.valueRank = -2;
77299attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
77300attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SourceTimestamp");
77301retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77302requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9021LU),
77303parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9020LU),
77304referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77305browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SourceTimestamp"),
77306typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77307attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77308if (retVal != UA_STATUSCODE_GOOD) return retVal;
77309return retVal;
77310}
77311
77312static UA_StatusCode function_namespace0_generated_313_finish(UA_Server *server, UA_UInt16* ns) {
77313return UA_Server_addNode_finish(server,
77314nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9021LU)
77315);
77316}
77317
77318/* SourceTimestamp - ns=0;i=9003 */
77319
77320static UA_StatusCode function_namespace0_generated_314_begin(UA_Server *server, UA_UInt16* ns) {
77321UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77322UA_VariableAttributes attr = UA_VariableAttributes_default;
77323attr.minimumSamplingInterval = 0.000000;
77324attr.userAccessLevel = 1;
77325attr.accessLevel = 1;
77326/* Value rank inherited */
77327attr.valueRank = -2;
77328attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
77329attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SourceTimestamp");
77330retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77331requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9003LU),
77332parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9002LU),
77333referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77334browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SourceTimestamp"),
77335typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77336attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77337if (retVal != UA_STATUSCODE_GOOD) return retVal;
77338return retVal;
77339}
77340
77341static UA_StatusCode function_namespace0_generated_314_finish(UA_Server *server, UA_UInt16* ns) {
77342return UA_Server_addNode_finish(server,
77343nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9003LU)
77344);
77345}
77346
77347/* AuditEventType - ns=0;i=2052 */
77348
77349static UA_StatusCode function_namespace0_generated_315_begin(UA_Server *server, UA_UInt16* ns) {
77350UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77351UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
77352attr.isAbstract = true;
77353attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AuditEventType");
77354retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
77355requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2052LU),
77356parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
77357referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
77358browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AuditEventType"),
77359 typeDefinition: UA_NODEID_NULL,
77360attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
77361if (retVal != UA_STATUSCODE_GOOD) return retVal;
77362return retVal;
77363}
77364
77365static UA_StatusCode function_namespace0_generated_315_finish(UA_Server *server, UA_UInt16* ns) {
77366return UA_Server_addNode_finish(server,
77367nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2052LU)
77368);
77369}
77370
77371/* AuditUpdateMethodEventType - ns=0;i=2127 */
77372
77373static UA_StatusCode function_namespace0_generated_316_begin(UA_Server *server, UA_UInt16* ns) {
77374UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77375UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
77376attr.isAbstract = true;
77377attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AuditUpdateMethodEventType");
77378retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
77379requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2127LU),
77380parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2052LU),
77381referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
77382browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AuditUpdateMethodEventType"),
77383 typeDefinition: UA_NODEID_NULL,
77384attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
77385if (retVal != UA_STATUSCODE_GOOD) return retVal;
77386return retVal;
77387}
77388
77389static UA_StatusCode function_namespace0_generated_316_finish(UA_Server *server, UA_UInt16* ns) {
77390return UA_Server_addNode_finish(server,
77391nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2127LU)
77392);
77393}
77394
77395/* AuditConditionEventType - ns=0;i=2790 */
77396
77397static UA_StatusCode function_namespace0_generated_317_begin(UA_Server *server, UA_UInt16* ns) {
77398UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77399UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
77400attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AuditConditionEventType");
77401retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
77402requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2790LU),
77403parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2127LU),
77404referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
77405browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AuditConditionEventType"),
77406 typeDefinition: UA_NODEID_NULL,
77407attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
77408if (retVal != UA_STATUSCODE_GOOD) return retVal;
77409return retVal;
77410}
77411
77412static UA_StatusCode function_namespace0_generated_317_finish(UA_Server *server, UA_UInt16* ns) {
77413return UA_Server_addNode_finish(server,
77414nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2790LU)
77415);
77416}
77417
77418/* AuditConditionCommentEventType - ns=0;i=2829 */
77419
77420static UA_StatusCode function_namespace0_generated_318_begin(UA_Server *server, UA_UInt16* ns) {
77421UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77422UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
77423attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AuditConditionCommentEventType");
77424retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
77425requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2829LU),
77426parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2790LU),
77427referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
77428browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AuditConditionCommentEventType"),
77429 typeDefinition: UA_NODEID_NULL,
77430attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
77431if (retVal != UA_STATUSCODE_GOOD) return retVal;
77432retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2829LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3065LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9029LU), false);
77433if (retVal != UA_STATUSCODE_GOOD) return retVal;
77434return retVal;
77435}
77436
77437static UA_StatusCode function_namespace0_generated_318_finish(UA_Server *server, UA_UInt16* ns) {
77438return UA_Server_addNode_finish(server,
77439nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2829LU)
77440);
77441}
77442
77443/* ConditionEventId - ns=0;i=17222 */
77444
77445static UA_StatusCode function_namespace0_generated_319_begin(UA_Server *server, UA_UInt16* ns) {
77446UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77447UA_VariableAttributes attr = UA_VariableAttributes_default;
77448attr.minimumSamplingInterval = 0.000000;
77449attr.userAccessLevel = 1;
77450attr.accessLevel = 1;
77451/* Value rank inherited */
77452attr.valueRank = -2;
77453attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15LU);
77454attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ConditionEventId");
77455retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77456requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17222LU),
77457parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2829LU),
77458referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77459browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ConditionEventId"),
77460typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77461attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77462if (retVal != UA_STATUSCODE_GOOD) return retVal;
77463return retVal;
77464}
77465
77466static UA_StatusCode function_namespace0_generated_319_finish(UA_Server *server, UA_UInt16* ns) {
77467return UA_Server_addNode_finish(server,
77468nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17222LU)
77469);
77470}
77471
77472/* Comment - ns=0;i=11851 */
77473
77474static UA_StatusCode function_namespace0_generated_320_begin(UA_Server *server, UA_UInt16* ns) {
77475UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77476UA_VariableAttributes attr = UA_VariableAttributes_default;
77477attr.minimumSamplingInterval = 0.000000;
77478attr.userAccessLevel = 1;
77479attr.accessLevel = 1;
77480/* Value rank inherited */
77481attr.valueRank = -2;
77482attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
77483attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Comment");
77484retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77485requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11851LU),
77486parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2829LU),
77487referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77488browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Comment"),
77489typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77490attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77491if (retVal != UA_STATUSCODE_GOOD) return retVal;
77492return retVal;
77493}
77494
77495static UA_StatusCode function_namespace0_generated_320_finish(UA_Server *server, UA_UInt16* ns) {
77496return UA_Server_addNode_finish(server,
77497nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11851LU)
77498);
77499}
77500
77501/* AuditConditionEnableEventType - ns=0;i=2803 */
77502
77503static UA_StatusCode function_namespace0_generated_321_begin(UA_Server *server, UA_UInt16* ns) {
77504UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77505UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
77506attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AuditConditionEnableEventType");
77507retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
77508requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2803LU),
77509parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2790LU),
77510referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
77511browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AuditConditionEnableEventType"),
77512 typeDefinition: UA_NODEID_NULL,
77513attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
77514if (retVal != UA_STATUSCODE_GOOD) return retVal;
77515retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2803LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3065LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9028LU), false);
77516if (retVal != UA_STATUSCODE_GOOD) return retVal;
77517retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2803LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3065LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9027LU), false);
77518if (retVal != UA_STATUSCODE_GOOD) return retVal;
77519return retVal;
77520}
77521
77522static UA_StatusCode function_namespace0_generated_321_finish(UA_Server *server, UA_UInt16* ns) {
77523return UA_Server_addNode_finish(server,
77524nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2803LU)
77525);
77526}
77527
77528/* InputArguments - ns=0;i=2129 */
77529
77530static UA_StatusCode function_namespace0_generated_322_begin(UA_Server *server, UA_UInt16* ns) {
77531UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77532UA_VariableAttributes attr = UA_VariableAttributes_default;
77533attr.minimumSamplingInterval = 0.000000;
77534attr.userAccessLevel = 1;
77535attr.accessLevel = 1;
77536attr.valueRank = 1;
77537attr.arrayDimensionsSize = 1;
77538UA_UInt32 arrayDimensions[1];
77539arrayDimensions[0] = 0;
77540attr.arrayDimensions = &arrayDimensions[0];
77541/* DataType inherited */
77542attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
77543attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
77544retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77545requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2129LU),
77546parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2127LU),
77547referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77548browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
77549typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77550attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77551if (retVal != UA_STATUSCODE_GOOD) return retVal;
77552return retVal;
77553}
77554
77555static UA_StatusCode function_namespace0_generated_322_finish(UA_Server *server, UA_UInt16* ns) {
77556return UA_Server_addNode_finish(server,
77557nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2129LU)
77558);
77559}
77560
77561/* MethodId - ns=0;i=2128 */
77562
77563static UA_StatusCode function_namespace0_generated_323_begin(UA_Server *server, UA_UInt16* ns) {
77564UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77565UA_VariableAttributes attr = UA_VariableAttributes_default;
77566attr.minimumSamplingInterval = 0.000000;
77567attr.userAccessLevel = 1;
77568attr.accessLevel = 1;
77569/* Value rank inherited */
77570attr.valueRank = -2;
77571attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
77572attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MethodId");
77573retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77574requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2128LU),
77575parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2127LU),
77576referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77577browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MethodId"),
77578typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77579attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77580if (retVal != UA_STATUSCODE_GOOD) return retVal;
77581return retVal;
77582}
77583
77584static UA_StatusCode function_namespace0_generated_323_finish(UA_Server *server, UA_UInt16* ns) {
77585return UA_Server_addNode_finish(server,
77586nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2128LU)
77587);
77588}
77589
77590/* ClientUserId - ns=0;i=2057 */
77591
77592static UA_StatusCode function_namespace0_generated_324_begin(UA_Server *server, UA_UInt16* ns) {
77593UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77594UA_VariableAttributes attr = UA_VariableAttributes_default;
77595attr.minimumSamplingInterval = 0.000000;
77596attr.userAccessLevel = 1;
77597attr.accessLevel = 1;
77598/* Value rank inherited */
77599attr.valueRank = -2;
77600attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
77601attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientUserId");
77602retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77603requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2057LU),
77604parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2052LU),
77605referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77606browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientUserId"),
77607typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77608attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77609if (retVal != UA_STATUSCODE_GOOD) return retVal;
77610return retVal;
77611}
77612
77613static UA_StatusCode function_namespace0_generated_324_finish(UA_Server *server, UA_UInt16* ns) {
77614return UA_Server_addNode_finish(server,
77615nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2057LU)
77616);
77617}
77618
77619/* ClientAuditEntryId - ns=0;i=2056 */
77620
77621static UA_StatusCode function_namespace0_generated_325_begin(UA_Server *server, UA_UInt16* ns) {
77622UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77623UA_VariableAttributes attr = UA_VariableAttributes_default;
77624attr.minimumSamplingInterval = 0.000000;
77625attr.userAccessLevel = 1;
77626attr.accessLevel = 1;
77627/* Value rank inherited */
77628attr.valueRank = -2;
77629attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
77630attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientAuditEntryId");
77631retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77632requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2056LU),
77633parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2052LU),
77634referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77635browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientAuditEntryId"),
77636typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77637attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77638if (retVal != UA_STATUSCODE_GOOD) return retVal;
77639return retVal;
77640}
77641
77642static UA_StatusCode function_namespace0_generated_325_finish(UA_Server *server, UA_UInt16* ns) {
77643return UA_Server_addNode_finish(server,
77644nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2056LU)
77645);
77646}
77647
77648/* ServerId - ns=0;i=2055 */
77649
77650static UA_StatusCode function_namespace0_generated_326_begin(UA_Server *server, UA_UInt16* ns) {
77651UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77652UA_VariableAttributes attr = UA_VariableAttributes_default;
77653attr.minimumSamplingInterval = 0.000000;
77654attr.userAccessLevel = 1;
77655attr.accessLevel = 1;
77656/* Value rank inherited */
77657attr.valueRank = -2;
77658attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
77659attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerId");
77660retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77661requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2055LU),
77662parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2052LU),
77663referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77664browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerId"),
77665typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77666attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77667if (retVal != UA_STATUSCODE_GOOD) return retVal;
77668return retVal;
77669}
77670
77671static UA_StatusCode function_namespace0_generated_326_finish(UA_Server *server, UA_UInt16* ns) {
77672return UA_Server_addNode_finish(server,
77673nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2055LU)
77674);
77675}
77676
77677/* Status - ns=0;i=2054 */
77678
77679static UA_StatusCode function_namespace0_generated_327_begin(UA_Server *server, UA_UInt16* ns) {
77680UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77681UA_VariableAttributes attr = UA_VariableAttributes_default;
77682attr.minimumSamplingInterval = 0.000000;
77683attr.userAccessLevel = 1;
77684attr.accessLevel = 1;
77685/* Value rank inherited */
77686attr.valueRank = -2;
77687attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
77688attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Status");
77689retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77690requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2054LU),
77691parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2052LU),
77692referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77693browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Status"),
77694typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77695attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77696if (retVal != UA_STATUSCODE_GOOD) return retVal;
77697return retVal;
77698}
77699
77700static UA_StatusCode function_namespace0_generated_327_finish(UA_Server *server, UA_UInt16* ns) {
77701return UA_Server_addNode_finish(server,
77702nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2054LU)
77703);
77704}
77705
77706/* ActionTimeStamp - ns=0;i=2053 */
77707
77708static UA_StatusCode function_namespace0_generated_328_begin(UA_Server *server, UA_UInt16* ns) {
77709UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77710UA_VariableAttributes attr = UA_VariableAttributes_default;
77711attr.minimumSamplingInterval = 0.000000;
77712attr.userAccessLevel = 1;
77713attr.accessLevel = 1;
77714/* Value rank inherited */
77715attr.valueRank = -2;
77716attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
77717attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ActionTimeStamp");
77718retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77719requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2053LU),
77720parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2052LU),
77721referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77722browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ActionTimeStamp"),
77723typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77724attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77725if (retVal != UA_STATUSCODE_GOOD) return retVal;
77726return retVal;
77727}
77728
77729static UA_StatusCode function_namespace0_generated_328_finish(UA_Server *server, UA_UInt16* ns) {
77730return UA_Server_addNode_finish(server,
77731nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2053LU)
77732);
77733}
77734
77735/* SystemEventType - ns=0;i=2130 */
77736
77737static UA_StatusCode function_namespace0_generated_329_begin(UA_Server *server, UA_UInt16* ns) {
77738UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77739UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
77740attr.isAbstract = true;
77741attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SystemEventType");
77742retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
77743requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2130LU),
77744parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
77745referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
77746browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SystemEventType"),
77747 typeDefinition: UA_NODEID_NULL,
77748attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
77749if (retVal != UA_STATUSCODE_GOOD) return retVal;
77750return retVal;
77751}
77752
77753static UA_StatusCode function_namespace0_generated_329_finish(UA_Server *server, UA_UInt16* ns) {
77754return UA_Server_addNode_finish(server,
77755nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2130LU)
77756);
77757}
77758
77759/* RefreshEndEventType - ns=0;i=2788 */
77760
77761static UA_StatusCode function_namespace0_generated_330_begin(UA_Server *server, UA_UInt16* ns) {
77762UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77763UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
77764attr.isAbstract = true;
77765attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RefreshEndEventType");
77766retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
77767requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2788LU),
77768parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2130LU),
77769referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
77770browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RefreshEndEventType"),
77771 typeDefinition: UA_NODEID_NULL,
77772attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
77773if (retVal != UA_STATUSCODE_GOOD) return retVal;
77774retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2788LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3065LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3875LU), false);
77775if (retVal != UA_STATUSCODE_GOOD) return retVal;
77776retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2788LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3065LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12912LU), false);
77777if (retVal != UA_STATUSCODE_GOOD) return retVal;
77778return retVal;
77779}
77780
77781static UA_StatusCode function_namespace0_generated_330_finish(UA_Server *server, UA_UInt16* ns) {
77782return UA_Server_addNode_finish(server,
77783nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2788LU)
77784);
77785}
77786
77787/* RefreshStartEventType - ns=0;i=2787 */
77788
77789static UA_StatusCode function_namespace0_generated_331_begin(UA_Server *server, UA_UInt16* ns) {
77790UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77791UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
77792attr.isAbstract = true;
77793attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RefreshStartEventType");
77794retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
77795requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2787LU),
77796parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2130LU),
77797referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
77798browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RefreshStartEventType"),
77799 typeDefinition: UA_NODEID_NULL,
77800attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
77801if (retVal != UA_STATUSCODE_GOOD) return retVal;
77802retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2787LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3065LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3875LU), false);
77803if (retVal != UA_STATUSCODE_GOOD) return retVal;
77804retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2787LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3065LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12912LU), false);
77805if (retVal != UA_STATUSCODE_GOOD) return retVal;
77806return retVal;
77807}
77808
77809static UA_StatusCode function_namespace0_generated_331_finish(UA_Server *server, UA_UInt16* ns) {
77810return UA_Server_addNode_finish(server,
77811nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2787LU)
77812);
77813}
77814
77815/* BaseModelChangeEventType - ns=0;i=2132 */
77816
77817static UA_StatusCode function_namespace0_generated_332_begin(UA_Server *server, UA_UInt16* ns) {
77818UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77819UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
77820attr.isAbstract = true;
77821attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BaseModelChangeEventType");
77822retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
77823requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2132LU),
77824parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
77825referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
77826browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BaseModelChangeEventType"),
77827 typeDefinition: UA_NODEID_NULL,
77828attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
77829if (retVal != UA_STATUSCODE_GOOD) return retVal;
77830return retVal;
77831}
77832
77833static UA_StatusCode function_namespace0_generated_332_finish(UA_Server *server, UA_UInt16* ns) {
77834return UA_Server_addNode_finish(server,
77835nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2132LU)
77836);
77837}
77838
77839/* GeneralModelChangeEventType - ns=0;i=2133 */
77840
77841static UA_StatusCode function_namespace0_generated_333_begin(UA_Server *server, UA_UInt16* ns) {
77842UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77843UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
77844attr.isAbstract = true;
77845attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "GeneralModelChangeEventType");
77846retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
77847requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2133LU),
77848parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2132LU),
77849referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
77850browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "GeneralModelChangeEventType"),
77851 typeDefinition: UA_NODEID_NULL,
77852attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
77853if (retVal != UA_STATUSCODE_GOOD) return retVal;
77854return retVal;
77855}
77856
77857static UA_StatusCode function_namespace0_generated_333_finish(UA_Server *server, UA_UInt16* ns) {
77858return UA_Server_addNode_finish(server,
77859nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2133LU)
77860);
77861}
77862
77863/* Changes - ns=0;i=2134 */
77864
77865static UA_StatusCode function_namespace0_generated_334_begin(UA_Server *server, UA_UInt16* ns) {
77866UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77867UA_VariableAttributes attr = UA_VariableAttributes_default;
77868attr.minimumSamplingInterval = 0.000000;
77869attr.userAccessLevel = 1;
77870attr.accessLevel = 1;
77871attr.valueRank = 1;
77872attr.arrayDimensionsSize = 1;
77873UA_UInt32 arrayDimensions[1];
77874arrayDimensions[0] = 0;
77875attr.arrayDimensions = &arrayDimensions[0];
77876attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 877LU);
77877attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Changes");
77878retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77879requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2134LU),
77880parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2133LU),
77881referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77882browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Changes"),
77883typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77884attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77885if (retVal != UA_STATUSCODE_GOOD) return retVal;
77886return retVal;
77887}
77888
77889static UA_StatusCode function_namespace0_generated_334_finish(UA_Server *server, UA_UInt16* ns) {
77890return UA_Server_addNode_finish(server,
77891nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2134LU)
77892);
77893}
77894
77895/* EventQueueOverflowEventType - ns=0;i=3035 */
77896
77897static UA_StatusCode function_namespace0_generated_335_begin(UA_Server *server, UA_UInt16* ns) {
77898UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77899UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
77900attr.isAbstract = true;
77901attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EventQueueOverflowEventType");
77902retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
77903requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3035LU),
77904parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
77905referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
77906browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EventQueueOverflowEventType"),
77907 typeDefinition: UA_NODEID_NULL,
77908attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
77909if (retVal != UA_STATUSCODE_GOOD) return retVal;
77910return retVal;
77911}
77912
77913static UA_StatusCode function_namespace0_generated_335_finish(UA_Server *server, UA_UInt16* ns) {
77914return UA_Server_addNode_finish(server,
77915nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3035LU)
77916);
77917}
77918
77919/* Severity - ns=0;i=2051 */
77920
77921static UA_StatusCode function_namespace0_generated_336_begin(UA_Server *server, UA_UInt16* ns) {
77922UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77923UA_VariableAttributes attr = UA_VariableAttributes_default;
77924attr.minimumSamplingInterval = 0.000000;
77925attr.userAccessLevel = 1;
77926attr.accessLevel = 1;
77927/* Value rank inherited */
77928attr.valueRank = -2;
77929attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
77930attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Severity");
77931#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS
77932attr.description = UA_LOCALIZEDTEXT(locale: "", text: "Indicates how urgent an event is.");
77933#endif
77934retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77935requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2051LU),
77936parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
77937referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77938browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Severity"),
77939typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77940attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77941if (retVal != UA_STATUSCODE_GOOD) return retVal;
77942return retVal;
77943}
77944
77945static UA_StatusCode function_namespace0_generated_336_finish(UA_Server *server, UA_UInt16* ns) {
77946return UA_Server_addNode_finish(server,
77947nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2051LU)
77948);
77949}
77950
77951/* Message - ns=0;i=2050 */
77952
77953static UA_StatusCode function_namespace0_generated_337_begin(UA_Server *server, UA_UInt16* ns) {
77954UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77955UA_VariableAttributes attr = UA_VariableAttributes_default;
77956attr.minimumSamplingInterval = 0.000000;
77957attr.userAccessLevel = 1;
77958attr.accessLevel = 1;
77959/* Value rank inherited */
77960attr.valueRank = -2;
77961attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
77962attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Message");
77963#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS
77964attr.description = UA_LOCALIZEDTEXT(locale: "", text: "A localized description of the event.");
77965#endif
77966retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77967requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2050LU),
77968parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
77969referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
77970browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Message"),
77971typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
77972attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
77973if (retVal != UA_STATUSCODE_GOOD) return retVal;
77974return retVal;
77975}
77976
77977static UA_StatusCode function_namespace0_generated_337_finish(UA_Server *server, UA_UInt16* ns) {
77978return UA_Server_addNode_finish(server,
77979nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2050LU)
77980);
77981}
77982
77983/* LocalTime - ns=0;i=3190 */
77984
77985static UA_StatusCode function_namespace0_generated_338_begin(UA_Server *server, UA_UInt16* ns) {
77986UA_StatusCode retVal = UA_STATUSCODE_GOOD;
77987UA_VariableAttributes attr = UA_VariableAttributes_default;
77988attr.minimumSamplingInterval = 0.000000;
77989attr.userAccessLevel = 1;
77990attr.accessLevel = 1;
77991/* Value rank inherited */
77992attr.valueRank = -2;
77993attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8912LU);
77994attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "LocalTime");
77995#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS
77996attr.description = UA_LOCALIZEDTEXT(locale: "", text: "Information about the local time where the event originated.");
77997#endif
77998retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
77999requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3190LU),
78000parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
78001referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
78002browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "LocalTime"),
78003typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
78004attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78005if (retVal != UA_STATUSCODE_GOOD) return retVal;
78006return retVal;
78007}
78008
78009static UA_StatusCode function_namespace0_generated_338_finish(UA_Server *server, UA_UInt16* ns) {
78010return UA_Server_addNode_finish(server,
78011nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3190LU)
78012);
78013}
78014
78015/* ReceiveTime - ns=0;i=2047 */
78016
78017static UA_StatusCode function_namespace0_generated_339_begin(UA_Server *server, UA_UInt16* ns) {
78018UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78019UA_VariableAttributes attr = UA_VariableAttributes_default;
78020attr.minimumSamplingInterval = 0.000000;
78021attr.userAccessLevel = 1;
78022attr.accessLevel = 1;
78023/* Value rank inherited */
78024attr.valueRank = -2;
78025attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
78026attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ReceiveTime");
78027#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS
78028attr.description = UA_LOCALIZEDTEXT(locale: "", text: "When the server received the event from the underlying system.");
78029#endif
78030retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78031requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2047LU),
78032parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
78033referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
78034browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ReceiveTime"),
78035typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
78036attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78037if (retVal != UA_STATUSCODE_GOOD) return retVal;
78038return retVal;
78039}
78040
78041static UA_StatusCode function_namespace0_generated_339_finish(UA_Server *server, UA_UInt16* ns) {
78042return UA_Server_addNode_finish(server,
78043nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2047LU)
78044);
78045}
78046
78047/* Time - ns=0;i=2046 */
78048
78049static UA_StatusCode function_namespace0_generated_340_begin(UA_Server *server, UA_UInt16* ns) {
78050UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78051UA_VariableAttributes attr = UA_VariableAttributes_default;
78052attr.minimumSamplingInterval = 0.000000;
78053attr.userAccessLevel = 1;
78054attr.accessLevel = 1;
78055/* Value rank inherited */
78056attr.valueRank = -2;
78057attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
78058attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Time");
78059#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS
78060attr.description = UA_LOCALIZEDTEXT(locale: "", text: "When the event occurred.");
78061#endif
78062retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78063requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2046LU),
78064parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
78065referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
78066browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Time"),
78067typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
78068attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78069if (retVal != UA_STATUSCODE_GOOD) return retVal;
78070return retVal;
78071}
78072
78073static UA_StatusCode function_namespace0_generated_340_finish(UA_Server *server, UA_UInt16* ns) {
78074return UA_Server_addNode_finish(server,
78075nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2046LU)
78076);
78077}
78078
78079/* SourceName - ns=0;i=2045 */
78080
78081static UA_StatusCode function_namespace0_generated_341_begin(UA_Server *server, UA_UInt16* ns) {
78082UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78083UA_VariableAttributes attr = UA_VariableAttributes_default;
78084attr.minimumSamplingInterval = 0.000000;
78085attr.userAccessLevel = 1;
78086attr.accessLevel = 1;
78087/* Value rank inherited */
78088attr.valueRank = -2;
78089attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
78090attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SourceName");
78091#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS
78092attr.description = UA_LOCALIZEDTEXT(locale: "", text: "A description of the source of the event.");
78093#endif
78094retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78095requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2045LU),
78096parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
78097referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
78098browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SourceName"),
78099typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
78100attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78101if (retVal != UA_STATUSCODE_GOOD) return retVal;
78102return retVal;
78103}
78104
78105static UA_StatusCode function_namespace0_generated_341_finish(UA_Server *server, UA_UInt16* ns) {
78106return UA_Server_addNode_finish(server,
78107nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2045LU)
78108);
78109}
78110
78111/* SourceNode - ns=0;i=2044 */
78112
78113static UA_StatusCode function_namespace0_generated_342_begin(UA_Server *server, UA_UInt16* ns) {
78114UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78115UA_VariableAttributes attr = UA_VariableAttributes_default;
78116attr.minimumSamplingInterval = 0.000000;
78117attr.userAccessLevel = 1;
78118attr.accessLevel = 1;
78119/* Value rank inherited */
78120attr.valueRank = -2;
78121attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
78122attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SourceNode");
78123#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS
78124attr.description = UA_LOCALIZEDTEXT(locale: "", text: "The source of the event.");
78125#endif
78126retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78127requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2044LU),
78128parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
78129referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
78130browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SourceNode"),
78131typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
78132attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78133if (retVal != UA_STATUSCODE_GOOD) return retVal;
78134return retVal;
78135}
78136
78137static UA_StatusCode function_namespace0_generated_342_finish(UA_Server *server, UA_UInt16* ns) {
78138return UA_Server_addNode_finish(server,
78139nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2044LU)
78140);
78141}
78142
78143/* EventType - ns=0;i=2043 */
78144
78145static UA_StatusCode function_namespace0_generated_343_begin(UA_Server *server, UA_UInt16* ns) {
78146UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78147UA_VariableAttributes attr = UA_VariableAttributes_default;
78148attr.minimumSamplingInterval = 0.000000;
78149attr.userAccessLevel = 1;
78150attr.accessLevel = 1;
78151/* Value rank inherited */
78152attr.valueRank = -2;
78153attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
78154attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EventType");
78155#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS
78156attr.description = UA_LOCALIZEDTEXT(locale: "", text: "The identifier for the event type.");
78157#endif
78158retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78159requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2043LU),
78160parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
78161referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
78162browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EventType"),
78163typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
78164attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78165if (retVal != UA_STATUSCODE_GOOD) return retVal;
78166return retVal;
78167}
78168
78169static UA_StatusCode function_namespace0_generated_343_finish(UA_Server *server, UA_UInt16* ns) {
78170return UA_Server_addNode_finish(server,
78171nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2043LU)
78172);
78173}
78174
78175/* EventId - ns=0;i=2042 */
78176
78177static UA_StatusCode function_namespace0_generated_344_begin(UA_Server *server, UA_UInt16* ns) {
78178UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78179UA_VariableAttributes attr = UA_VariableAttributes_default;
78180attr.minimumSamplingInterval = 0.000000;
78181attr.userAccessLevel = 1;
78182attr.accessLevel = 1;
78183/* Value rank inherited */
78184attr.valueRank = -2;
78185attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15LU);
78186attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EventId");
78187#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS
78188attr.description = UA_LOCALIZEDTEXT(locale: "", text: "A globally unique identifier for the event.");
78189#endif
78190retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78191requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2042LU),
78192parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2041LU),
78193referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
78194browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EventId"),
78195typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
78196attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78197if (retVal != UA_STATUSCODE_GOOD) return retVal;
78198return retVal;
78199}
78200
78201static UA_StatusCode function_namespace0_generated_344_finish(UA_Server *server, UA_UInt16* ns) {
78202return UA_Server_addNode_finish(server,
78203nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2042LU)
78204);
78205}
78206
78207/* SessionDiagnosticsVariableType - ns=0;i=2197 */
78208
78209static UA_StatusCode function_namespace0_generated_345_begin(UA_Server *server, UA_UInt16* ns) {
78210UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78211UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
78212/* Value rank inherited */
78213attr.valueRank = -2;
78214attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 865LU);
78215attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionDiagnosticsVariableType");
78216retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
78217requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78218parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78219referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
78220browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionDiagnosticsVariableType"),
78221typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
78222attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
78223if (retVal != UA_STATUSCODE_GOOD) return retVal;
78224return retVal;
78225}
78226
78227static UA_StatusCode function_namespace0_generated_345_finish(UA_Server *server, UA_UInt16* ns) {
78228return UA_Server_addNode_finish(server,
78229nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU)
78230);
78231}
78232
78233/* TotalRequestCount - ns=0;i=8900 */
78234
78235static UA_StatusCode function_namespace0_generated_346_begin(UA_Server *server, UA_UInt16* ns) {
78236UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78237UA_VariableAttributes attr = UA_VariableAttributes_default;
78238attr.minimumSamplingInterval = 0.000000;
78239attr.userAccessLevel = 1;
78240attr.accessLevel = 1;
78241/* Value rank inherited */
78242attr.valueRank = -2;
78243attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78244attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TotalRequestCount");
78245retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78246requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8900LU),
78247parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78248referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78249browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TotalRequestCount"),
78250typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78251attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78252if (retVal != UA_STATUSCODE_GOOD) return retVal;
78253return retVal;
78254}
78255
78256static UA_StatusCode function_namespace0_generated_346_finish(UA_Server *server, UA_UInt16* ns) {
78257return UA_Server_addNode_finish(server,
78258nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8900LU)
78259);
78260}
78261
78262/* MaxResponseMessageSize - ns=0;i=3050 */
78263
78264static UA_StatusCode function_namespace0_generated_347_begin(UA_Server *server, UA_UInt16* ns) {
78265UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78266UA_VariableAttributes attr = UA_VariableAttributes_default;
78267attr.minimumSamplingInterval = 0.000000;
78268attr.userAccessLevel = 1;
78269attr.accessLevel = 1;
78270/* Value rank inherited */
78271attr.valueRank = -2;
78272attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
78273attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxResponseMessageSize");
78274retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78275requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3050LU),
78276parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78277referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78278browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxResponseMessageSize"),
78279typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78280attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78281if (retVal != UA_STATUSCODE_GOOD) return retVal;
78282return retVal;
78283}
78284
78285static UA_StatusCode function_namespace0_generated_347_finish(UA_Server *server, UA_UInt16* ns) {
78286return UA_Server_addNode_finish(server,
78287nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3050LU)
78288);
78289}
78290
78291/* UnregisterNodesCount - ns=0;i=2731 */
78292
78293static UA_StatusCode function_namespace0_generated_348_begin(UA_Server *server, UA_UInt16* ns) {
78294UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78295UA_VariableAttributes attr = UA_VariableAttributes_default;
78296attr.minimumSamplingInterval = 0.000000;
78297attr.userAccessLevel = 1;
78298attr.accessLevel = 1;
78299/* Value rank inherited */
78300attr.valueRank = -2;
78301attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78302attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UnregisterNodesCount");
78303retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78304requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2731LU),
78305parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78306referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78307browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UnregisterNodesCount"),
78308typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78309attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78310if (retVal != UA_STATUSCODE_GOOD) return retVal;
78311return retVal;
78312}
78313
78314static UA_StatusCode function_namespace0_generated_348_finish(UA_Server *server, UA_UInt16* ns) {
78315return UA_Server_addNode_finish(server,
78316nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2731LU)
78317);
78318}
78319
78320/* RegisterNodesCount - ns=0;i=2730 */
78321
78322static UA_StatusCode function_namespace0_generated_349_begin(UA_Server *server, UA_UInt16* ns) {
78323UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78324UA_VariableAttributes attr = UA_VariableAttributes_default;
78325attr.minimumSamplingInterval = 0.000000;
78326attr.userAccessLevel = 1;
78327attr.accessLevel = 1;
78328/* Value rank inherited */
78329attr.valueRank = -2;
78330attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78331attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RegisterNodesCount");
78332retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78333requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2730LU),
78334parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78335referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78336browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RegisterNodesCount"),
78337typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78338attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78339if (retVal != UA_STATUSCODE_GOOD) return retVal;
78340return retVal;
78341}
78342
78343static UA_StatusCode function_namespace0_generated_349_finish(UA_Server *server, UA_UInt16* ns) {
78344return UA_Server_addNode_finish(server,
78345nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2730LU)
78346);
78347}
78348
78349/* QueryNextCount - ns=0;i=2242 */
78350
78351static UA_StatusCode function_namespace0_generated_350_begin(UA_Server *server, UA_UInt16* ns) {
78352UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78353UA_VariableAttributes attr = UA_VariableAttributes_default;
78354attr.minimumSamplingInterval = 0.000000;
78355attr.userAccessLevel = 1;
78356attr.accessLevel = 1;
78357/* Value rank inherited */
78358attr.valueRank = -2;
78359attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78360attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "QueryNextCount");
78361retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78362requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2242LU),
78363parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78364referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78365browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "QueryNextCount"),
78366typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78367attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78368if (retVal != UA_STATUSCODE_GOOD) return retVal;
78369return retVal;
78370}
78371
78372static UA_StatusCode function_namespace0_generated_350_finish(UA_Server *server, UA_UInt16* ns) {
78373return UA_Server_addNode_finish(server,
78374nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2242LU)
78375);
78376}
78377
78378/* QueryFirstCount - ns=0;i=2241 */
78379
78380static UA_StatusCode function_namespace0_generated_351_begin(UA_Server *server, UA_UInt16* ns) {
78381UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78382UA_VariableAttributes attr = UA_VariableAttributes_default;
78383attr.minimumSamplingInterval = 0.000000;
78384attr.userAccessLevel = 1;
78385attr.accessLevel = 1;
78386/* Value rank inherited */
78387attr.valueRank = -2;
78388attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78389attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "QueryFirstCount");
78390retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78391requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2241LU),
78392parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78393referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78394browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "QueryFirstCount"),
78395typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78396attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78397if (retVal != UA_STATUSCODE_GOOD) return retVal;
78398return retVal;
78399}
78400
78401static UA_StatusCode function_namespace0_generated_351_finish(UA_Server *server, UA_UInt16* ns) {
78402return UA_Server_addNode_finish(server,
78403nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2241LU)
78404);
78405}
78406
78407/* TranslateBrowsePathsToNodeIdsCount - ns=0;i=2240 */
78408
78409static UA_StatusCode function_namespace0_generated_352_begin(UA_Server *server, UA_UInt16* ns) {
78410UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78411UA_VariableAttributes attr = UA_VariableAttributes_default;
78412attr.minimumSamplingInterval = 0.000000;
78413attr.userAccessLevel = 1;
78414attr.accessLevel = 1;
78415/* Value rank inherited */
78416attr.valueRank = -2;
78417attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78418attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TranslateBrowsePathsToNodeIdsCount");
78419retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78420requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2240LU),
78421parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78422referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78423browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TranslateBrowsePathsToNodeIdsCount"),
78424typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78425attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78426if (retVal != UA_STATUSCODE_GOOD) return retVal;
78427return retVal;
78428}
78429
78430static UA_StatusCode function_namespace0_generated_352_finish(UA_Server *server, UA_UInt16* ns) {
78431return UA_Server_addNode_finish(server,
78432nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2240LU)
78433);
78434}
78435
78436/* BrowseNextCount - ns=0;i=2239 */
78437
78438static UA_StatusCode function_namespace0_generated_353_begin(UA_Server *server, UA_UInt16* ns) {
78439UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78440UA_VariableAttributes attr = UA_VariableAttributes_default;
78441attr.minimumSamplingInterval = 0.000000;
78442attr.userAccessLevel = 1;
78443attr.accessLevel = 1;
78444/* Value rank inherited */
78445attr.valueRank = -2;
78446attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78447attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BrowseNextCount");
78448retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78449requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2239LU),
78450parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78451referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78452browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BrowseNextCount"),
78453typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78454attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78455if (retVal != UA_STATUSCODE_GOOD) return retVal;
78456return retVal;
78457}
78458
78459static UA_StatusCode function_namespace0_generated_353_finish(UA_Server *server, UA_UInt16* ns) {
78460return UA_Server_addNode_finish(server,
78461nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2239LU)
78462);
78463}
78464
78465/* BrowseCount - ns=0;i=2238 */
78466
78467static UA_StatusCode function_namespace0_generated_354_begin(UA_Server *server, UA_UInt16* ns) {
78468UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78469UA_VariableAttributes attr = UA_VariableAttributes_default;
78470attr.minimumSamplingInterval = 0.000000;
78471attr.userAccessLevel = 1;
78472attr.accessLevel = 1;
78473/* Value rank inherited */
78474attr.valueRank = -2;
78475attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78476attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BrowseCount");
78477retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78478requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2238LU),
78479parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78480referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78481browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BrowseCount"),
78482typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78483attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78484if (retVal != UA_STATUSCODE_GOOD) return retVal;
78485return retVal;
78486}
78487
78488static UA_StatusCode function_namespace0_generated_354_finish(UA_Server *server, UA_UInt16* ns) {
78489return UA_Server_addNode_finish(server,
78490nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2238LU)
78491);
78492}
78493
78494/* DeleteReferencesCount - ns=0;i=2237 */
78495
78496static UA_StatusCode function_namespace0_generated_355_begin(UA_Server *server, UA_UInt16* ns) {
78497UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78498UA_VariableAttributes attr = UA_VariableAttributes_default;
78499attr.minimumSamplingInterval = 0.000000;
78500attr.userAccessLevel = 1;
78501attr.accessLevel = 1;
78502/* Value rank inherited */
78503attr.valueRank = -2;
78504attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78505attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteReferencesCount");
78506retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78507requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2237LU),
78508parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78509referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78510browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteReferencesCount"),
78511typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78512attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78513if (retVal != UA_STATUSCODE_GOOD) return retVal;
78514return retVal;
78515}
78516
78517static UA_StatusCode function_namespace0_generated_355_finish(UA_Server *server, UA_UInt16* ns) {
78518return UA_Server_addNode_finish(server,
78519nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2237LU)
78520);
78521}
78522
78523/* DeleteNodesCount - ns=0;i=2236 */
78524
78525static UA_StatusCode function_namespace0_generated_356_begin(UA_Server *server, UA_UInt16* ns) {
78526UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78527UA_VariableAttributes attr = UA_VariableAttributes_default;
78528attr.minimumSamplingInterval = 0.000000;
78529attr.userAccessLevel = 1;
78530attr.accessLevel = 1;
78531/* Value rank inherited */
78532attr.valueRank = -2;
78533attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78534attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteNodesCount");
78535retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78536requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2236LU),
78537parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78538referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78539browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteNodesCount"),
78540typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78541attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78542if (retVal != UA_STATUSCODE_GOOD) return retVal;
78543return retVal;
78544}
78545
78546static UA_StatusCode function_namespace0_generated_356_finish(UA_Server *server, UA_UInt16* ns) {
78547return UA_Server_addNode_finish(server,
78548nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2236LU)
78549);
78550}
78551
78552/* AddReferencesCount - ns=0;i=2235 */
78553
78554static UA_StatusCode function_namespace0_generated_357_begin(UA_Server *server, UA_UInt16* ns) {
78555UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78556UA_VariableAttributes attr = UA_VariableAttributes_default;
78557attr.minimumSamplingInterval = 0.000000;
78558attr.userAccessLevel = 1;
78559attr.accessLevel = 1;
78560/* Value rank inherited */
78561attr.valueRank = -2;
78562attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78563attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddReferencesCount");
78564retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78565requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2235LU),
78566parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78567referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78568browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddReferencesCount"),
78569typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78570attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78571if (retVal != UA_STATUSCODE_GOOD) return retVal;
78572return retVal;
78573}
78574
78575static UA_StatusCode function_namespace0_generated_357_finish(UA_Server *server, UA_UInt16* ns) {
78576return UA_Server_addNode_finish(server,
78577nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2235LU)
78578);
78579}
78580
78581/* AddNodesCount - ns=0;i=2234 */
78582
78583static UA_StatusCode function_namespace0_generated_358_begin(UA_Server *server, UA_UInt16* ns) {
78584UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78585UA_VariableAttributes attr = UA_VariableAttributes_default;
78586attr.minimumSamplingInterval = 0.000000;
78587attr.userAccessLevel = 1;
78588attr.accessLevel = 1;
78589/* Value rank inherited */
78590attr.valueRank = -2;
78591attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78592attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddNodesCount");
78593retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78594requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2234LU),
78595parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78596referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78597browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddNodesCount"),
78598typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78599attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78600if (retVal != UA_STATUSCODE_GOOD) return retVal;
78601return retVal;
78602}
78603
78604static UA_StatusCode function_namespace0_generated_358_finish(UA_Server *server, UA_UInt16* ns) {
78605return UA_Server_addNode_finish(server,
78606nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2234LU)
78607);
78608}
78609
78610/* DeleteSubscriptionsCount - ns=0;i=2233 */
78611
78612static UA_StatusCode function_namespace0_generated_359_begin(UA_Server *server, UA_UInt16* ns) {
78613UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78614UA_VariableAttributes attr = UA_VariableAttributes_default;
78615attr.minimumSamplingInterval = 0.000000;
78616attr.userAccessLevel = 1;
78617attr.accessLevel = 1;
78618/* Value rank inherited */
78619attr.valueRank = -2;
78620attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78621attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteSubscriptionsCount");
78622retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78623requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2233LU),
78624parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78625referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78626browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteSubscriptionsCount"),
78627typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78628attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78629if (retVal != UA_STATUSCODE_GOOD) return retVal;
78630return retVal;
78631}
78632
78633static UA_StatusCode function_namespace0_generated_359_finish(UA_Server *server, UA_UInt16* ns) {
78634return UA_Server_addNode_finish(server,
78635nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2233LU)
78636);
78637}
78638
78639/* TransferSubscriptionsCount - ns=0;i=2232 */
78640
78641static UA_StatusCode function_namespace0_generated_360_begin(UA_Server *server, UA_UInt16* ns) {
78642UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78643UA_VariableAttributes attr = UA_VariableAttributes_default;
78644attr.minimumSamplingInterval = 0.000000;
78645attr.userAccessLevel = 1;
78646attr.accessLevel = 1;
78647/* Value rank inherited */
78648attr.valueRank = -2;
78649attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78650attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransferSubscriptionsCount");
78651retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78652requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2232LU),
78653parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78654referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78655browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransferSubscriptionsCount"),
78656typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78657attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78658if (retVal != UA_STATUSCODE_GOOD) return retVal;
78659return retVal;
78660}
78661
78662static UA_StatusCode function_namespace0_generated_360_finish(UA_Server *server, UA_UInt16* ns) {
78663return UA_Server_addNode_finish(server,
78664nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2232LU)
78665);
78666}
78667
78668/* RepublishCount - ns=0;i=2231 */
78669
78670static UA_StatusCode function_namespace0_generated_361_begin(UA_Server *server, UA_UInt16* ns) {
78671UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78672UA_VariableAttributes attr = UA_VariableAttributes_default;
78673attr.minimumSamplingInterval = 0.000000;
78674attr.userAccessLevel = 1;
78675attr.accessLevel = 1;
78676/* Value rank inherited */
78677attr.valueRank = -2;
78678attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78679attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RepublishCount");
78680retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78681requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2231LU),
78682parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78683referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78684browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RepublishCount"),
78685typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78686attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78687if (retVal != UA_STATUSCODE_GOOD) return retVal;
78688return retVal;
78689}
78690
78691static UA_StatusCode function_namespace0_generated_361_finish(UA_Server *server, UA_UInt16* ns) {
78692return UA_Server_addNode_finish(server,
78693nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2231LU)
78694);
78695}
78696
78697/* PublishCount - ns=0;i=2230 */
78698
78699static UA_StatusCode function_namespace0_generated_362_begin(UA_Server *server, UA_UInt16* ns) {
78700UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78701UA_VariableAttributes attr = UA_VariableAttributes_default;
78702attr.minimumSamplingInterval = 0.000000;
78703attr.userAccessLevel = 1;
78704attr.accessLevel = 1;
78705/* Value rank inherited */
78706attr.valueRank = -2;
78707attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78708attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishCount");
78709retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78710requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2230LU),
78711parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78712referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78713browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishCount"),
78714typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78715attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78716if (retVal != UA_STATUSCODE_GOOD) return retVal;
78717return retVal;
78718}
78719
78720static UA_StatusCode function_namespace0_generated_362_finish(UA_Server *server, UA_UInt16* ns) {
78721return UA_Server_addNode_finish(server,
78722nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2230LU)
78723);
78724}
78725
78726/* SetPublishingModeCount - ns=0;i=2229 */
78727
78728static UA_StatusCode function_namespace0_generated_363_begin(UA_Server *server, UA_UInt16* ns) {
78729UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78730UA_VariableAttributes attr = UA_VariableAttributes_default;
78731attr.minimumSamplingInterval = 0.000000;
78732attr.userAccessLevel = 1;
78733attr.accessLevel = 1;
78734/* Value rank inherited */
78735attr.valueRank = -2;
78736attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78737attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SetPublishingModeCount");
78738retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78739requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2229LU),
78740parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78741referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78742browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SetPublishingModeCount"),
78743typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78744attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78745if (retVal != UA_STATUSCODE_GOOD) return retVal;
78746return retVal;
78747}
78748
78749static UA_StatusCode function_namespace0_generated_363_finish(UA_Server *server, UA_UInt16* ns) {
78750return UA_Server_addNode_finish(server,
78751nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2229LU)
78752);
78753}
78754
78755/* ModifySubscriptionCount - ns=0;i=2228 */
78756
78757static UA_StatusCode function_namespace0_generated_364_begin(UA_Server *server, UA_UInt16* ns) {
78758UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78759UA_VariableAttributes attr = UA_VariableAttributes_default;
78760attr.minimumSamplingInterval = 0.000000;
78761attr.userAccessLevel = 1;
78762attr.accessLevel = 1;
78763/* Value rank inherited */
78764attr.valueRank = -2;
78765attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78766attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ModifySubscriptionCount");
78767retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78768requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2228LU),
78769parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78770referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78771browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ModifySubscriptionCount"),
78772typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78773attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78774if (retVal != UA_STATUSCODE_GOOD) return retVal;
78775return retVal;
78776}
78777
78778static UA_StatusCode function_namespace0_generated_364_finish(UA_Server *server, UA_UInt16* ns) {
78779return UA_Server_addNode_finish(server,
78780nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2228LU)
78781);
78782}
78783
78784/* CreateSubscriptionCount - ns=0;i=2227 */
78785
78786static UA_StatusCode function_namespace0_generated_365_begin(UA_Server *server, UA_UInt16* ns) {
78787UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78788UA_VariableAttributes attr = UA_VariableAttributes_default;
78789attr.minimumSamplingInterval = 0.000000;
78790attr.userAccessLevel = 1;
78791attr.accessLevel = 1;
78792/* Value rank inherited */
78793attr.valueRank = -2;
78794attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78795attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CreateSubscriptionCount");
78796retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78797requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2227LU),
78798parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78799referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78800browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CreateSubscriptionCount"),
78801typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78802attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78803if (retVal != UA_STATUSCODE_GOOD) return retVal;
78804return retVal;
78805}
78806
78807static UA_StatusCode function_namespace0_generated_365_finish(UA_Server *server, UA_UInt16* ns) {
78808return UA_Server_addNode_finish(server,
78809nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2227LU)
78810);
78811}
78812
78813/* DeleteMonitoredItemsCount - ns=0;i=2226 */
78814
78815static UA_StatusCode function_namespace0_generated_366_begin(UA_Server *server, UA_UInt16* ns) {
78816UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78817UA_VariableAttributes attr = UA_VariableAttributes_default;
78818attr.minimumSamplingInterval = 0.000000;
78819attr.userAccessLevel = 1;
78820attr.accessLevel = 1;
78821/* Value rank inherited */
78822attr.valueRank = -2;
78823attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78824attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteMonitoredItemsCount");
78825retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78826requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2226LU),
78827parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78828referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78829browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteMonitoredItemsCount"),
78830typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78831attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78832if (retVal != UA_STATUSCODE_GOOD) return retVal;
78833return retVal;
78834}
78835
78836static UA_StatusCode function_namespace0_generated_366_finish(UA_Server *server, UA_UInt16* ns) {
78837return UA_Server_addNode_finish(server,
78838nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2226LU)
78839);
78840}
78841
78842/* SetTriggeringCount - ns=0;i=2225 */
78843
78844static UA_StatusCode function_namespace0_generated_367_begin(UA_Server *server, UA_UInt16* ns) {
78845UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78846UA_VariableAttributes attr = UA_VariableAttributes_default;
78847attr.minimumSamplingInterval = 0.000000;
78848attr.userAccessLevel = 1;
78849attr.accessLevel = 1;
78850/* Value rank inherited */
78851attr.valueRank = -2;
78852attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78853attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SetTriggeringCount");
78854retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78855requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2225LU),
78856parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78857referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78858browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SetTriggeringCount"),
78859typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78860attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78861if (retVal != UA_STATUSCODE_GOOD) return retVal;
78862return retVal;
78863}
78864
78865static UA_StatusCode function_namespace0_generated_367_finish(UA_Server *server, UA_UInt16* ns) {
78866return UA_Server_addNode_finish(server,
78867nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2225LU)
78868);
78869}
78870
78871/* SetMonitoringModeCount - ns=0;i=2224 */
78872
78873static UA_StatusCode function_namespace0_generated_368_begin(UA_Server *server, UA_UInt16* ns) {
78874UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78875UA_VariableAttributes attr = UA_VariableAttributes_default;
78876attr.minimumSamplingInterval = 0.000000;
78877attr.userAccessLevel = 1;
78878attr.accessLevel = 1;
78879/* Value rank inherited */
78880attr.valueRank = -2;
78881attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78882attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SetMonitoringModeCount");
78883retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78884requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2224LU),
78885parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78886referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78887browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SetMonitoringModeCount"),
78888typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78889attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78890if (retVal != UA_STATUSCODE_GOOD) return retVal;
78891return retVal;
78892}
78893
78894static UA_StatusCode function_namespace0_generated_368_finish(UA_Server *server, UA_UInt16* ns) {
78895return UA_Server_addNode_finish(server,
78896nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2224LU)
78897);
78898}
78899
78900/* ModifyMonitoredItemsCount - ns=0;i=2223 */
78901
78902static UA_StatusCode function_namespace0_generated_369_begin(UA_Server *server, UA_UInt16* ns) {
78903UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78904UA_VariableAttributes attr = UA_VariableAttributes_default;
78905attr.minimumSamplingInterval = 0.000000;
78906attr.userAccessLevel = 1;
78907attr.accessLevel = 1;
78908/* Value rank inherited */
78909attr.valueRank = -2;
78910attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78911attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ModifyMonitoredItemsCount");
78912retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78913requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2223LU),
78914parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78915referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78916browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ModifyMonitoredItemsCount"),
78917typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78918attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78919if (retVal != UA_STATUSCODE_GOOD) return retVal;
78920return retVal;
78921}
78922
78923static UA_StatusCode function_namespace0_generated_369_finish(UA_Server *server, UA_UInt16* ns) {
78924return UA_Server_addNode_finish(server,
78925nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2223LU)
78926);
78927}
78928
78929/* CreateMonitoredItemsCount - ns=0;i=2222 */
78930
78931static UA_StatusCode function_namespace0_generated_370_begin(UA_Server *server, UA_UInt16* ns) {
78932UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78933UA_VariableAttributes attr = UA_VariableAttributes_default;
78934attr.minimumSamplingInterval = 0.000000;
78935attr.userAccessLevel = 1;
78936attr.accessLevel = 1;
78937/* Value rank inherited */
78938attr.valueRank = -2;
78939attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78940attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CreateMonitoredItemsCount");
78941retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78942requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2222LU),
78943parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78944referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78945browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CreateMonitoredItemsCount"),
78946typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78947attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78948if (retVal != UA_STATUSCODE_GOOD) return retVal;
78949return retVal;
78950}
78951
78952static UA_StatusCode function_namespace0_generated_370_finish(UA_Server *server, UA_UInt16* ns) {
78953return UA_Server_addNode_finish(server,
78954nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2222LU)
78955);
78956}
78957
78958/* CallCount - ns=0;i=2221 */
78959
78960static UA_StatusCode function_namespace0_generated_371_begin(UA_Server *server, UA_UInt16* ns) {
78961UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78962UA_VariableAttributes attr = UA_VariableAttributes_default;
78963attr.minimumSamplingInterval = 0.000000;
78964attr.userAccessLevel = 1;
78965attr.accessLevel = 1;
78966/* Value rank inherited */
78967attr.valueRank = -2;
78968attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78969attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CallCount");
78970retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
78971requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2221LU),
78972parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
78973referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
78974browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CallCount"),
78975typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
78976attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
78977if (retVal != UA_STATUSCODE_GOOD) return retVal;
78978return retVal;
78979}
78980
78981static UA_StatusCode function_namespace0_generated_371_finish(UA_Server *server, UA_UInt16* ns) {
78982return UA_Server_addNode_finish(server,
78983nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2221LU)
78984);
78985}
78986
78987/* HistoryUpdateCount - ns=0;i=2220 */
78988
78989static UA_StatusCode function_namespace0_generated_372_begin(UA_Server *server, UA_UInt16* ns) {
78990UA_StatusCode retVal = UA_STATUSCODE_GOOD;
78991UA_VariableAttributes attr = UA_VariableAttributes_default;
78992attr.minimumSamplingInterval = 0.000000;
78993attr.userAccessLevel = 1;
78994attr.accessLevel = 1;
78995/* Value rank inherited */
78996attr.valueRank = -2;
78997attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
78998attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HistoryUpdateCount");
78999retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79000requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2220LU),
79001parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79002referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79003browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HistoryUpdateCount"),
79004typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79005attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79006if (retVal != UA_STATUSCODE_GOOD) return retVal;
79007return retVal;
79008}
79009
79010static UA_StatusCode function_namespace0_generated_372_finish(UA_Server *server, UA_UInt16* ns) {
79011return UA_Server_addNode_finish(server,
79012nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2220LU)
79013);
79014}
79015
79016/* WriteCount - ns=0;i=2219 */
79017
79018static UA_StatusCode function_namespace0_generated_373_begin(UA_Server *server, UA_UInt16* ns) {
79019UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79020UA_VariableAttributes attr = UA_VariableAttributes_default;
79021attr.minimumSamplingInterval = 0.000000;
79022attr.userAccessLevel = 1;
79023attr.accessLevel = 1;
79024/* Value rank inherited */
79025attr.valueRank = -2;
79026attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
79027attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "WriteCount");
79028retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79029requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2219LU),
79030parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79031referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79032browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "WriteCount"),
79033typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79034attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79035if (retVal != UA_STATUSCODE_GOOD) return retVal;
79036return retVal;
79037}
79038
79039static UA_StatusCode function_namespace0_generated_373_finish(UA_Server *server, UA_UInt16* ns) {
79040return UA_Server_addNode_finish(server,
79041nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2219LU)
79042);
79043}
79044
79045/* HistoryReadCount - ns=0;i=2218 */
79046
79047static UA_StatusCode function_namespace0_generated_374_begin(UA_Server *server, UA_UInt16* ns) {
79048UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79049UA_VariableAttributes attr = UA_VariableAttributes_default;
79050attr.minimumSamplingInterval = 0.000000;
79051attr.userAccessLevel = 1;
79052attr.accessLevel = 1;
79053/* Value rank inherited */
79054attr.valueRank = -2;
79055attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
79056attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HistoryReadCount");
79057retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79058requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2218LU),
79059parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79060referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79061browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HistoryReadCount"),
79062typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79063attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79064if (retVal != UA_STATUSCODE_GOOD) return retVal;
79065return retVal;
79066}
79067
79068static UA_StatusCode function_namespace0_generated_374_finish(UA_Server *server, UA_UInt16* ns) {
79069return UA_Server_addNode_finish(server,
79070nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2218LU)
79071);
79072}
79073
79074/* ReadCount - ns=0;i=2217 */
79075
79076static UA_StatusCode function_namespace0_generated_375_begin(UA_Server *server, UA_UInt16* ns) {
79077UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79078UA_VariableAttributes attr = UA_VariableAttributes_default;
79079attr.minimumSamplingInterval = 0.000000;
79080attr.userAccessLevel = 1;
79081attr.accessLevel = 1;
79082/* Value rank inherited */
79083attr.valueRank = -2;
79084attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
79085attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ReadCount");
79086retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79087requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2217LU),
79088parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79089referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79090browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ReadCount"),
79091typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79092attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79093if (retVal != UA_STATUSCODE_GOOD) return retVal;
79094return retVal;
79095}
79096
79097static UA_StatusCode function_namespace0_generated_375_finish(UA_Server *server, UA_UInt16* ns) {
79098return UA_Server_addNode_finish(server,
79099nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2217LU)
79100);
79101}
79102
79103/* CurrentPublishRequestsInQueue - ns=0;i=2209 */
79104
79105static UA_StatusCode function_namespace0_generated_376_begin(UA_Server *server, UA_UInt16* ns) {
79106UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79107UA_VariableAttributes attr = UA_VariableAttributes_default;
79108attr.minimumSamplingInterval = 0.000000;
79109attr.userAccessLevel = 1;
79110attr.accessLevel = 1;
79111/* Value rank inherited */
79112attr.valueRank = -2;
79113attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79114attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentPublishRequestsInQueue");
79115retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79116requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2209LU),
79117parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79118referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79119browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentPublishRequestsInQueue"),
79120typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79121attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79122if (retVal != UA_STATUSCODE_GOOD) return retVal;
79123return retVal;
79124}
79125
79126static UA_StatusCode function_namespace0_generated_376_finish(UA_Server *server, UA_UInt16* ns) {
79127return UA_Server_addNode_finish(server,
79128nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2209LU)
79129);
79130}
79131
79132/* CurrentMonitoredItemsCount - ns=0;i=2208 */
79133
79134static UA_StatusCode function_namespace0_generated_377_begin(UA_Server *server, UA_UInt16* ns) {
79135UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79136UA_VariableAttributes attr = UA_VariableAttributes_default;
79137attr.minimumSamplingInterval = 0.000000;
79138attr.userAccessLevel = 1;
79139attr.accessLevel = 1;
79140/* Value rank inherited */
79141attr.valueRank = -2;
79142attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79143attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentMonitoredItemsCount");
79144retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79145requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2208LU),
79146parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79147referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79148browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentMonitoredItemsCount"),
79149typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79150attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79151if (retVal != UA_STATUSCODE_GOOD) return retVal;
79152return retVal;
79153}
79154
79155static UA_StatusCode function_namespace0_generated_377_finish(UA_Server *server, UA_UInt16* ns) {
79156return UA_Server_addNode_finish(server,
79157nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2208LU)
79158);
79159}
79160
79161/* CurrentSubscriptionsCount - ns=0;i=2207 */
79162
79163static UA_StatusCode function_namespace0_generated_378_begin(UA_Server *server, UA_UInt16* ns) {
79164UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79165UA_VariableAttributes attr = UA_VariableAttributes_default;
79166attr.minimumSamplingInterval = 0.000000;
79167attr.userAccessLevel = 1;
79168attr.accessLevel = 1;
79169/* Value rank inherited */
79170attr.valueRank = -2;
79171attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79172attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentSubscriptionsCount");
79173retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79174requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2207LU),
79175parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79176referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79177browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentSubscriptionsCount"),
79178typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79179attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79180if (retVal != UA_STATUSCODE_GOOD) return retVal;
79181return retVal;
79182}
79183
79184static UA_StatusCode function_namespace0_generated_378_finish(UA_Server *server, UA_UInt16* ns) {
79185return UA_Server_addNode_finish(server,
79186nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2207LU)
79187);
79188}
79189
79190/* ClientLastContactTime - ns=0;i=2206 */
79191
79192static UA_StatusCode function_namespace0_generated_379_begin(UA_Server *server, UA_UInt16* ns) {
79193UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79194UA_VariableAttributes attr = UA_VariableAttributes_default;
79195attr.minimumSamplingInterval = 0.000000;
79196attr.userAccessLevel = 1;
79197attr.accessLevel = 1;
79198/* Value rank inherited */
79199attr.valueRank = -2;
79200attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
79201attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientLastContactTime");
79202retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79203requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2206LU),
79204parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79205referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79206browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientLastContactTime"),
79207typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79208attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79209if (retVal != UA_STATUSCODE_GOOD) return retVal;
79210return retVal;
79211}
79212
79213static UA_StatusCode function_namespace0_generated_379_finish(UA_Server *server, UA_UInt16* ns) {
79214return UA_Server_addNode_finish(server,
79215nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2206LU)
79216);
79217}
79218
79219/* ClientConnectionTime - ns=0;i=2205 */
79220
79221static UA_StatusCode function_namespace0_generated_380_begin(UA_Server *server, UA_UInt16* ns) {
79222UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79223UA_VariableAttributes attr = UA_VariableAttributes_default;
79224attr.minimumSamplingInterval = 0.000000;
79225attr.userAccessLevel = 1;
79226attr.accessLevel = 1;
79227/* Value rank inherited */
79228attr.valueRank = -2;
79229attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
79230attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientConnectionTime");
79231retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79232requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2205LU),
79233parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79234referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79235browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientConnectionTime"),
79236typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79237attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79238if (retVal != UA_STATUSCODE_GOOD) return retVal;
79239return retVal;
79240}
79241
79242static UA_StatusCode function_namespace0_generated_380_finish(UA_Server *server, UA_UInt16* ns) {
79243return UA_Server_addNode_finish(server,
79244nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2205LU)
79245);
79246}
79247
79248/* ActualSessionTimeout - ns=0;i=2204 */
79249
79250static UA_StatusCode function_namespace0_generated_381_begin(UA_Server *server, UA_UInt16* ns) {
79251UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79252UA_VariableAttributes attr = UA_VariableAttributes_default;
79253attr.minimumSamplingInterval = 0.000000;
79254attr.userAccessLevel = 1;
79255attr.accessLevel = 1;
79256/* Value rank inherited */
79257attr.valueRank = -2;
79258attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU);
79259attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ActualSessionTimeout");
79260retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79261requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2204LU),
79262parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79263referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79264browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ActualSessionTimeout"),
79265typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79266attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79267if (retVal != UA_STATUSCODE_GOOD) return retVal;
79268return retVal;
79269}
79270
79271static UA_StatusCode function_namespace0_generated_381_finish(UA_Server *server, UA_UInt16* ns) {
79272return UA_Server_addNode_finish(server,
79273nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2204LU)
79274);
79275}
79276
79277/* LocaleIds - ns=0;i=2203 */
79278
79279static UA_StatusCode function_namespace0_generated_382_begin(UA_Server *server, UA_UInt16* ns) {
79280UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79281UA_VariableAttributes attr = UA_VariableAttributes_default;
79282attr.minimumSamplingInterval = 0.000000;
79283attr.userAccessLevel = 1;
79284attr.accessLevel = 1;
79285attr.valueRank = 1;
79286attr.arrayDimensionsSize = 1;
79287UA_UInt32 arrayDimensions[1];
79288arrayDimensions[0] = 0;
79289attr.arrayDimensions = &arrayDimensions[0];
79290attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 295LU);
79291attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "LocaleIds");
79292retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79293requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2203LU),
79294parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79295referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79296browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "LocaleIds"),
79297typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79298attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79299if (retVal != UA_STATUSCODE_GOOD) return retVal;
79300return retVal;
79301}
79302
79303static UA_StatusCode function_namespace0_generated_382_finish(UA_Server *server, UA_UInt16* ns) {
79304return UA_Server_addNode_finish(server,
79305nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2203LU)
79306);
79307}
79308
79309/* EndpointUrl - ns=0;i=2202 */
79310
79311static UA_StatusCode function_namespace0_generated_383_begin(UA_Server *server, UA_UInt16* ns) {
79312UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79313UA_VariableAttributes attr = UA_VariableAttributes_default;
79314attr.minimumSamplingInterval = 0.000000;
79315attr.userAccessLevel = 1;
79316attr.accessLevel = 1;
79317/* Value rank inherited */
79318attr.valueRank = -2;
79319attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
79320attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EndpointUrl");
79321retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79322requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2202LU),
79323parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79324referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79325browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EndpointUrl"),
79326typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79327attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79328if (retVal != UA_STATUSCODE_GOOD) return retVal;
79329return retVal;
79330}
79331
79332static UA_StatusCode function_namespace0_generated_383_finish(UA_Server *server, UA_UInt16* ns) {
79333return UA_Server_addNode_finish(server,
79334nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2202LU)
79335);
79336}
79337
79338/* ServerUri - ns=0;i=2201 */
79339
79340static UA_StatusCode function_namespace0_generated_384_begin(UA_Server *server, UA_UInt16* ns) {
79341UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79342UA_VariableAttributes attr = UA_VariableAttributes_default;
79343attr.minimumSamplingInterval = 0.000000;
79344attr.userAccessLevel = 1;
79345attr.accessLevel = 1;
79346/* Value rank inherited */
79347attr.valueRank = -2;
79348attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
79349attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerUri");
79350retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79351requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2201LU),
79352parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79353referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79354browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerUri"),
79355typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79356attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79357if (retVal != UA_STATUSCODE_GOOD) return retVal;
79358return retVal;
79359}
79360
79361static UA_StatusCode function_namespace0_generated_384_finish(UA_Server *server, UA_UInt16* ns) {
79362return UA_Server_addNode_finish(server,
79363nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2201LU)
79364);
79365}
79366
79367/* ClientDescription - ns=0;i=2200 */
79368
79369static UA_StatusCode function_namespace0_generated_385_begin(UA_Server *server, UA_UInt16* ns) {
79370UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79371UA_VariableAttributes attr = UA_VariableAttributes_default;
79372attr.minimumSamplingInterval = 0.000000;
79373attr.userAccessLevel = 1;
79374attr.accessLevel = 1;
79375/* Value rank inherited */
79376attr.valueRank = -2;
79377attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 308LU);
79378attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientDescription");
79379retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79380requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2200LU),
79381parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79382referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79383browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientDescription"),
79384typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79385attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79386if (retVal != UA_STATUSCODE_GOOD) return retVal;
79387return retVal;
79388}
79389
79390static UA_StatusCode function_namespace0_generated_385_finish(UA_Server *server, UA_UInt16* ns) {
79391return UA_Server_addNode_finish(server,
79392nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2200LU)
79393);
79394}
79395
79396/* SessionName - ns=0;i=2199 */
79397
79398static UA_StatusCode function_namespace0_generated_386_begin(UA_Server *server, UA_UInt16* ns) {
79399UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79400UA_VariableAttributes attr = UA_VariableAttributes_default;
79401attr.minimumSamplingInterval = 0.000000;
79402attr.userAccessLevel = 1;
79403attr.accessLevel = 1;
79404/* Value rank inherited */
79405attr.valueRank = -2;
79406attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
79407attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionName");
79408retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79409requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2199LU),
79410parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79411referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79412browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionName"),
79413typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79414attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79415if (retVal != UA_STATUSCODE_GOOD) return retVal;
79416return retVal;
79417}
79418
79419static UA_StatusCode function_namespace0_generated_386_finish(UA_Server *server, UA_UInt16* ns) {
79420return UA_Server_addNode_finish(server,
79421nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2199LU)
79422);
79423}
79424
79425/* SessionId - ns=0;i=2198 */
79426
79427static UA_StatusCode function_namespace0_generated_387_begin(UA_Server *server, UA_UInt16* ns) {
79428UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79429UA_VariableAttributes attr = UA_VariableAttributes_default;
79430attr.minimumSamplingInterval = 0.000000;
79431attr.userAccessLevel = 1;
79432attr.accessLevel = 1;
79433/* Value rank inherited */
79434attr.valueRank = -2;
79435attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
79436attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionId");
79437retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79438requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2198LU),
79439parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79440referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79441browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionId"),
79442typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79443attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79444if (retVal != UA_STATUSCODE_GOOD) return retVal;
79445return retVal;
79446}
79447
79448static UA_StatusCode function_namespace0_generated_387_finish(UA_Server *server, UA_UInt16* ns) {
79449return UA_Server_addNode_finish(server,
79450nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2198LU)
79451);
79452}
79453
79454/* UnauthorizedRequestCount - ns=0;i=11892 */
79455
79456static UA_StatusCode function_namespace0_generated_388_begin(UA_Server *server, UA_UInt16* ns) {
79457UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79458UA_VariableAttributes attr = UA_VariableAttributes_default;
79459attr.minimumSamplingInterval = 0.000000;
79460attr.userAccessLevel = 1;
79461attr.accessLevel = 1;
79462/* Value rank inherited */
79463attr.valueRank = -2;
79464attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79465attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UnauthorizedRequestCount");
79466retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79467requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11892LU),
79468parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
79469referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79470browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UnauthorizedRequestCount"),
79471typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79472attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79473if (retVal != UA_STATUSCODE_GOOD) return retVal;
79474return retVal;
79475}
79476
79477static UA_StatusCode function_namespace0_generated_388_finish(UA_Server *server, UA_UInt16* ns) {
79478return UA_Server_addNode_finish(server,
79479nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11892LU)
79480);
79481}
79482
79483/* SubscriptionDiagnosticsType - ns=0;i=2172 */
79484
79485static UA_StatusCode function_namespace0_generated_389_begin(UA_Server *server, UA_UInt16* ns) {
79486UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79487UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
79488/* Value rank inherited */
79489attr.valueRank = -2;
79490attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 874LU);
79491attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscriptionDiagnosticsType");
79492retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
79493requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79494parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79495referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
79496browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscriptionDiagnosticsType"),
79497typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
79498attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
79499if (retVal != UA_STATUSCODE_GOOD) return retVal;
79500return retVal;
79501}
79502
79503static UA_StatusCode function_namespace0_generated_389_finish(UA_Server *server, UA_UInt16* ns) {
79504return UA_Server_addNode_finish(server,
79505nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU)
79506);
79507}
79508
79509/* EventQueueOverflowCount - ns=0;i=8902 */
79510
79511static UA_StatusCode function_namespace0_generated_390_begin(UA_Server *server, UA_UInt16* ns) {
79512UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79513UA_VariableAttributes attr = UA_VariableAttributes_default;
79514attr.minimumSamplingInterval = 0.000000;
79515attr.userAccessLevel = 1;
79516attr.accessLevel = 1;
79517/* Value rank inherited */
79518attr.valueRank = -2;
79519attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79520attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EventQueueOverflowCount");
79521retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79522requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8902LU),
79523parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79524referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79525browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EventQueueOverflowCount"),
79526typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79527attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79528if (retVal != UA_STATUSCODE_GOOD) return retVal;
79529return retVal;
79530}
79531
79532static UA_StatusCode function_namespace0_generated_390_finish(UA_Server *server, UA_UInt16* ns) {
79533return UA_Server_addNode_finish(server,
79534nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8902LU)
79535);
79536}
79537
79538/* NextSequenceNumber - ns=0;i=8897 */
79539
79540static UA_StatusCode function_namespace0_generated_391_begin(UA_Server *server, UA_UInt16* ns) {
79541UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79542UA_VariableAttributes attr = UA_VariableAttributes_default;
79543attr.minimumSamplingInterval = 0.000000;
79544attr.userAccessLevel = 1;
79545attr.accessLevel = 1;
79546/* Value rank inherited */
79547attr.valueRank = -2;
79548attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79549attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NextSequenceNumber");
79550retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79551requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8897LU),
79552parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79553referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79554browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NextSequenceNumber"),
79555typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79556attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79557if (retVal != UA_STATUSCODE_GOOD) return retVal;
79558return retVal;
79559}
79560
79561static UA_StatusCode function_namespace0_generated_391_finish(UA_Server *server, UA_UInt16* ns) {
79562return UA_Server_addNode_finish(server,
79563nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8897LU)
79564);
79565}
79566
79567/* MonitoringQueueOverflowCount - ns=0;i=8896 */
79568
79569static UA_StatusCode function_namespace0_generated_392_begin(UA_Server *server, UA_UInt16* ns) {
79570UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79571UA_VariableAttributes attr = UA_VariableAttributes_default;
79572attr.minimumSamplingInterval = 0.000000;
79573attr.userAccessLevel = 1;
79574attr.accessLevel = 1;
79575/* Value rank inherited */
79576attr.valueRank = -2;
79577attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79578attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MonitoringQueueOverflowCount");
79579retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79580requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8896LU),
79581parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79582referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79583browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MonitoringQueueOverflowCount"),
79584typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79585attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79586if (retVal != UA_STATUSCODE_GOOD) return retVal;
79587return retVal;
79588}
79589
79590static UA_StatusCode function_namespace0_generated_392_finish(UA_Server *server, UA_UInt16* ns) {
79591return UA_Server_addNode_finish(server,
79592nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8896LU)
79593);
79594}
79595
79596/* DisabledMonitoredItemCount - ns=0;i=8895 */
79597
79598static UA_StatusCode function_namespace0_generated_393_begin(UA_Server *server, UA_UInt16* ns) {
79599UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79600UA_VariableAttributes attr = UA_VariableAttributes_default;
79601attr.minimumSamplingInterval = 0.000000;
79602attr.userAccessLevel = 1;
79603attr.accessLevel = 1;
79604/* Value rank inherited */
79605attr.valueRank = -2;
79606attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79607attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DisabledMonitoredItemCount");
79608retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79609requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8895LU),
79610parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79611referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79612browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DisabledMonitoredItemCount"),
79613typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79614attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79615if (retVal != UA_STATUSCODE_GOOD) return retVal;
79616return retVal;
79617}
79618
79619static UA_StatusCode function_namespace0_generated_393_finish(UA_Server *server, UA_UInt16* ns) {
79620return UA_Server_addNode_finish(server,
79621nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8895LU)
79622);
79623}
79624
79625/* MonitoredItemCount - ns=0;i=8894 */
79626
79627static UA_StatusCode function_namespace0_generated_394_begin(UA_Server *server, UA_UInt16* ns) {
79628UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79629UA_VariableAttributes attr = UA_VariableAttributes_default;
79630attr.minimumSamplingInterval = 0.000000;
79631attr.userAccessLevel = 1;
79632attr.accessLevel = 1;
79633/* Value rank inherited */
79634attr.valueRank = -2;
79635attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79636attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MonitoredItemCount");
79637retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79638requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8894LU),
79639parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79640referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79641browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MonitoredItemCount"),
79642typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79643attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79644if (retVal != UA_STATUSCODE_GOOD) return retVal;
79645return retVal;
79646}
79647
79648static UA_StatusCode function_namespace0_generated_394_finish(UA_Server *server, UA_UInt16* ns) {
79649return UA_Server_addNode_finish(server,
79650nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8894LU)
79651);
79652}
79653
79654/* DiscardedMessageCount - ns=0;i=8893 */
79655
79656static UA_StatusCode function_namespace0_generated_395_begin(UA_Server *server, UA_UInt16* ns) {
79657UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79658UA_VariableAttributes attr = UA_VariableAttributes_default;
79659attr.minimumSamplingInterval = 0.000000;
79660attr.userAccessLevel = 1;
79661attr.accessLevel = 1;
79662/* Value rank inherited */
79663attr.valueRank = -2;
79664attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79665attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DiscardedMessageCount");
79666retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79667requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8893LU),
79668parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79669referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79670browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DiscardedMessageCount"),
79671typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79672attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79673if (retVal != UA_STATUSCODE_GOOD) return retVal;
79674return retVal;
79675}
79676
79677static UA_StatusCode function_namespace0_generated_395_finish(UA_Server *server, UA_UInt16* ns) {
79678return UA_Server_addNode_finish(server,
79679nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8893LU)
79680);
79681}
79682
79683/* UnacknowledgedMessageCount - ns=0;i=8892 */
79684
79685static UA_StatusCode function_namespace0_generated_396_begin(UA_Server *server, UA_UInt16* ns) {
79686UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79687UA_VariableAttributes attr = UA_VariableAttributes_default;
79688attr.minimumSamplingInterval = 0.000000;
79689attr.userAccessLevel = 1;
79690attr.accessLevel = 1;
79691/* Value rank inherited */
79692attr.valueRank = -2;
79693attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79694attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UnacknowledgedMessageCount");
79695retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79696requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8892LU),
79697parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79698referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79699browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UnacknowledgedMessageCount"),
79700typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79701attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79702if (retVal != UA_STATUSCODE_GOOD) return retVal;
79703return retVal;
79704}
79705
79706static UA_StatusCode function_namespace0_generated_396_finish(UA_Server *server, UA_UInt16* ns) {
79707return UA_Server_addNode_finish(server,
79708nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8892LU)
79709);
79710}
79711
79712/* CurrentLifetimeCount - ns=0;i=8891 */
79713
79714static UA_StatusCode function_namespace0_generated_397_begin(UA_Server *server, UA_UInt16* ns) {
79715UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79716UA_VariableAttributes attr = UA_VariableAttributes_default;
79717attr.minimumSamplingInterval = 0.000000;
79718attr.userAccessLevel = 1;
79719attr.accessLevel = 1;
79720/* Value rank inherited */
79721attr.valueRank = -2;
79722attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79723attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentLifetimeCount");
79724retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79725requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8891LU),
79726parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79727referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79728browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentLifetimeCount"),
79729typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79730attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79731if (retVal != UA_STATUSCODE_GOOD) return retVal;
79732return retVal;
79733}
79734
79735static UA_StatusCode function_namespace0_generated_397_finish(UA_Server *server, UA_UInt16* ns) {
79736return UA_Server_addNode_finish(server,
79737nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8891LU)
79738);
79739}
79740
79741/* CurrentKeepAliveCount - ns=0;i=8890 */
79742
79743static UA_StatusCode function_namespace0_generated_398_begin(UA_Server *server, UA_UInt16* ns) {
79744UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79745UA_VariableAttributes attr = UA_VariableAttributes_default;
79746attr.minimumSamplingInterval = 0.000000;
79747attr.userAccessLevel = 1;
79748attr.accessLevel = 1;
79749/* Value rank inherited */
79750attr.valueRank = -2;
79751attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79752attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentKeepAliveCount");
79753retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79754requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8890LU),
79755parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79756referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79757browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentKeepAliveCount"),
79758typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79759attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79760if (retVal != UA_STATUSCODE_GOOD) return retVal;
79761return retVal;
79762}
79763
79764static UA_StatusCode function_namespace0_generated_398_finish(UA_Server *server, UA_UInt16* ns) {
79765return UA_Server_addNode_finish(server,
79766nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8890LU)
79767);
79768}
79769
79770/* LatePublishRequestCount - ns=0;i=8889 */
79771
79772static UA_StatusCode function_namespace0_generated_399_begin(UA_Server *server, UA_UInt16* ns) {
79773UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79774UA_VariableAttributes attr = UA_VariableAttributes_default;
79775attr.minimumSamplingInterval = 0.000000;
79776attr.userAccessLevel = 1;
79777attr.accessLevel = 1;
79778/* Value rank inherited */
79779attr.valueRank = -2;
79780attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79781attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "LatePublishRequestCount");
79782retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79783requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8889LU),
79784parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79785referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79786browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "LatePublishRequestCount"),
79787typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79788attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79789if (retVal != UA_STATUSCODE_GOOD) return retVal;
79790return retVal;
79791}
79792
79793static UA_StatusCode function_namespace0_generated_399_finish(UA_Server *server, UA_UInt16* ns) {
79794return UA_Server_addNode_finish(server,
79795nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8889LU)
79796);
79797}
79798
79799/* MaxLifetimeCount - ns=0;i=8888 */
79800
79801static UA_StatusCode function_namespace0_generated_400_begin(UA_Server *server, UA_UInt16* ns) {
79802UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79803UA_VariableAttributes attr = UA_VariableAttributes_default;
79804attr.minimumSamplingInterval = 0.000000;
79805attr.userAccessLevel = 1;
79806attr.accessLevel = 1;
79807/* Value rank inherited */
79808attr.valueRank = -2;
79809attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79810attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxLifetimeCount");
79811retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79812requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8888LU),
79813parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79814referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79815browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxLifetimeCount"),
79816typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79817attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79818if (retVal != UA_STATUSCODE_GOOD) return retVal;
79819return retVal;
79820}
79821
79822static UA_StatusCode function_namespace0_generated_400_finish(UA_Server *server, UA_UInt16* ns) {
79823return UA_Server_addNode_finish(server,
79824nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8888LU)
79825);
79826}
79827
79828/* EventNotificationsCount - ns=0;i=2998 */
79829
79830static UA_StatusCode function_namespace0_generated_401_begin(UA_Server *server, UA_UInt16* ns) {
79831UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79832UA_VariableAttributes attr = UA_VariableAttributes_default;
79833attr.minimumSamplingInterval = 0.000000;
79834attr.userAccessLevel = 1;
79835attr.accessLevel = 1;
79836/* Value rank inherited */
79837attr.valueRank = -2;
79838attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79839attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EventNotificationsCount");
79840retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79841requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2998LU),
79842parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79843referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79844browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EventNotificationsCount"),
79845typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79846attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79847if (retVal != UA_STATUSCODE_GOOD) return retVal;
79848return retVal;
79849}
79850
79851static UA_StatusCode function_namespace0_generated_401_finish(UA_Server *server, UA_UInt16* ns) {
79852return UA_Server_addNode_finish(server,
79853nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2998LU)
79854);
79855}
79856
79857/* NotificationsCount - ns=0;i=2193 */
79858
79859static UA_StatusCode function_namespace0_generated_402_begin(UA_Server *server, UA_UInt16* ns) {
79860UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79861UA_VariableAttributes attr = UA_VariableAttributes_default;
79862attr.minimumSamplingInterval = 0.000000;
79863attr.userAccessLevel = 1;
79864attr.accessLevel = 1;
79865/* Value rank inherited */
79866attr.valueRank = -2;
79867attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79868attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NotificationsCount");
79869retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79870requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2193LU),
79871parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79872referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79873browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NotificationsCount"),
79874typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79875attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79876if (retVal != UA_STATUSCODE_GOOD) return retVal;
79877return retVal;
79878}
79879
79880static UA_StatusCode function_namespace0_generated_402_finish(UA_Server *server, UA_UInt16* ns) {
79881return UA_Server_addNode_finish(server,
79882nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2193LU)
79883);
79884}
79885
79886/* DataChangeNotificationsCount - ns=0;i=2191 */
79887
79888static UA_StatusCode function_namespace0_generated_403_begin(UA_Server *server, UA_UInt16* ns) {
79889UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79890UA_VariableAttributes attr = UA_VariableAttributes_default;
79891attr.minimumSamplingInterval = 0.000000;
79892attr.userAccessLevel = 1;
79893attr.accessLevel = 1;
79894/* Value rank inherited */
79895attr.valueRank = -2;
79896attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79897attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataChangeNotificationsCount");
79898retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79899requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2191LU),
79900parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79901referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79902browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataChangeNotificationsCount"),
79903typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79904attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79905if (retVal != UA_STATUSCODE_GOOD) return retVal;
79906return retVal;
79907}
79908
79909static UA_StatusCode function_namespace0_generated_403_finish(UA_Server *server, UA_UInt16* ns) {
79910return UA_Server_addNode_finish(server,
79911nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2191LU)
79912);
79913}
79914
79915/* PublishRequestCount - ns=0;i=2190 */
79916
79917static UA_StatusCode function_namespace0_generated_404_begin(UA_Server *server, UA_UInt16* ns) {
79918UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79919UA_VariableAttributes attr = UA_VariableAttributes_default;
79920attr.minimumSamplingInterval = 0.000000;
79921attr.userAccessLevel = 1;
79922attr.accessLevel = 1;
79923/* Value rank inherited */
79924attr.valueRank = -2;
79925attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79926attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishRequestCount");
79927retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79928requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2190LU),
79929parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79930referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79931browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishRequestCount"),
79932typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79933attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79934if (retVal != UA_STATUSCODE_GOOD) return retVal;
79935return retVal;
79936}
79937
79938static UA_StatusCode function_namespace0_generated_404_finish(UA_Server *server, UA_UInt16* ns) {
79939return UA_Server_addNode_finish(server,
79940nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2190LU)
79941);
79942}
79943
79944/* TransferredToSameClientCount - ns=0;i=2189 */
79945
79946static UA_StatusCode function_namespace0_generated_405_begin(UA_Server *server, UA_UInt16* ns) {
79947UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79948UA_VariableAttributes attr = UA_VariableAttributes_default;
79949attr.minimumSamplingInterval = 0.000000;
79950attr.userAccessLevel = 1;
79951attr.accessLevel = 1;
79952/* Value rank inherited */
79953attr.valueRank = -2;
79954attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79955attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransferredToSameClientCount");
79956retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79957requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2189LU),
79958parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79959referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79960browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransferredToSameClientCount"),
79961typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79962attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79963if (retVal != UA_STATUSCODE_GOOD) return retVal;
79964return retVal;
79965}
79966
79967static UA_StatusCode function_namespace0_generated_405_finish(UA_Server *server, UA_UInt16* ns) {
79968return UA_Server_addNode_finish(server,
79969nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2189LU)
79970);
79971}
79972
79973/* TransferredToAltClientCount - ns=0;i=2188 */
79974
79975static UA_StatusCode function_namespace0_generated_406_begin(UA_Server *server, UA_UInt16* ns) {
79976UA_StatusCode retVal = UA_STATUSCODE_GOOD;
79977UA_VariableAttributes attr = UA_VariableAttributes_default;
79978attr.minimumSamplingInterval = 0.000000;
79979attr.userAccessLevel = 1;
79980attr.accessLevel = 1;
79981/* Value rank inherited */
79982attr.valueRank = -2;
79983attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
79984attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransferredToAltClientCount");
79985retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
79986requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2188LU),
79987parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
79988referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
79989browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransferredToAltClientCount"),
79990typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
79991attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
79992if (retVal != UA_STATUSCODE_GOOD) return retVal;
79993return retVal;
79994}
79995
79996static UA_StatusCode function_namespace0_generated_406_finish(UA_Server *server, UA_UInt16* ns) {
79997return UA_Server_addNode_finish(server,
79998nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2188LU)
79999);
80000}
80001
80002/* TransferRequestCount - ns=0;i=2187 */
80003
80004static UA_StatusCode function_namespace0_generated_407_begin(UA_Server *server, UA_UInt16* ns) {
80005UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80006UA_VariableAttributes attr = UA_VariableAttributes_default;
80007attr.minimumSamplingInterval = 0.000000;
80008attr.userAccessLevel = 1;
80009attr.accessLevel = 1;
80010/* Value rank inherited */
80011attr.valueRank = -2;
80012attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80013attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransferRequestCount");
80014retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80015requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2187LU),
80016parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80017referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80018browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransferRequestCount"),
80019typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80020attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80021if (retVal != UA_STATUSCODE_GOOD) return retVal;
80022return retVal;
80023}
80024
80025static UA_StatusCode function_namespace0_generated_407_finish(UA_Server *server, UA_UInt16* ns) {
80026return UA_Server_addNode_finish(server,
80027nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2187LU)
80028);
80029}
80030
80031/* RepublishMessageCount - ns=0;i=2186 */
80032
80033static UA_StatusCode function_namespace0_generated_408_begin(UA_Server *server, UA_UInt16* ns) {
80034UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80035UA_VariableAttributes attr = UA_VariableAttributes_default;
80036attr.minimumSamplingInterval = 0.000000;
80037attr.userAccessLevel = 1;
80038attr.accessLevel = 1;
80039/* Value rank inherited */
80040attr.valueRank = -2;
80041attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80042attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RepublishMessageCount");
80043retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80044requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2186LU),
80045parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80046referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80047browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RepublishMessageCount"),
80048typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80049attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80050if (retVal != UA_STATUSCODE_GOOD) return retVal;
80051return retVal;
80052}
80053
80054static UA_StatusCode function_namespace0_generated_408_finish(UA_Server *server, UA_UInt16* ns) {
80055return UA_Server_addNode_finish(server,
80056nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2186LU)
80057);
80058}
80059
80060/* RepublishMessageRequestCount - ns=0;i=2185 */
80061
80062static UA_StatusCode function_namespace0_generated_409_begin(UA_Server *server, UA_UInt16* ns) {
80063UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80064UA_VariableAttributes attr = UA_VariableAttributes_default;
80065attr.minimumSamplingInterval = 0.000000;
80066attr.userAccessLevel = 1;
80067attr.accessLevel = 1;
80068/* Value rank inherited */
80069attr.valueRank = -2;
80070attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80071attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RepublishMessageRequestCount");
80072retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80073requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2185LU),
80074parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80075referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80076browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RepublishMessageRequestCount"),
80077typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80078attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80079if (retVal != UA_STATUSCODE_GOOD) return retVal;
80080return retVal;
80081}
80082
80083static UA_StatusCode function_namespace0_generated_409_finish(UA_Server *server, UA_UInt16* ns) {
80084return UA_Server_addNode_finish(server,
80085nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2185LU)
80086);
80087}
80088
80089/* RepublishRequestCount - ns=0;i=2184 */
80090
80091static UA_StatusCode function_namespace0_generated_410_begin(UA_Server *server, UA_UInt16* ns) {
80092UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80093UA_VariableAttributes attr = UA_VariableAttributes_default;
80094attr.minimumSamplingInterval = 0.000000;
80095attr.userAccessLevel = 1;
80096attr.accessLevel = 1;
80097/* Value rank inherited */
80098attr.valueRank = -2;
80099attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80100attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RepublishRequestCount");
80101retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80102requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2184LU),
80103parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80104referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80105browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RepublishRequestCount"),
80106typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80107attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80108if (retVal != UA_STATUSCODE_GOOD) return retVal;
80109return retVal;
80110}
80111
80112static UA_StatusCode function_namespace0_generated_410_finish(UA_Server *server, UA_UInt16* ns) {
80113return UA_Server_addNode_finish(server,
80114nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2184LU)
80115);
80116}
80117
80118/* DisableCount - ns=0;i=2183 */
80119
80120static UA_StatusCode function_namespace0_generated_411_begin(UA_Server *server, UA_UInt16* ns) {
80121UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80122UA_VariableAttributes attr = UA_VariableAttributes_default;
80123attr.minimumSamplingInterval = 0.000000;
80124attr.userAccessLevel = 1;
80125attr.accessLevel = 1;
80126/* Value rank inherited */
80127attr.valueRank = -2;
80128attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80129attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DisableCount");
80130retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80131requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2183LU),
80132parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80133referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80134browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DisableCount"),
80135typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80136attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80137if (retVal != UA_STATUSCODE_GOOD) return retVal;
80138return retVal;
80139}
80140
80141static UA_StatusCode function_namespace0_generated_411_finish(UA_Server *server, UA_UInt16* ns) {
80142return UA_Server_addNode_finish(server,
80143nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2183LU)
80144);
80145}
80146
80147/* EnableCount - ns=0;i=2182 */
80148
80149static UA_StatusCode function_namespace0_generated_412_begin(UA_Server *server, UA_UInt16* ns) {
80150UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80151UA_VariableAttributes attr = UA_VariableAttributes_default;
80152attr.minimumSamplingInterval = 0.000000;
80153attr.userAccessLevel = 1;
80154attr.accessLevel = 1;
80155/* Value rank inherited */
80156attr.valueRank = -2;
80157attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80158attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnableCount");
80159retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80160requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2182LU),
80161parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80162referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80163browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnableCount"),
80164typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80165attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80166if (retVal != UA_STATUSCODE_GOOD) return retVal;
80167return retVal;
80168}
80169
80170static UA_StatusCode function_namespace0_generated_412_finish(UA_Server *server, UA_UInt16* ns) {
80171return UA_Server_addNode_finish(server,
80172nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2182LU)
80173);
80174}
80175
80176/* ModifyCount - ns=0;i=2181 */
80177
80178static UA_StatusCode function_namespace0_generated_413_begin(UA_Server *server, UA_UInt16* ns) {
80179UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80180UA_VariableAttributes attr = UA_VariableAttributes_default;
80181attr.minimumSamplingInterval = 0.000000;
80182attr.userAccessLevel = 1;
80183attr.accessLevel = 1;
80184/* Value rank inherited */
80185attr.valueRank = -2;
80186attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80187attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ModifyCount");
80188retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80189requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2181LU),
80190parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80191referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80192browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ModifyCount"),
80193typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80194attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80195if (retVal != UA_STATUSCODE_GOOD) return retVal;
80196return retVal;
80197}
80198
80199static UA_StatusCode function_namespace0_generated_413_finish(UA_Server *server, UA_UInt16* ns) {
80200return UA_Server_addNode_finish(server,
80201nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2181LU)
80202);
80203}
80204
80205/* PublishingEnabled - ns=0;i=2180 */
80206
80207static UA_StatusCode function_namespace0_generated_414_begin(UA_Server *server, UA_UInt16* ns) {
80208UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80209UA_VariableAttributes attr = UA_VariableAttributes_default;
80210attr.minimumSamplingInterval = 0.000000;
80211attr.userAccessLevel = 1;
80212attr.accessLevel = 1;
80213/* Value rank inherited */
80214attr.valueRank = -2;
80215attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
80216attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishingEnabled");
80217retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80218requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2180LU),
80219parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80220referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80221browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishingEnabled"),
80222typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80223attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80224if (retVal != UA_STATUSCODE_GOOD) return retVal;
80225return retVal;
80226}
80227
80228static UA_StatusCode function_namespace0_generated_414_finish(UA_Server *server, UA_UInt16* ns) {
80229return UA_Server_addNode_finish(server,
80230nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2180LU)
80231);
80232}
80233
80234/* MaxNotificationsPerPublish - ns=0;i=2179 */
80235
80236static UA_StatusCode function_namespace0_generated_415_begin(UA_Server *server, UA_UInt16* ns) {
80237UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80238UA_VariableAttributes attr = UA_VariableAttributes_default;
80239attr.minimumSamplingInterval = 0.000000;
80240attr.userAccessLevel = 1;
80241attr.accessLevel = 1;
80242/* Value rank inherited */
80243attr.valueRank = -2;
80244attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80245attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNotificationsPerPublish");
80246retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80247requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2179LU),
80248parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80249referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80250browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNotificationsPerPublish"),
80251typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80252attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80253if (retVal != UA_STATUSCODE_GOOD) return retVal;
80254return retVal;
80255}
80256
80257static UA_StatusCode function_namespace0_generated_415_finish(UA_Server *server, UA_UInt16* ns) {
80258return UA_Server_addNode_finish(server,
80259nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2179LU)
80260);
80261}
80262
80263/* MaxKeepAliveCount - ns=0;i=2177 */
80264
80265static UA_StatusCode function_namespace0_generated_416_begin(UA_Server *server, UA_UInt16* ns) {
80266UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80267UA_VariableAttributes attr = UA_VariableAttributes_default;
80268attr.minimumSamplingInterval = 0.000000;
80269attr.userAccessLevel = 1;
80270attr.accessLevel = 1;
80271/* Value rank inherited */
80272attr.valueRank = -2;
80273attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80274attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxKeepAliveCount");
80275retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80276requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2177LU),
80277parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80278referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80279browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxKeepAliveCount"),
80280typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80281attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80282if (retVal != UA_STATUSCODE_GOOD) return retVal;
80283return retVal;
80284}
80285
80286static UA_StatusCode function_namespace0_generated_416_finish(UA_Server *server, UA_UInt16* ns) {
80287return UA_Server_addNode_finish(server,
80288nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2177LU)
80289);
80290}
80291
80292/* PublishingInterval - ns=0;i=2176 */
80293
80294static UA_StatusCode function_namespace0_generated_417_begin(UA_Server *server, UA_UInt16* ns) {
80295UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80296UA_VariableAttributes attr = UA_VariableAttributes_default;
80297attr.minimumSamplingInterval = 0.000000;
80298attr.userAccessLevel = 1;
80299attr.accessLevel = 1;
80300/* Value rank inherited */
80301attr.valueRank = -2;
80302attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU);
80303attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishingInterval");
80304retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80305requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2176LU),
80306parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80307referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80308browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishingInterval"),
80309typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80310attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80311if (retVal != UA_STATUSCODE_GOOD) return retVal;
80312return retVal;
80313}
80314
80315static UA_StatusCode function_namespace0_generated_417_finish(UA_Server *server, UA_UInt16* ns) {
80316return UA_Server_addNode_finish(server,
80317nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2176LU)
80318);
80319}
80320
80321/* Priority - ns=0;i=2175 */
80322
80323static UA_StatusCode function_namespace0_generated_418_begin(UA_Server *server, UA_UInt16* ns) {
80324UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80325UA_VariableAttributes attr = UA_VariableAttributes_default;
80326attr.minimumSamplingInterval = 0.000000;
80327attr.userAccessLevel = 1;
80328attr.accessLevel = 1;
80329/* Value rank inherited */
80330attr.valueRank = -2;
80331attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3LU);
80332attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Priority");
80333retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80334requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2175LU),
80335parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80336referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80337browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Priority"),
80338typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80339attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80340if (retVal != UA_STATUSCODE_GOOD) return retVal;
80341return retVal;
80342}
80343
80344static UA_StatusCode function_namespace0_generated_418_finish(UA_Server *server, UA_UInt16* ns) {
80345return UA_Server_addNode_finish(server,
80346nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2175LU)
80347);
80348}
80349
80350/* SubscriptionId - ns=0;i=2174 */
80351
80352static UA_StatusCode function_namespace0_generated_419_begin(UA_Server *server, UA_UInt16* ns) {
80353UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80354UA_VariableAttributes attr = UA_VariableAttributes_default;
80355attr.minimumSamplingInterval = 0.000000;
80356attr.userAccessLevel = 1;
80357attr.accessLevel = 1;
80358/* Value rank inherited */
80359attr.valueRank = -2;
80360attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80361attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscriptionId");
80362retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80363requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2174LU),
80364parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80365referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80366browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscriptionId"),
80367typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80368attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80369if (retVal != UA_STATUSCODE_GOOD) return retVal;
80370return retVal;
80371}
80372
80373static UA_StatusCode function_namespace0_generated_419_finish(UA_Server *server, UA_UInt16* ns) {
80374return UA_Server_addNode_finish(server,
80375nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2174LU)
80376);
80377}
80378
80379/* SessionId - ns=0;i=2173 */
80380
80381static UA_StatusCode function_namespace0_generated_420_begin(UA_Server *server, UA_UInt16* ns) {
80382UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80383UA_VariableAttributes attr = UA_VariableAttributes_default;
80384attr.minimumSamplingInterval = 0.000000;
80385attr.userAccessLevel = 1;
80386attr.accessLevel = 1;
80387/* Value rank inherited */
80388attr.valueRank = -2;
80389attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
80390attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionId");
80391retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80392requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2173LU),
80393parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80394referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80395browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionId"),
80396typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80397attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80398if (retVal != UA_STATUSCODE_GOOD) return retVal;
80399return retVal;
80400}
80401
80402static UA_StatusCode function_namespace0_generated_420_finish(UA_Server *server, UA_UInt16* ns) {
80403return UA_Server_addNode_finish(server,
80404nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2173LU)
80405);
80406}
80407
80408/* SubscriptionDiagnosticsArrayType - ns=0;i=2171 */
80409
80410static UA_StatusCode function_namespace0_generated_421_begin(UA_Server *server, UA_UInt16* ns) {
80411UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80412UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
80413attr.valueRank = 1;
80414attr.arrayDimensionsSize = 1;
80415UA_UInt32 arrayDimensions[1];
80416arrayDimensions[0] = 0;
80417attr.arrayDimensions = &arrayDimensions[0];
80418attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 874LU);
80419attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscriptionDiagnosticsArrayType");
80420retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
80421requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2171LU),
80422parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80423referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
80424browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscriptionDiagnosticsArrayType"),
80425typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
80426attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
80427if (retVal != UA_STATUSCODE_GOOD) return retVal;
80428return retVal;
80429}
80430
80431static UA_StatusCode function_namespace0_generated_421_finish(UA_Server *server, UA_UInt16* ns) {
80432return UA_Server_addNode_finish(server,
80433nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2171LU)
80434);
80435}
80436
80437/* SubscriptionDiagnostics - ns=0;i=12784 */
80438
80439static UA_StatusCode function_namespace0_generated_422_begin(UA_Server *server, UA_UInt16* ns) {
80440UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80441UA_VariableAttributes attr = UA_VariableAttributes_default;
80442attr.minimumSamplingInterval = 0.000000;
80443attr.userAccessLevel = 1;
80444attr.accessLevel = 1;
80445/* Value rank inherited */
80446attr.valueRank = -2;
80447attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 874LU);
80448attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscriptionDiagnostics");
80449retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80450requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80451parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2171LU),
80452referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80453browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscriptionDiagnostics"),
80454typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2172LU),
80455attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80456if (retVal != UA_STATUSCODE_GOOD) return retVal;
80457return retVal;
80458}
80459
80460static UA_StatusCode function_namespace0_generated_422_finish(UA_Server *server, UA_UInt16* ns) {
80461return UA_Server_addNode_finish(server,
80462nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU)
80463);
80464}
80465
80466/* EventQueueOverflowCount - ns=0;i=12815 */
80467
80468static UA_StatusCode function_namespace0_generated_423_begin(UA_Server *server, UA_UInt16* ns) {
80469UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80470UA_VariableAttributes attr = UA_VariableAttributes_default;
80471attr.minimumSamplingInterval = 0.000000;
80472attr.userAccessLevel = 1;
80473attr.accessLevel = 1;
80474/* Value rank inherited */
80475attr.valueRank = -2;
80476attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80477attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EventQueueOverflowCount");
80478retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80479requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12815LU),
80480parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80481referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80482browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EventQueueOverflowCount"),
80483typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80484attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80485if (retVal != UA_STATUSCODE_GOOD) return retVal;
80486return retVal;
80487}
80488
80489static UA_StatusCode function_namespace0_generated_423_finish(UA_Server *server, UA_UInt16* ns) {
80490return UA_Server_addNode_finish(server,
80491nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12815LU)
80492);
80493}
80494
80495/* NextSequenceNumber - ns=0;i=12814 */
80496
80497static UA_StatusCode function_namespace0_generated_424_begin(UA_Server *server, UA_UInt16* ns) {
80498UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80499UA_VariableAttributes attr = UA_VariableAttributes_default;
80500attr.minimumSamplingInterval = 0.000000;
80501attr.userAccessLevel = 1;
80502attr.accessLevel = 1;
80503/* Value rank inherited */
80504attr.valueRank = -2;
80505attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80506attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NextSequenceNumber");
80507retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80508requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12814LU),
80509parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80510referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80511browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NextSequenceNumber"),
80512typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80513attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80514if (retVal != UA_STATUSCODE_GOOD) return retVal;
80515return retVal;
80516}
80517
80518static UA_StatusCode function_namespace0_generated_424_finish(UA_Server *server, UA_UInt16* ns) {
80519return UA_Server_addNode_finish(server,
80520nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12814LU)
80521);
80522}
80523
80524/* MonitoringQueueOverflowCount - ns=0;i=12813 */
80525
80526static UA_StatusCode function_namespace0_generated_425_begin(UA_Server *server, UA_UInt16* ns) {
80527UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80528UA_VariableAttributes attr = UA_VariableAttributes_default;
80529attr.minimumSamplingInterval = 0.000000;
80530attr.userAccessLevel = 1;
80531attr.accessLevel = 1;
80532/* Value rank inherited */
80533attr.valueRank = -2;
80534attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80535attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MonitoringQueueOverflowCount");
80536retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80537requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12813LU),
80538parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80539referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80540browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MonitoringQueueOverflowCount"),
80541typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80542attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80543if (retVal != UA_STATUSCODE_GOOD) return retVal;
80544return retVal;
80545}
80546
80547static UA_StatusCode function_namespace0_generated_425_finish(UA_Server *server, UA_UInt16* ns) {
80548return UA_Server_addNode_finish(server,
80549nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12813LU)
80550);
80551}
80552
80553/* DisabledMonitoredItemCount - ns=0;i=12812 */
80554
80555static UA_StatusCode function_namespace0_generated_426_begin(UA_Server *server, UA_UInt16* ns) {
80556UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80557UA_VariableAttributes attr = UA_VariableAttributes_default;
80558attr.minimumSamplingInterval = 0.000000;
80559attr.userAccessLevel = 1;
80560attr.accessLevel = 1;
80561/* Value rank inherited */
80562attr.valueRank = -2;
80563attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80564attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DisabledMonitoredItemCount");
80565retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80566requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12812LU),
80567parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80568referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80569browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DisabledMonitoredItemCount"),
80570typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80571attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80572if (retVal != UA_STATUSCODE_GOOD) return retVal;
80573return retVal;
80574}
80575
80576static UA_StatusCode function_namespace0_generated_426_finish(UA_Server *server, UA_UInt16* ns) {
80577return UA_Server_addNode_finish(server,
80578nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12812LU)
80579);
80580}
80581
80582/* MonitoredItemCount - ns=0;i=12811 */
80583
80584static UA_StatusCode function_namespace0_generated_427_begin(UA_Server *server, UA_UInt16* ns) {
80585UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80586UA_VariableAttributes attr = UA_VariableAttributes_default;
80587attr.minimumSamplingInterval = 0.000000;
80588attr.userAccessLevel = 1;
80589attr.accessLevel = 1;
80590/* Value rank inherited */
80591attr.valueRank = -2;
80592attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80593attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MonitoredItemCount");
80594retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80595requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12811LU),
80596parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80597referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80598browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MonitoredItemCount"),
80599typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80600attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80601if (retVal != UA_STATUSCODE_GOOD) return retVal;
80602return retVal;
80603}
80604
80605static UA_StatusCode function_namespace0_generated_427_finish(UA_Server *server, UA_UInt16* ns) {
80606return UA_Server_addNode_finish(server,
80607nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12811LU)
80608);
80609}
80610
80611/* DiscardedMessageCount - ns=0;i=12810 */
80612
80613static UA_StatusCode function_namespace0_generated_428_begin(UA_Server *server, UA_UInt16* ns) {
80614UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80615UA_VariableAttributes attr = UA_VariableAttributes_default;
80616attr.minimumSamplingInterval = 0.000000;
80617attr.userAccessLevel = 1;
80618attr.accessLevel = 1;
80619/* Value rank inherited */
80620attr.valueRank = -2;
80621attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80622attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DiscardedMessageCount");
80623retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80624requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12810LU),
80625parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80626referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80627browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DiscardedMessageCount"),
80628typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80629attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80630if (retVal != UA_STATUSCODE_GOOD) return retVal;
80631return retVal;
80632}
80633
80634static UA_StatusCode function_namespace0_generated_428_finish(UA_Server *server, UA_UInt16* ns) {
80635return UA_Server_addNode_finish(server,
80636nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12810LU)
80637);
80638}
80639
80640/* UnacknowledgedMessageCount - ns=0;i=12809 */
80641
80642static UA_StatusCode function_namespace0_generated_429_begin(UA_Server *server, UA_UInt16* ns) {
80643UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80644UA_VariableAttributes attr = UA_VariableAttributes_default;
80645attr.minimumSamplingInterval = 0.000000;
80646attr.userAccessLevel = 1;
80647attr.accessLevel = 1;
80648/* Value rank inherited */
80649attr.valueRank = -2;
80650attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80651attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UnacknowledgedMessageCount");
80652retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80653requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12809LU),
80654parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80655referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80656browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UnacknowledgedMessageCount"),
80657typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80658attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80659if (retVal != UA_STATUSCODE_GOOD) return retVal;
80660return retVal;
80661}
80662
80663static UA_StatusCode function_namespace0_generated_429_finish(UA_Server *server, UA_UInt16* ns) {
80664return UA_Server_addNode_finish(server,
80665nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12809LU)
80666);
80667}
80668
80669/* CurrentLifetimeCount - ns=0;i=12808 */
80670
80671static UA_StatusCode function_namespace0_generated_430_begin(UA_Server *server, UA_UInt16* ns) {
80672UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80673UA_VariableAttributes attr = UA_VariableAttributes_default;
80674attr.minimumSamplingInterval = 0.000000;
80675attr.userAccessLevel = 1;
80676attr.accessLevel = 1;
80677/* Value rank inherited */
80678attr.valueRank = -2;
80679attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80680attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentLifetimeCount");
80681retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80682requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12808LU),
80683parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80684referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80685browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentLifetimeCount"),
80686typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80687attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80688if (retVal != UA_STATUSCODE_GOOD) return retVal;
80689return retVal;
80690}
80691
80692static UA_StatusCode function_namespace0_generated_430_finish(UA_Server *server, UA_UInt16* ns) {
80693return UA_Server_addNode_finish(server,
80694nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12808LU)
80695);
80696}
80697
80698/* CurrentKeepAliveCount - ns=0;i=12807 */
80699
80700static UA_StatusCode function_namespace0_generated_431_begin(UA_Server *server, UA_UInt16* ns) {
80701UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80702UA_VariableAttributes attr = UA_VariableAttributes_default;
80703attr.minimumSamplingInterval = 0.000000;
80704attr.userAccessLevel = 1;
80705attr.accessLevel = 1;
80706/* Value rank inherited */
80707attr.valueRank = -2;
80708attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80709attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentKeepAliveCount");
80710retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80711requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12807LU),
80712parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80713referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80714browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentKeepAliveCount"),
80715typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80716attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80717if (retVal != UA_STATUSCODE_GOOD) return retVal;
80718return retVal;
80719}
80720
80721static UA_StatusCode function_namespace0_generated_431_finish(UA_Server *server, UA_UInt16* ns) {
80722return UA_Server_addNode_finish(server,
80723nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12807LU)
80724);
80725}
80726
80727/* LatePublishRequestCount - ns=0;i=12806 */
80728
80729static UA_StatusCode function_namespace0_generated_432_begin(UA_Server *server, UA_UInt16* ns) {
80730UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80731UA_VariableAttributes attr = UA_VariableAttributes_default;
80732attr.minimumSamplingInterval = 0.000000;
80733attr.userAccessLevel = 1;
80734attr.accessLevel = 1;
80735/* Value rank inherited */
80736attr.valueRank = -2;
80737attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80738attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "LatePublishRequestCount");
80739retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80740requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12806LU),
80741parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80742referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80743browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "LatePublishRequestCount"),
80744typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80745attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80746if (retVal != UA_STATUSCODE_GOOD) return retVal;
80747return retVal;
80748}
80749
80750static UA_StatusCode function_namespace0_generated_432_finish(UA_Server *server, UA_UInt16* ns) {
80751return UA_Server_addNode_finish(server,
80752nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12806LU)
80753);
80754}
80755
80756/* NotificationsCount - ns=0;i=12805 */
80757
80758static UA_StatusCode function_namespace0_generated_433_begin(UA_Server *server, UA_UInt16* ns) {
80759UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80760UA_VariableAttributes attr = UA_VariableAttributes_default;
80761attr.minimumSamplingInterval = 0.000000;
80762attr.userAccessLevel = 1;
80763attr.accessLevel = 1;
80764/* Value rank inherited */
80765attr.valueRank = -2;
80766attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80767attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NotificationsCount");
80768retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80769requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12805LU),
80770parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80771referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80772browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NotificationsCount"),
80773typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80774attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80775if (retVal != UA_STATUSCODE_GOOD) return retVal;
80776return retVal;
80777}
80778
80779static UA_StatusCode function_namespace0_generated_433_finish(UA_Server *server, UA_UInt16* ns) {
80780return UA_Server_addNode_finish(server,
80781nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12805LU)
80782);
80783}
80784
80785/* EventNotificationsCount - ns=0;i=12804 */
80786
80787static UA_StatusCode function_namespace0_generated_434_begin(UA_Server *server, UA_UInt16* ns) {
80788UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80789UA_VariableAttributes attr = UA_VariableAttributes_default;
80790attr.minimumSamplingInterval = 0.000000;
80791attr.userAccessLevel = 1;
80792attr.accessLevel = 1;
80793/* Value rank inherited */
80794attr.valueRank = -2;
80795attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80796attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EventNotificationsCount");
80797retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80798requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12804LU),
80799parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80800referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80801browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EventNotificationsCount"),
80802typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80803attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80804if (retVal != UA_STATUSCODE_GOOD) return retVal;
80805return retVal;
80806}
80807
80808static UA_StatusCode function_namespace0_generated_434_finish(UA_Server *server, UA_UInt16* ns) {
80809return UA_Server_addNode_finish(server,
80810nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12804LU)
80811);
80812}
80813
80814/* DataChangeNotificationsCount - ns=0;i=12803 */
80815
80816static UA_StatusCode function_namespace0_generated_435_begin(UA_Server *server, UA_UInt16* ns) {
80817UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80818UA_VariableAttributes attr = UA_VariableAttributes_default;
80819attr.minimumSamplingInterval = 0.000000;
80820attr.userAccessLevel = 1;
80821attr.accessLevel = 1;
80822/* Value rank inherited */
80823attr.valueRank = -2;
80824attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80825attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataChangeNotificationsCount");
80826retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80827requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12803LU),
80828parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80829referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80830browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataChangeNotificationsCount"),
80831typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80832attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80833if (retVal != UA_STATUSCODE_GOOD) return retVal;
80834return retVal;
80835}
80836
80837static UA_StatusCode function_namespace0_generated_435_finish(UA_Server *server, UA_UInt16* ns) {
80838return UA_Server_addNode_finish(server,
80839nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12803LU)
80840);
80841}
80842
80843/* PublishRequestCount - ns=0;i=12802 */
80844
80845static UA_StatusCode function_namespace0_generated_436_begin(UA_Server *server, UA_UInt16* ns) {
80846UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80847UA_VariableAttributes attr = UA_VariableAttributes_default;
80848attr.minimumSamplingInterval = 0.000000;
80849attr.userAccessLevel = 1;
80850attr.accessLevel = 1;
80851/* Value rank inherited */
80852attr.valueRank = -2;
80853attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80854attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishRequestCount");
80855retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80856requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12802LU),
80857parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80858referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80859browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishRequestCount"),
80860typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80861attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80862if (retVal != UA_STATUSCODE_GOOD) return retVal;
80863return retVal;
80864}
80865
80866static UA_StatusCode function_namespace0_generated_436_finish(UA_Server *server, UA_UInt16* ns) {
80867return UA_Server_addNode_finish(server,
80868nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12802LU)
80869);
80870}
80871
80872/* TransferredToSameClientCount - ns=0;i=12801 */
80873
80874static UA_StatusCode function_namespace0_generated_437_begin(UA_Server *server, UA_UInt16* ns) {
80875UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80876UA_VariableAttributes attr = UA_VariableAttributes_default;
80877attr.minimumSamplingInterval = 0.000000;
80878attr.userAccessLevel = 1;
80879attr.accessLevel = 1;
80880/* Value rank inherited */
80881attr.valueRank = -2;
80882attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80883attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransferredToSameClientCount");
80884retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80885requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12801LU),
80886parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80887referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80888browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransferredToSameClientCount"),
80889typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80890attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80891if (retVal != UA_STATUSCODE_GOOD) return retVal;
80892return retVal;
80893}
80894
80895static UA_StatusCode function_namespace0_generated_437_finish(UA_Server *server, UA_UInt16* ns) {
80896return UA_Server_addNode_finish(server,
80897nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12801LU)
80898);
80899}
80900
80901/* TransferredToAltClientCount - ns=0;i=12800 */
80902
80903static UA_StatusCode function_namespace0_generated_438_begin(UA_Server *server, UA_UInt16* ns) {
80904UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80905UA_VariableAttributes attr = UA_VariableAttributes_default;
80906attr.minimumSamplingInterval = 0.000000;
80907attr.userAccessLevel = 1;
80908attr.accessLevel = 1;
80909/* Value rank inherited */
80910attr.valueRank = -2;
80911attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80912attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransferredToAltClientCount");
80913retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80914requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12800LU),
80915parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80916referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80917browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransferredToAltClientCount"),
80918typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80919attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80920if (retVal != UA_STATUSCODE_GOOD) return retVal;
80921return retVal;
80922}
80923
80924static UA_StatusCode function_namespace0_generated_438_finish(UA_Server *server, UA_UInt16* ns) {
80925return UA_Server_addNode_finish(server,
80926nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12800LU)
80927);
80928}
80929
80930/* TransferRequestCount - ns=0;i=12799 */
80931
80932static UA_StatusCode function_namespace0_generated_439_begin(UA_Server *server, UA_UInt16* ns) {
80933UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80934UA_VariableAttributes attr = UA_VariableAttributes_default;
80935attr.minimumSamplingInterval = 0.000000;
80936attr.userAccessLevel = 1;
80937attr.accessLevel = 1;
80938/* Value rank inherited */
80939attr.valueRank = -2;
80940attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80941attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransferRequestCount");
80942retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80943requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12799LU),
80944parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80945referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80946browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransferRequestCount"),
80947typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80948attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80949if (retVal != UA_STATUSCODE_GOOD) return retVal;
80950return retVal;
80951}
80952
80953static UA_StatusCode function_namespace0_generated_439_finish(UA_Server *server, UA_UInt16* ns) {
80954return UA_Server_addNode_finish(server,
80955nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12799LU)
80956);
80957}
80958
80959/* RepublishMessageCount - ns=0;i=12798 */
80960
80961static UA_StatusCode function_namespace0_generated_440_begin(UA_Server *server, UA_UInt16* ns) {
80962UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80963UA_VariableAttributes attr = UA_VariableAttributes_default;
80964attr.minimumSamplingInterval = 0.000000;
80965attr.userAccessLevel = 1;
80966attr.accessLevel = 1;
80967/* Value rank inherited */
80968attr.valueRank = -2;
80969attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80970attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RepublishMessageCount");
80971retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
80972requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12798LU),
80973parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
80974referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
80975browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RepublishMessageCount"),
80976typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
80977attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
80978if (retVal != UA_STATUSCODE_GOOD) return retVal;
80979return retVal;
80980}
80981
80982static UA_StatusCode function_namespace0_generated_440_finish(UA_Server *server, UA_UInt16* ns) {
80983return UA_Server_addNode_finish(server,
80984nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12798LU)
80985);
80986}
80987
80988/* RepublishMessageRequestCount - ns=0;i=12797 */
80989
80990static UA_StatusCode function_namespace0_generated_441_begin(UA_Server *server, UA_UInt16* ns) {
80991UA_StatusCode retVal = UA_STATUSCODE_GOOD;
80992UA_VariableAttributes attr = UA_VariableAttributes_default;
80993attr.minimumSamplingInterval = 0.000000;
80994attr.userAccessLevel = 1;
80995attr.accessLevel = 1;
80996/* Value rank inherited */
80997attr.valueRank = -2;
80998attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
80999attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RepublishMessageRequestCount");
81000retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81001requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12797LU),
81002parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
81003referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81004browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RepublishMessageRequestCount"),
81005typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81006attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81007if (retVal != UA_STATUSCODE_GOOD) return retVal;
81008return retVal;
81009}
81010
81011static UA_StatusCode function_namespace0_generated_441_finish(UA_Server *server, UA_UInt16* ns) {
81012return UA_Server_addNode_finish(server,
81013nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12797LU)
81014);
81015}
81016
81017/* RepublishRequestCount - ns=0;i=12796 */
81018
81019static UA_StatusCode function_namespace0_generated_442_begin(UA_Server *server, UA_UInt16* ns) {
81020UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81021UA_VariableAttributes attr = UA_VariableAttributes_default;
81022attr.minimumSamplingInterval = 0.000000;
81023attr.userAccessLevel = 1;
81024attr.accessLevel = 1;
81025/* Value rank inherited */
81026attr.valueRank = -2;
81027attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
81028attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RepublishRequestCount");
81029retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81030requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12796LU),
81031parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
81032referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81033browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RepublishRequestCount"),
81034typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81035attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81036if (retVal != UA_STATUSCODE_GOOD) return retVal;
81037return retVal;
81038}
81039
81040static UA_StatusCode function_namespace0_generated_442_finish(UA_Server *server, UA_UInt16* ns) {
81041return UA_Server_addNode_finish(server,
81042nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12796LU)
81043);
81044}
81045
81046/* DisableCount - ns=0;i=12795 */
81047
81048static UA_StatusCode function_namespace0_generated_443_begin(UA_Server *server, UA_UInt16* ns) {
81049UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81050UA_VariableAttributes attr = UA_VariableAttributes_default;
81051attr.minimumSamplingInterval = 0.000000;
81052attr.userAccessLevel = 1;
81053attr.accessLevel = 1;
81054/* Value rank inherited */
81055attr.valueRank = -2;
81056attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
81057attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DisableCount");
81058retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81059requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12795LU),
81060parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
81061referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81062browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DisableCount"),
81063typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81064attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81065if (retVal != UA_STATUSCODE_GOOD) return retVal;
81066return retVal;
81067}
81068
81069static UA_StatusCode function_namespace0_generated_443_finish(UA_Server *server, UA_UInt16* ns) {
81070return UA_Server_addNode_finish(server,
81071nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12795LU)
81072);
81073}
81074
81075/* EnableCount - ns=0;i=12794 */
81076
81077static UA_StatusCode function_namespace0_generated_444_begin(UA_Server *server, UA_UInt16* ns) {
81078UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81079UA_VariableAttributes attr = UA_VariableAttributes_default;
81080attr.minimumSamplingInterval = 0.000000;
81081attr.userAccessLevel = 1;
81082attr.accessLevel = 1;
81083/* Value rank inherited */
81084attr.valueRank = -2;
81085attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
81086attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnableCount");
81087retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81088requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12794LU),
81089parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
81090referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81091browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnableCount"),
81092typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81093attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81094if (retVal != UA_STATUSCODE_GOOD) return retVal;
81095return retVal;
81096}
81097
81098static UA_StatusCode function_namespace0_generated_444_finish(UA_Server *server, UA_UInt16* ns) {
81099return UA_Server_addNode_finish(server,
81100nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12794LU)
81101);
81102}
81103
81104/* ModifyCount - ns=0;i=12793 */
81105
81106static UA_StatusCode function_namespace0_generated_445_begin(UA_Server *server, UA_UInt16* ns) {
81107UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81108UA_VariableAttributes attr = UA_VariableAttributes_default;
81109attr.minimumSamplingInterval = 0.000000;
81110attr.userAccessLevel = 1;
81111attr.accessLevel = 1;
81112/* Value rank inherited */
81113attr.valueRank = -2;
81114attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
81115attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ModifyCount");
81116retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81117requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12793LU),
81118parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
81119referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81120browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ModifyCount"),
81121typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81122attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81123if (retVal != UA_STATUSCODE_GOOD) return retVal;
81124return retVal;
81125}
81126
81127static UA_StatusCode function_namespace0_generated_445_finish(UA_Server *server, UA_UInt16* ns) {
81128return UA_Server_addNode_finish(server,
81129nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12793LU)
81130);
81131}
81132
81133/* PublishingEnabled - ns=0;i=12792 */
81134
81135static UA_StatusCode function_namespace0_generated_446_begin(UA_Server *server, UA_UInt16* ns) {
81136UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81137UA_VariableAttributes attr = UA_VariableAttributes_default;
81138attr.minimumSamplingInterval = 0.000000;
81139attr.userAccessLevel = 1;
81140attr.accessLevel = 1;
81141/* Value rank inherited */
81142attr.valueRank = -2;
81143attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
81144attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishingEnabled");
81145retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81146requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12792LU),
81147parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
81148referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81149browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishingEnabled"),
81150typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81151attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81152if (retVal != UA_STATUSCODE_GOOD) return retVal;
81153return retVal;
81154}
81155
81156static UA_StatusCode function_namespace0_generated_446_finish(UA_Server *server, UA_UInt16* ns) {
81157return UA_Server_addNode_finish(server,
81158nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12792LU)
81159);
81160}
81161
81162/* MaxNotificationsPerPublish - ns=0;i=12791 */
81163
81164static UA_StatusCode function_namespace0_generated_447_begin(UA_Server *server, UA_UInt16* ns) {
81165UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81166UA_VariableAttributes attr = UA_VariableAttributes_default;
81167attr.minimumSamplingInterval = 0.000000;
81168attr.userAccessLevel = 1;
81169attr.accessLevel = 1;
81170/* Value rank inherited */
81171attr.valueRank = -2;
81172attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
81173attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNotificationsPerPublish");
81174retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81175requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12791LU),
81176parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
81177referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81178browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNotificationsPerPublish"),
81179typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81180attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81181if (retVal != UA_STATUSCODE_GOOD) return retVal;
81182return retVal;
81183}
81184
81185static UA_StatusCode function_namespace0_generated_447_finish(UA_Server *server, UA_UInt16* ns) {
81186return UA_Server_addNode_finish(server,
81187nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12791LU)
81188);
81189}
81190
81191/* MaxLifetimeCount - ns=0;i=12790 */
81192
81193static UA_StatusCode function_namespace0_generated_448_begin(UA_Server *server, UA_UInt16* ns) {
81194UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81195UA_VariableAttributes attr = UA_VariableAttributes_default;
81196attr.minimumSamplingInterval = 0.000000;
81197attr.userAccessLevel = 1;
81198attr.accessLevel = 1;
81199/* Value rank inherited */
81200attr.valueRank = -2;
81201attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
81202attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxLifetimeCount");
81203retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81204requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12790LU),
81205parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
81206referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81207browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxLifetimeCount"),
81208typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81209attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81210if (retVal != UA_STATUSCODE_GOOD) return retVal;
81211return retVal;
81212}
81213
81214static UA_StatusCode function_namespace0_generated_448_finish(UA_Server *server, UA_UInt16* ns) {
81215return UA_Server_addNode_finish(server,
81216nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12790LU)
81217);
81218}
81219
81220/* MaxKeepAliveCount - ns=0;i=12789 */
81221
81222static UA_StatusCode function_namespace0_generated_449_begin(UA_Server *server, UA_UInt16* ns) {
81223UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81224UA_VariableAttributes attr = UA_VariableAttributes_default;
81225attr.minimumSamplingInterval = 0.000000;
81226attr.userAccessLevel = 1;
81227attr.accessLevel = 1;
81228/* Value rank inherited */
81229attr.valueRank = -2;
81230attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
81231attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxKeepAliveCount");
81232retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81233requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12789LU),
81234parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
81235referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81236browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxKeepAliveCount"),
81237typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81238attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81239if (retVal != UA_STATUSCODE_GOOD) return retVal;
81240return retVal;
81241}
81242
81243static UA_StatusCode function_namespace0_generated_449_finish(UA_Server *server, UA_UInt16* ns) {
81244return UA_Server_addNode_finish(server,
81245nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12789LU)
81246);
81247}
81248
81249/* PublishingInterval - ns=0;i=12788 */
81250
81251static UA_StatusCode function_namespace0_generated_450_begin(UA_Server *server, UA_UInt16* ns) {
81252UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81253UA_VariableAttributes attr = UA_VariableAttributes_default;
81254attr.minimumSamplingInterval = 0.000000;
81255attr.userAccessLevel = 1;
81256attr.accessLevel = 1;
81257/* Value rank inherited */
81258attr.valueRank = -2;
81259attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU);
81260attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishingInterval");
81261retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81262requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12788LU),
81263parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
81264referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81265browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishingInterval"),
81266typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81267attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81268if (retVal != UA_STATUSCODE_GOOD) return retVal;
81269return retVal;
81270}
81271
81272static UA_StatusCode function_namespace0_generated_450_finish(UA_Server *server, UA_UInt16* ns) {
81273return UA_Server_addNode_finish(server,
81274nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12788LU)
81275);
81276}
81277
81278/* Priority - ns=0;i=12787 */
81279
81280static UA_StatusCode function_namespace0_generated_451_begin(UA_Server *server, UA_UInt16* ns) {
81281UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81282UA_VariableAttributes attr = UA_VariableAttributes_default;
81283attr.minimumSamplingInterval = 0.000000;
81284attr.userAccessLevel = 1;
81285attr.accessLevel = 1;
81286/* Value rank inherited */
81287attr.valueRank = -2;
81288attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3LU);
81289attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Priority");
81290retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81291requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12787LU),
81292parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
81293referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81294browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Priority"),
81295typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81296attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81297if (retVal != UA_STATUSCODE_GOOD) return retVal;
81298return retVal;
81299}
81300
81301static UA_StatusCode function_namespace0_generated_451_finish(UA_Server *server, UA_UInt16* ns) {
81302return UA_Server_addNode_finish(server,
81303nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12787LU)
81304);
81305}
81306
81307/* SubscriptionId - ns=0;i=12786 */
81308
81309static UA_StatusCode function_namespace0_generated_452_begin(UA_Server *server, UA_UInt16* ns) {
81310UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81311UA_VariableAttributes attr = UA_VariableAttributes_default;
81312attr.minimumSamplingInterval = 0.000000;
81313attr.userAccessLevel = 1;
81314attr.accessLevel = 1;
81315/* Value rank inherited */
81316attr.valueRank = -2;
81317attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
81318attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscriptionId");
81319retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81320requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12786LU),
81321parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
81322referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81323browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscriptionId"),
81324typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81325attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81326if (retVal != UA_STATUSCODE_GOOD) return retVal;
81327return retVal;
81328}
81329
81330static UA_StatusCode function_namespace0_generated_452_finish(UA_Server *server, UA_UInt16* ns) {
81331return UA_Server_addNode_finish(server,
81332nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12786LU)
81333);
81334}
81335
81336/* SessionId - ns=0;i=12785 */
81337
81338static UA_StatusCode function_namespace0_generated_453_begin(UA_Server *server, UA_UInt16* ns) {
81339UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81340UA_VariableAttributes attr = UA_VariableAttributes_default;
81341attr.minimumSamplingInterval = 0.000000;
81342attr.userAccessLevel = 1;
81343attr.accessLevel = 1;
81344/* Value rank inherited */
81345attr.valueRank = -2;
81346attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
81347attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionId");
81348retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81349requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12785LU),
81350parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU),
81351referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81352browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionId"),
81353typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81354attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81355if (retVal != UA_STATUSCODE_GOOD) return retVal;
81356return retVal;
81357}
81358
81359static UA_StatusCode function_namespace0_generated_453_finish(UA_Server *server, UA_UInt16* ns) {
81360return UA_Server_addNode_finish(server,
81361nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12785LU)
81362);
81363}
81364
81365/* SessionSecurityDiagnosticsType - ns=0;i=2244 */
81366
81367static UA_StatusCode function_namespace0_generated_454_begin(UA_Server *server, UA_UInt16* ns) {
81368UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81369UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
81370/* Value rank inherited */
81371attr.valueRank = -2;
81372attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 868LU);
81373attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionSecurityDiagnosticsType");
81374retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
81375requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU),
81376parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81377referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
81378browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionSecurityDiagnosticsType"),
81379typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
81380attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
81381if (retVal != UA_STATUSCODE_GOOD) return retVal;
81382return retVal;
81383}
81384
81385static UA_StatusCode function_namespace0_generated_454_finish(UA_Server *server, UA_UInt16* ns) {
81386return UA_Server_addNode_finish(server,
81387nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU)
81388);
81389}
81390
81391/* ClientCertificate - ns=0;i=3058 */
81392
81393static UA_StatusCode function_namespace0_generated_455_begin(UA_Server *server, UA_UInt16* ns) {
81394UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81395UA_VariableAttributes attr = UA_VariableAttributes_default;
81396attr.minimumSamplingInterval = 0.000000;
81397attr.userAccessLevel = 1;
81398attr.accessLevel = 1;
81399/* Value rank inherited */
81400attr.valueRank = -2;
81401attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15LU);
81402attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientCertificate");
81403retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81404requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3058LU),
81405parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU),
81406referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81407browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientCertificate"),
81408typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81409attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81410if (retVal != UA_STATUSCODE_GOOD) return retVal;
81411return retVal;
81412}
81413
81414static UA_StatusCode function_namespace0_generated_455_finish(UA_Server *server, UA_UInt16* ns) {
81415return UA_Server_addNode_finish(server,
81416nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3058LU)
81417);
81418}
81419
81420/* SecurityPolicyUri - ns=0;i=2252 */
81421
81422static UA_StatusCode function_namespace0_generated_456_begin(UA_Server *server, UA_UInt16* ns) {
81423UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81424UA_VariableAttributes attr = UA_VariableAttributes_default;
81425attr.minimumSamplingInterval = 0.000000;
81426attr.userAccessLevel = 1;
81427attr.accessLevel = 1;
81428/* Value rank inherited */
81429attr.valueRank = -2;
81430attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
81431attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityPolicyUri");
81432retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81433requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2252LU),
81434parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU),
81435referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81436browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityPolicyUri"),
81437typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81438attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81439if (retVal != UA_STATUSCODE_GOOD) return retVal;
81440return retVal;
81441}
81442
81443static UA_StatusCode function_namespace0_generated_456_finish(UA_Server *server, UA_UInt16* ns) {
81444return UA_Server_addNode_finish(server,
81445nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2252LU)
81446);
81447}
81448
81449/* SecurityMode - ns=0;i=2251 */
81450
81451static UA_StatusCode function_namespace0_generated_457_begin(UA_Server *server, UA_UInt16* ns) {
81452UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81453UA_VariableAttributes attr = UA_VariableAttributes_default;
81454attr.minimumSamplingInterval = 0.000000;
81455attr.userAccessLevel = 1;
81456attr.accessLevel = 1;
81457/* Value rank inherited */
81458attr.valueRank = -2;
81459attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 302LU);
81460attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityMode");
81461retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81462requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2251LU),
81463parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU),
81464referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81465browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityMode"),
81466typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81467attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81468if (retVal != UA_STATUSCODE_GOOD) return retVal;
81469return retVal;
81470}
81471
81472static UA_StatusCode function_namespace0_generated_457_finish(UA_Server *server, UA_UInt16* ns) {
81473return UA_Server_addNode_finish(server,
81474nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2251LU)
81475);
81476}
81477
81478/* TransportProtocol - ns=0;i=2250 */
81479
81480static UA_StatusCode function_namespace0_generated_458_begin(UA_Server *server, UA_UInt16* ns) {
81481UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81482UA_VariableAttributes attr = UA_VariableAttributes_default;
81483attr.minimumSamplingInterval = 0.000000;
81484attr.userAccessLevel = 1;
81485attr.accessLevel = 1;
81486/* Value rank inherited */
81487attr.valueRank = -2;
81488attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
81489attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransportProtocol");
81490retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81491requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2250LU),
81492parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU),
81493referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81494browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransportProtocol"),
81495typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81496attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81497if (retVal != UA_STATUSCODE_GOOD) return retVal;
81498return retVal;
81499}
81500
81501static UA_StatusCode function_namespace0_generated_458_finish(UA_Server *server, UA_UInt16* ns) {
81502return UA_Server_addNode_finish(server,
81503nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2250LU)
81504);
81505}
81506
81507/* Encoding - ns=0;i=2249 */
81508
81509static UA_StatusCode function_namespace0_generated_459_begin(UA_Server *server, UA_UInt16* ns) {
81510UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81511UA_VariableAttributes attr = UA_VariableAttributes_default;
81512attr.minimumSamplingInterval = 0.000000;
81513attr.userAccessLevel = 1;
81514attr.accessLevel = 1;
81515/* Value rank inherited */
81516attr.valueRank = -2;
81517attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
81518attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Encoding");
81519retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81520requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2249LU),
81521parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU),
81522referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81523browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Encoding"),
81524typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81525attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81526if (retVal != UA_STATUSCODE_GOOD) return retVal;
81527return retVal;
81528}
81529
81530static UA_StatusCode function_namespace0_generated_459_finish(UA_Server *server, UA_UInt16* ns) {
81531return UA_Server_addNode_finish(server,
81532nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2249LU)
81533);
81534}
81535
81536/* AuthenticationMechanism - ns=0;i=2248 */
81537
81538static UA_StatusCode function_namespace0_generated_460_begin(UA_Server *server, UA_UInt16* ns) {
81539UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81540UA_VariableAttributes attr = UA_VariableAttributes_default;
81541attr.minimumSamplingInterval = 0.000000;
81542attr.userAccessLevel = 1;
81543attr.accessLevel = 1;
81544/* Value rank inherited */
81545attr.valueRank = -2;
81546attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
81547attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AuthenticationMechanism");
81548retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81549requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2248LU),
81550parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU),
81551referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81552browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AuthenticationMechanism"),
81553typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81554attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81555if (retVal != UA_STATUSCODE_GOOD) return retVal;
81556return retVal;
81557}
81558
81559static UA_StatusCode function_namespace0_generated_460_finish(UA_Server *server, UA_UInt16* ns) {
81560return UA_Server_addNode_finish(server,
81561nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2248LU)
81562);
81563}
81564
81565/* ClientUserIdHistory - ns=0;i=2247 */
81566
81567static UA_StatusCode function_namespace0_generated_461_begin(UA_Server *server, UA_UInt16* ns) {
81568UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81569UA_VariableAttributes attr = UA_VariableAttributes_default;
81570attr.minimumSamplingInterval = 0.000000;
81571attr.userAccessLevel = 1;
81572attr.accessLevel = 1;
81573attr.valueRank = 1;
81574attr.arrayDimensionsSize = 1;
81575UA_UInt32 arrayDimensions[1];
81576arrayDimensions[0] = 0;
81577attr.arrayDimensions = &arrayDimensions[0];
81578attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
81579attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientUserIdHistory");
81580retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81581requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2247LU),
81582parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU),
81583referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81584browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientUserIdHistory"),
81585typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81586attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81587if (retVal != UA_STATUSCODE_GOOD) return retVal;
81588return retVal;
81589}
81590
81591static UA_StatusCode function_namespace0_generated_461_finish(UA_Server *server, UA_UInt16* ns) {
81592return UA_Server_addNode_finish(server,
81593nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2247LU)
81594);
81595}
81596
81597/* ClientUserIdOfSession - ns=0;i=2246 */
81598
81599static UA_StatusCode function_namespace0_generated_462_begin(UA_Server *server, UA_UInt16* ns) {
81600UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81601UA_VariableAttributes attr = UA_VariableAttributes_default;
81602attr.minimumSamplingInterval = 0.000000;
81603attr.userAccessLevel = 1;
81604attr.accessLevel = 1;
81605/* Value rank inherited */
81606attr.valueRank = -2;
81607attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
81608attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientUserIdOfSession");
81609retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81610requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2246LU),
81611parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU),
81612referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81613browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientUserIdOfSession"),
81614typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81615attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81616if (retVal != UA_STATUSCODE_GOOD) return retVal;
81617return retVal;
81618}
81619
81620static UA_StatusCode function_namespace0_generated_462_finish(UA_Server *server, UA_UInt16* ns) {
81621return UA_Server_addNode_finish(server,
81622nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2246LU)
81623);
81624}
81625
81626/* SessionId - ns=0;i=2245 */
81627
81628static UA_StatusCode function_namespace0_generated_463_begin(UA_Server *server, UA_UInt16* ns) {
81629UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81630UA_VariableAttributes attr = UA_VariableAttributes_default;
81631attr.minimumSamplingInterval = 0.000000;
81632attr.userAccessLevel = 1;
81633attr.accessLevel = 1;
81634/* Value rank inherited */
81635attr.valueRank = -2;
81636attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
81637attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionId");
81638retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81639requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2245LU),
81640parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU),
81641referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81642browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionId"),
81643typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81644attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81645if (retVal != UA_STATUSCODE_GOOD) return retVal;
81646return retVal;
81647}
81648
81649static UA_StatusCode function_namespace0_generated_463_finish(UA_Server *server, UA_UInt16* ns) {
81650return UA_Server_addNode_finish(server,
81651nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2245LU)
81652);
81653}
81654
81655/* SessionDiagnosticsObjectType - ns=0;i=2029 */
81656
81657static UA_StatusCode function_namespace0_generated_464_begin(UA_Server *server, UA_UInt16* ns) {
81658UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81659UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
81660attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionDiagnosticsObjectType");
81661retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
81662requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2029LU),
81663parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
81664referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
81665browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionDiagnosticsObjectType"),
81666 typeDefinition: UA_NODEID_NULL,
81667attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
81668if (retVal != UA_STATUSCODE_GOOD) return retVal;
81669return retVal;
81670}
81671
81672static UA_StatusCode function_namespace0_generated_464_finish(UA_Server *server, UA_UInt16* ns) {
81673return UA_Server_addNode_finish(server,
81674nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2029LU)
81675);
81676}
81677
81678/* SubscriptionDiagnosticsArray - ns=0;i=2032 */
81679
81680static UA_StatusCode function_namespace0_generated_465_begin(UA_Server *server, UA_UInt16* ns) {
81681UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81682UA_VariableAttributes attr = UA_VariableAttributes_default;
81683attr.minimumSamplingInterval = 0.000000;
81684attr.userAccessLevel = 1;
81685attr.accessLevel = 1;
81686attr.valueRank = 1;
81687attr.arrayDimensionsSize = 1;
81688UA_UInt32 arrayDimensions[1];
81689arrayDimensions[0] = 0;
81690attr.arrayDimensions = &arrayDimensions[0];
81691attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 874LU);
81692attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscriptionDiagnosticsArray");
81693retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81694requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2032LU),
81695parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2029LU),
81696referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81697browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscriptionDiagnosticsArray"),
81698typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2171LU),
81699attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81700if (retVal != UA_STATUSCODE_GOOD) return retVal;
81701return retVal;
81702}
81703
81704static UA_StatusCode function_namespace0_generated_465_finish(UA_Server *server, UA_UInt16* ns) {
81705return UA_Server_addNode_finish(server,
81706nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2032LU)
81707);
81708}
81709
81710/* SessionSecurityDiagnostics - ns=0;i=2031 */
81711
81712static UA_StatusCode function_namespace0_generated_466_begin(UA_Server *server, UA_UInt16* ns) {
81713UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81714UA_VariableAttributes attr = UA_VariableAttributes_default;
81715attr.minimumSamplingInterval = 0.000000;
81716attr.userAccessLevel = 1;
81717attr.accessLevel = 1;
81718/* Value rank inherited */
81719attr.valueRank = -2;
81720attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 868LU);
81721attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionSecurityDiagnostics");
81722retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81723requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2031LU),
81724parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2029LU),
81725referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81726browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionSecurityDiagnostics"),
81727typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU),
81728attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81729if (retVal != UA_STATUSCODE_GOOD) return retVal;
81730return retVal;
81731}
81732
81733static UA_StatusCode function_namespace0_generated_466_finish(UA_Server *server, UA_UInt16* ns) {
81734return UA_Server_addNode_finish(server,
81735nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2031LU)
81736);
81737}
81738
81739/* ClientCertificate - ns=0;i=3187 */
81740
81741static UA_StatusCode function_namespace0_generated_467_begin(UA_Server *server, UA_UInt16* ns) {
81742UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81743UA_VariableAttributes attr = UA_VariableAttributes_default;
81744attr.minimumSamplingInterval = 0.000000;
81745attr.userAccessLevel = 1;
81746attr.accessLevel = 1;
81747/* Value rank inherited */
81748attr.valueRank = -2;
81749attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15LU);
81750attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientCertificate");
81751retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81752requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3187LU),
81753parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2031LU),
81754referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81755browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientCertificate"),
81756typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81757attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81758if (retVal != UA_STATUSCODE_GOOD) return retVal;
81759return retVal;
81760}
81761
81762static UA_StatusCode function_namespace0_generated_467_finish(UA_Server *server, UA_UInt16* ns) {
81763return UA_Server_addNode_finish(server,
81764nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3187LU)
81765);
81766}
81767
81768/* SecurityPolicyUri - ns=0;i=3186 */
81769
81770static UA_StatusCode function_namespace0_generated_468_begin(UA_Server *server, UA_UInt16* ns) {
81771UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81772UA_VariableAttributes attr = UA_VariableAttributes_default;
81773attr.minimumSamplingInterval = 0.000000;
81774attr.userAccessLevel = 1;
81775attr.accessLevel = 1;
81776/* Value rank inherited */
81777attr.valueRank = -2;
81778attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
81779attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityPolicyUri");
81780retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81781requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3186LU),
81782parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2031LU),
81783referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81784browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityPolicyUri"),
81785typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81786attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81787if (retVal != UA_STATUSCODE_GOOD) return retVal;
81788return retVal;
81789}
81790
81791static UA_StatusCode function_namespace0_generated_468_finish(UA_Server *server, UA_UInt16* ns) {
81792return UA_Server_addNode_finish(server,
81793nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3186LU)
81794);
81795}
81796
81797/* SecurityMode - ns=0;i=3185 */
81798
81799static UA_StatusCode function_namespace0_generated_469_begin(UA_Server *server, UA_UInt16* ns) {
81800UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81801UA_VariableAttributes attr = UA_VariableAttributes_default;
81802attr.minimumSamplingInterval = 0.000000;
81803attr.userAccessLevel = 1;
81804attr.accessLevel = 1;
81805/* Value rank inherited */
81806attr.valueRank = -2;
81807attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 302LU);
81808attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityMode");
81809retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81810requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3185LU),
81811parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2031LU),
81812referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81813browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityMode"),
81814typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81815attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81816if (retVal != UA_STATUSCODE_GOOD) return retVal;
81817return retVal;
81818}
81819
81820static UA_StatusCode function_namespace0_generated_469_finish(UA_Server *server, UA_UInt16* ns) {
81821return UA_Server_addNode_finish(server,
81822nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3185LU)
81823);
81824}
81825
81826/* TransportProtocol - ns=0;i=3184 */
81827
81828static UA_StatusCode function_namespace0_generated_470_begin(UA_Server *server, UA_UInt16* ns) {
81829UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81830UA_VariableAttributes attr = UA_VariableAttributes_default;
81831attr.minimumSamplingInterval = 0.000000;
81832attr.userAccessLevel = 1;
81833attr.accessLevel = 1;
81834/* Value rank inherited */
81835attr.valueRank = -2;
81836attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
81837attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransportProtocol");
81838retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81839requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3184LU),
81840parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2031LU),
81841referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81842browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransportProtocol"),
81843typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81844attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81845if (retVal != UA_STATUSCODE_GOOD) return retVal;
81846return retVal;
81847}
81848
81849static UA_StatusCode function_namespace0_generated_470_finish(UA_Server *server, UA_UInt16* ns) {
81850return UA_Server_addNode_finish(server,
81851nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3184LU)
81852);
81853}
81854
81855/* Encoding - ns=0;i=3183 */
81856
81857static UA_StatusCode function_namespace0_generated_471_begin(UA_Server *server, UA_UInt16* ns) {
81858UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81859UA_VariableAttributes attr = UA_VariableAttributes_default;
81860attr.minimumSamplingInterval = 0.000000;
81861attr.userAccessLevel = 1;
81862attr.accessLevel = 1;
81863/* Value rank inherited */
81864attr.valueRank = -2;
81865attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
81866attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Encoding");
81867retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81868requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3183LU),
81869parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2031LU),
81870referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81871browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Encoding"),
81872typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81873attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81874if (retVal != UA_STATUSCODE_GOOD) return retVal;
81875return retVal;
81876}
81877
81878static UA_StatusCode function_namespace0_generated_471_finish(UA_Server *server, UA_UInt16* ns) {
81879return UA_Server_addNode_finish(server,
81880nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3183LU)
81881);
81882}
81883
81884/* AuthenticationMechanism - ns=0;i=3182 */
81885
81886static UA_StatusCode function_namespace0_generated_472_begin(UA_Server *server, UA_UInt16* ns) {
81887UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81888UA_VariableAttributes attr = UA_VariableAttributes_default;
81889attr.minimumSamplingInterval = 0.000000;
81890attr.userAccessLevel = 1;
81891attr.accessLevel = 1;
81892/* Value rank inherited */
81893attr.valueRank = -2;
81894attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
81895attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AuthenticationMechanism");
81896retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81897requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3182LU),
81898parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2031LU),
81899referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81900browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AuthenticationMechanism"),
81901typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81902attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81903if (retVal != UA_STATUSCODE_GOOD) return retVal;
81904return retVal;
81905}
81906
81907static UA_StatusCode function_namespace0_generated_472_finish(UA_Server *server, UA_UInt16* ns) {
81908return UA_Server_addNode_finish(server,
81909nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3182LU)
81910);
81911}
81912
81913/* ClientUserIdHistory - ns=0;i=3181 */
81914
81915static UA_StatusCode function_namespace0_generated_473_begin(UA_Server *server, UA_UInt16* ns) {
81916UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81917UA_VariableAttributes attr = UA_VariableAttributes_default;
81918attr.minimumSamplingInterval = 0.000000;
81919attr.userAccessLevel = 1;
81920attr.accessLevel = 1;
81921attr.valueRank = 1;
81922attr.arrayDimensionsSize = 1;
81923UA_UInt32 arrayDimensions[1];
81924arrayDimensions[0] = 0;
81925attr.arrayDimensions = &arrayDimensions[0];
81926attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
81927attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientUserIdHistory");
81928retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81929requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3181LU),
81930parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2031LU),
81931referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81932browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientUserIdHistory"),
81933typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81934attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81935if (retVal != UA_STATUSCODE_GOOD) return retVal;
81936return retVal;
81937}
81938
81939static UA_StatusCode function_namespace0_generated_473_finish(UA_Server *server, UA_UInt16* ns) {
81940return UA_Server_addNode_finish(server,
81941nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3181LU)
81942);
81943}
81944
81945/* ClientUserIdOfSession - ns=0;i=3180 */
81946
81947static UA_StatusCode function_namespace0_generated_474_begin(UA_Server *server, UA_UInt16* ns) {
81948UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81949UA_VariableAttributes attr = UA_VariableAttributes_default;
81950attr.minimumSamplingInterval = 0.000000;
81951attr.userAccessLevel = 1;
81952attr.accessLevel = 1;
81953/* Value rank inherited */
81954attr.valueRank = -2;
81955attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
81956attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientUserIdOfSession");
81957retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81958requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3180LU),
81959parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2031LU),
81960referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81961browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientUserIdOfSession"),
81962typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81963attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81964if (retVal != UA_STATUSCODE_GOOD) return retVal;
81965return retVal;
81966}
81967
81968static UA_StatusCode function_namespace0_generated_474_finish(UA_Server *server, UA_UInt16* ns) {
81969return UA_Server_addNode_finish(server,
81970nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3180LU)
81971);
81972}
81973
81974/* SessionId - ns=0;i=3179 */
81975
81976static UA_StatusCode function_namespace0_generated_475_begin(UA_Server *server, UA_UInt16* ns) {
81977UA_StatusCode retVal = UA_STATUSCODE_GOOD;
81978UA_VariableAttributes attr = UA_VariableAttributes_default;
81979attr.minimumSamplingInterval = 0.000000;
81980attr.userAccessLevel = 1;
81981attr.accessLevel = 1;
81982/* Value rank inherited */
81983attr.valueRank = -2;
81984attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
81985attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionId");
81986retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
81987requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3179LU),
81988parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2031LU),
81989referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
81990browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionId"),
81991typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
81992attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
81993if (retVal != UA_STATUSCODE_GOOD) return retVal;
81994return retVal;
81995}
81996
81997static UA_StatusCode function_namespace0_generated_475_finish(UA_Server *server, UA_UInt16* ns) {
81998return UA_Server_addNode_finish(server,
81999nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3179LU)
82000);
82001}
82002
82003/* SessionDiagnostics - ns=0;i=2030 */
82004
82005static UA_StatusCode function_namespace0_generated_476_begin(UA_Server *server, UA_UInt16* ns) {
82006UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82007UA_VariableAttributes attr = UA_VariableAttributes_default;
82008attr.minimumSamplingInterval = 0.000000;
82009attr.userAccessLevel = 1;
82010attr.accessLevel = 1;
82011/* Value rank inherited */
82012attr.valueRank = -2;
82013attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 865LU);
82014attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionDiagnostics");
82015retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82016requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82017parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2029LU),
82018referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82019browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionDiagnostics"),
82020typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
82021attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82022if (retVal != UA_STATUSCODE_GOOD) return retVal;
82023return retVal;
82024}
82025
82026static UA_StatusCode function_namespace0_generated_476_finish(UA_Server *server, UA_UInt16* ns) {
82027return UA_Server_addNode_finish(server,
82028nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU)
82029);
82030}
82031
82032/* TotalRequestCount - ns=0;i=8898 */
82033
82034static UA_StatusCode function_namespace0_generated_477_begin(UA_Server *server, UA_UInt16* ns) {
82035UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82036UA_VariableAttributes attr = UA_VariableAttributes_default;
82037attr.minimumSamplingInterval = 0.000000;
82038attr.userAccessLevel = 1;
82039attr.accessLevel = 1;
82040/* Value rank inherited */
82041attr.valueRank = -2;
82042attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82043attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TotalRequestCount");
82044retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82045requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8898LU),
82046parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82047referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82048browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TotalRequestCount"),
82049typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82050attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82051if (retVal != UA_STATUSCODE_GOOD) return retVal;
82052return retVal;
82053}
82054
82055static UA_StatusCode function_namespace0_generated_477_finish(UA_Server *server, UA_UInt16* ns) {
82056return UA_Server_addNode_finish(server,
82057nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8898LU)
82058);
82059}
82060
82061/* UnregisterNodesCount - ns=0;i=3178 */
82062
82063static UA_StatusCode function_namespace0_generated_478_begin(UA_Server *server, UA_UInt16* ns) {
82064UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82065UA_VariableAttributes attr = UA_VariableAttributes_default;
82066attr.minimumSamplingInterval = 0.000000;
82067attr.userAccessLevel = 1;
82068attr.accessLevel = 1;
82069/* Value rank inherited */
82070attr.valueRank = -2;
82071attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82072attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UnregisterNodesCount");
82073retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82074requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3178LU),
82075parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82076referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82077browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UnregisterNodesCount"),
82078typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82079attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82080if (retVal != UA_STATUSCODE_GOOD) return retVal;
82081return retVal;
82082}
82083
82084static UA_StatusCode function_namespace0_generated_478_finish(UA_Server *server, UA_UInt16* ns) {
82085return UA_Server_addNode_finish(server,
82086nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3178LU)
82087);
82088}
82089
82090/* RegisterNodesCount - ns=0;i=3177 */
82091
82092static UA_StatusCode function_namespace0_generated_479_begin(UA_Server *server, UA_UInt16* ns) {
82093UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82094UA_VariableAttributes attr = UA_VariableAttributes_default;
82095attr.minimumSamplingInterval = 0.000000;
82096attr.userAccessLevel = 1;
82097attr.accessLevel = 1;
82098/* Value rank inherited */
82099attr.valueRank = -2;
82100attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82101attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RegisterNodesCount");
82102retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82103requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3177LU),
82104parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82105referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82106browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RegisterNodesCount"),
82107typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82108attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82109if (retVal != UA_STATUSCODE_GOOD) return retVal;
82110return retVal;
82111}
82112
82113static UA_StatusCode function_namespace0_generated_479_finish(UA_Server *server, UA_UInt16* ns) {
82114return UA_Server_addNode_finish(server,
82115nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3177LU)
82116);
82117}
82118
82119/* QueryNextCount - ns=0;i=3176 */
82120
82121static UA_StatusCode function_namespace0_generated_480_begin(UA_Server *server, UA_UInt16* ns) {
82122UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82123UA_VariableAttributes attr = UA_VariableAttributes_default;
82124attr.minimumSamplingInterval = 0.000000;
82125attr.userAccessLevel = 1;
82126attr.accessLevel = 1;
82127/* Value rank inherited */
82128attr.valueRank = -2;
82129attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82130attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "QueryNextCount");
82131retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82132requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3176LU),
82133parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82134referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82135browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "QueryNextCount"),
82136typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82137attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82138if (retVal != UA_STATUSCODE_GOOD) return retVal;
82139return retVal;
82140}
82141
82142static UA_StatusCode function_namespace0_generated_480_finish(UA_Server *server, UA_UInt16* ns) {
82143return UA_Server_addNode_finish(server,
82144nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3176LU)
82145);
82146}
82147
82148/* QueryFirstCount - ns=0;i=3175 */
82149
82150static UA_StatusCode function_namespace0_generated_481_begin(UA_Server *server, UA_UInt16* ns) {
82151UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82152UA_VariableAttributes attr = UA_VariableAttributes_default;
82153attr.minimumSamplingInterval = 0.000000;
82154attr.userAccessLevel = 1;
82155attr.accessLevel = 1;
82156/* Value rank inherited */
82157attr.valueRank = -2;
82158attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82159attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "QueryFirstCount");
82160retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82161requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3175LU),
82162parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82163referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82164browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "QueryFirstCount"),
82165typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82166attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82167if (retVal != UA_STATUSCODE_GOOD) return retVal;
82168return retVal;
82169}
82170
82171static UA_StatusCode function_namespace0_generated_481_finish(UA_Server *server, UA_UInt16* ns) {
82172return UA_Server_addNode_finish(server,
82173nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3175LU)
82174);
82175}
82176
82177/* TranslateBrowsePathsToNodeIdsCount - ns=0;i=3174 */
82178
82179static UA_StatusCode function_namespace0_generated_482_begin(UA_Server *server, UA_UInt16* ns) {
82180UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82181UA_VariableAttributes attr = UA_VariableAttributes_default;
82182attr.minimumSamplingInterval = 0.000000;
82183attr.userAccessLevel = 1;
82184attr.accessLevel = 1;
82185/* Value rank inherited */
82186attr.valueRank = -2;
82187attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82188attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TranslateBrowsePathsToNodeIdsCount");
82189retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82190requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3174LU),
82191parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82192referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82193browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TranslateBrowsePathsToNodeIdsCount"),
82194typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82195attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82196if (retVal != UA_STATUSCODE_GOOD) return retVal;
82197return retVal;
82198}
82199
82200static UA_StatusCode function_namespace0_generated_482_finish(UA_Server *server, UA_UInt16* ns) {
82201return UA_Server_addNode_finish(server,
82202nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3174LU)
82203);
82204}
82205
82206/* BrowseNextCount - ns=0;i=3173 */
82207
82208static UA_StatusCode function_namespace0_generated_483_begin(UA_Server *server, UA_UInt16* ns) {
82209UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82210UA_VariableAttributes attr = UA_VariableAttributes_default;
82211attr.minimumSamplingInterval = 0.000000;
82212attr.userAccessLevel = 1;
82213attr.accessLevel = 1;
82214/* Value rank inherited */
82215attr.valueRank = -2;
82216attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82217attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BrowseNextCount");
82218retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82219requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3173LU),
82220parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82221referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82222browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BrowseNextCount"),
82223typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82224attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82225if (retVal != UA_STATUSCODE_GOOD) return retVal;
82226return retVal;
82227}
82228
82229static UA_StatusCode function_namespace0_generated_483_finish(UA_Server *server, UA_UInt16* ns) {
82230return UA_Server_addNode_finish(server,
82231nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3173LU)
82232);
82233}
82234
82235/* BrowseCount - ns=0;i=3172 */
82236
82237static UA_StatusCode function_namespace0_generated_484_begin(UA_Server *server, UA_UInt16* ns) {
82238UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82239UA_VariableAttributes attr = UA_VariableAttributes_default;
82240attr.minimumSamplingInterval = 0.000000;
82241attr.userAccessLevel = 1;
82242attr.accessLevel = 1;
82243/* Value rank inherited */
82244attr.valueRank = -2;
82245attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82246attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BrowseCount");
82247retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82248requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3172LU),
82249parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82250referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82251browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BrowseCount"),
82252typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82253attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82254if (retVal != UA_STATUSCODE_GOOD) return retVal;
82255return retVal;
82256}
82257
82258static UA_StatusCode function_namespace0_generated_484_finish(UA_Server *server, UA_UInt16* ns) {
82259return UA_Server_addNode_finish(server,
82260nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3172LU)
82261);
82262}
82263
82264/* DeleteReferencesCount - ns=0;i=3171 */
82265
82266static UA_StatusCode function_namespace0_generated_485_begin(UA_Server *server, UA_UInt16* ns) {
82267UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82268UA_VariableAttributes attr = UA_VariableAttributes_default;
82269attr.minimumSamplingInterval = 0.000000;
82270attr.userAccessLevel = 1;
82271attr.accessLevel = 1;
82272/* Value rank inherited */
82273attr.valueRank = -2;
82274attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82275attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteReferencesCount");
82276retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82277requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3171LU),
82278parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82279referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82280browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteReferencesCount"),
82281typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82282attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82283if (retVal != UA_STATUSCODE_GOOD) return retVal;
82284return retVal;
82285}
82286
82287static UA_StatusCode function_namespace0_generated_485_finish(UA_Server *server, UA_UInt16* ns) {
82288return UA_Server_addNode_finish(server,
82289nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3171LU)
82290);
82291}
82292
82293/* DeleteNodesCount - ns=0;i=3170 */
82294
82295static UA_StatusCode function_namespace0_generated_486_begin(UA_Server *server, UA_UInt16* ns) {
82296UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82297UA_VariableAttributes attr = UA_VariableAttributes_default;
82298attr.minimumSamplingInterval = 0.000000;
82299attr.userAccessLevel = 1;
82300attr.accessLevel = 1;
82301/* Value rank inherited */
82302attr.valueRank = -2;
82303attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82304attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteNodesCount");
82305retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82306requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3170LU),
82307parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82308referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82309browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteNodesCount"),
82310typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82311attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82312if (retVal != UA_STATUSCODE_GOOD) return retVal;
82313return retVal;
82314}
82315
82316static UA_StatusCode function_namespace0_generated_486_finish(UA_Server *server, UA_UInt16* ns) {
82317return UA_Server_addNode_finish(server,
82318nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3170LU)
82319);
82320}
82321
82322/* AddReferencesCount - ns=0;i=3169 */
82323
82324static UA_StatusCode function_namespace0_generated_487_begin(UA_Server *server, UA_UInt16* ns) {
82325UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82326UA_VariableAttributes attr = UA_VariableAttributes_default;
82327attr.minimumSamplingInterval = 0.000000;
82328attr.userAccessLevel = 1;
82329attr.accessLevel = 1;
82330/* Value rank inherited */
82331attr.valueRank = -2;
82332attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82333attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddReferencesCount");
82334retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82335requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3169LU),
82336parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82337referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82338browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddReferencesCount"),
82339typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82340attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82341if (retVal != UA_STATUSCODE_GOOD) return retVal;
82342return retVal;
82343}
82344
82345static UA_StatusCode function_namespace0_generated_487_finish(UA_Server *server, UA_UInt16* ns) {
82346return UA_Server_addNode_finish(server,
82347nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3169LU)
82348);
82349}
82350
82351/* AddNodesCount - ns=0;i=3168 */
82352
82353static UA_StatusCode function_namespace0_generated_488_begin(UA_Server *server, UA_UInt16* ns) {
82354UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82355UA_VariableAttributes attr = UA_VariableAttributes_default;
82356attr.minimumSamplingInterval = 0.000000;
82357attr.userAccessLevel = 1;
82358attr.accessLevel = 1;
82359/* Value rank inherited */
82360attr.valueRank = -2;
82361attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82362attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddNodesCount");
82363retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82364requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3168LU),
82365parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82366referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82367browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddNodesCount"),
82368typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82369attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82370if (retVal != UA_STATUSCODE_GOOD) return retVal;
82371return retVal;
82372}
82373
82374static UA_StatusCode function_namespace0_generated_488_finish(UA_Server *server, UA_UInt16* ns) {
82375return UA_Server_addNode_finish(server,
82376nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3168LU)
82377);
82378}
82379
82380/* DeleteSubscriptionsCount - ns=0;i=3167 */
82381
82382static UA_StatusCode function_namespace0_generated_489_begin(UA_Server *server, UA_UInt16* ns) {
82383UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82384UA_VariableAttributes attr = UA_VariableAttributes_default;
82385attr.minimumSamplingInterval = 0.000000;
82386attr.userAccessLevel = 1;
82387attr.accessLevel = 1;
82388/* Value rank inherited */
82389attr.valueRank = -2;
82390attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82391attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteSubscriptionsCount");
82392retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82393requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3167LU),
82394parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82395referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82396browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteSubscriptionsCount"),
82397typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82398attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82399if (retVal != UA_STATUSCODE_GOOD) return retVal;
82400return retVal;
82401}
82402
82403static UA_StatusCode function_namespace0_generated_489_finish(UA_Server *server, UA_UInt16* ns) {
82404return UA_Server_addNode_finish(server,
82405nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3167LU)
82406);
82407}
82408
82409/* TransferSubscriptionsCount - ns=0;i=3166 */
82410
82411static UA_StatusCode function_namespace0_generated_490_begin(UA_Server *server, UA_UInt16* ns) {
82412UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82413UA_VariableAttributes attr = UA_VariableAttributes_default;
82414attr.minimumSamplingInterval = 0.000000;
82415attr.userAccessLevel = 1;
82416attr.accessLevel = 1;
82417/* Value rank inherited */
82418attr.valueRank = -2;
82419attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82420attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransferSubscriptionsCount");
82421retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82422requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3166LU),
82423parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82424referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82425browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransferSubscriptionsCount"),
82426typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82427attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82428if (retVal != UA_STATUSCODE_GOOD) return retVal;
82429return retVal;
82430}
82431
82432static UA_StatusCode function_namespace0_generated_490_finish(UA_Server *server, UA_UInt16* ns) {
82433return UA_Server_addNode_finish(server,
82434nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3166LU)
82435);
82436}
82437
82438/* RepublishCount - ns=0;i=3165 */
82439
82440static UA_StatusCode function_namespace0_generated_491_begin(UA_Server *server, UA_UInt16* ns) {
82441UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82442UA_VariableAttributes attr = UA_VariableAttributes_default;
82443attr.minimumSamplingInterval = 0.000000;
82444attr.userAccessLevel = 1;
82445attr.accessLevel = 1;
82446/* Value rank inherited */
82447attr.valueRank = -2;
82448attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82449attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RepublishCount");
82450retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82451requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3165LU),
82452parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82453referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82454browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RepublishCount"),
82455typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82456attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82457if (retVal != UA_STATUSCODE_GOOD) return retVal;
82458return retVal;
82459}
82460
82461static UA_StatusCode function_namespace0_generated_491_finish(UA_Server *server, UA_UInt16* ns) {
82462return UA_Server_addNode_finish(server,
82463nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3165LU)
82464);
82465}
82466
82467/* PublishCount - ns=0;i=3164 */
82468
82469static UA_StatusCode function_namespace0_generated_492_begin(UA_Server *server, UA_UInt16* ns) {
82470UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82471UA_VariableAttributes attr = UA_VariableAttributes_default;
82472attr.minimumSamplingInterval = 0.000000;
82473attr.userAccessLevel = 1;
82474attr.accessLevel = 1;
82475/* Value rank inherited */
82476attr.valueRank = -2;
82477attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82478attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishCount");
82479retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82480requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3164LU),
82481parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82482referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82483browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishCount"),
82484typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82485attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82486if (retVal != UA_STATUSCODE_GOOD) return retVal;
82487return retVal;
82488}
82489
82490static UA_StatusCode function_namespace0_generated_492_finish(UA_Server *server, UA_UInt16* ns) {
82491return UA_Server_addNode_finish(server,
82492nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3164LU)
82493);
82494}
82495
82496/* SetPublishingModeCount - ns=0;i=3163 */
82497
82498static UA_StatusCode function_namespace0_generated_493_begin(UA_Server *server, UA_UInt16* ns) {
82499UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82500UA_VariableAttributes attr = UA_VariableAttributes_default;
82501attr.minimumSamplingInterval = 0.000000;
82502attr.userAccessLevel = 1;
82503attr.accessLevel = 1;
82504/* Value rank inherited */
82505attr.valueRank = -2;
82506attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82507attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SetPublishingModeCount");
82508retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82509requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3163LU),
82510parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82511referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82512browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SetPublishingModeCount"),
82513typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82514attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82515if (retVal != UA_STATUSCODE_GOOD) return retVal;
82516return retVal;
82517}
82518
82519static UA_StatusCode function_namespace0_generated_493_finish(UA_Server *server, UA_UInt16* ns) {
82520return UA_Server_addNode_finish(server,
82521nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3163LU)
82522);
82523}
82524
82525/* ModifySubscriptionCount - ns=0;i=3162 */
82526
82527static UA_StatusCode function_namespace0_generated_494_begin(UA_Server *server, UA_UInt16* ns) {
82528UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82529UA_VariableAttributes attr = UA_VariableAttributes_default;
82530attr.minimumSamplingInterval = 0.000000;
82531attr.userAccessLevel = 1;
82532attr.accessLevel = 1;
82533/* Value rank inherited */
82534attr.valueRank = -2;
82535attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82536attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ModifySubscriptionCount");
82537retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82538requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3162LU),
82539parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82540referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82541browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ModifySubscriptionCount"),
82542typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82543attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82544if (retVal != UA_STATUSCODE_GOOD) return retVal;
82545return retVal;
82546}
82547
82548static UA_StatusCode function_namespace0_generated_494_finish(UA_Server *server, UA_UInt16* ns) {
82549return UA_Server_addNode_finish(server,
82550nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3162LU)
82551);
82552}
82553
82554/* CreateSubscriptionCount - ns=0;i=3161 */
82555
82556static UA_StatusCode function_namespace0_generated_495_begin(UA_Server *server, UA_UInt16* ns) {
82557UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82558UA_VariableAttributes attr = UA_VariableAttributes_default;
82559attr.minimumSamplingInterval = 0.000000;
82560attr.userAccessLevel = 1;
82561attr.accessLevel = 1;
82562/* Value rank inherited */
82563attr.valueRank = -2;
82564attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82565attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CreateSubscriptionCount");
82566retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82567requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3161LU),
82568parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82569referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82570browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CreateSubscriptionCount"),
82571typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82572attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82573if (retVal != UA_STATUSCODE_GOOD) return retVal;
82574return retVal;
82575}
82576
82577static UA_StatusCode function_namespace0_generated_495_finish(UA_Server *server, UA_UInt16* ns) {
82578return UA_Server_addNode_finish(server,
82579nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3161LU)
82580);
82581}
82582
82583/* DeleteMonitoredItemsCount - ns=0;i=3160 */
82584
82585static UA_StatusCode function_namespace0_generated_496_begin(UA_Server *server, UA_UInt16* ns) {
82586UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82587UA_VariableAttributes attr = UA_VariableAttributes_default;
82588attr.minimumSamplingInterval = 0.000000;
82589attr.userAccessLevel = 1;
82590attr.accessLevel = 1;
82591/* Value rank inherited */
82592attr.valueRank = -2;
82593attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82594attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteMonitoredItemsCount");
82595retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82596requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3160LU),
82597parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82598referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82599browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteMonitoredItemsCount"),
82600typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82601attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82602if (retVal != UA_STATUSCODE_GOOD) return retVal;
82603return retVal;
82604}
82605
82606static UA_StatusCode function_namespace0_generated_496_finish(UA_Server *server, UA_UInt16* ns) {
82607return UA_Server_addNode_finish(server,
82608nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3160LU)
82609);
82610}
82611
82612/* SetTriggeringCount - ns=0;i=3159 */
82613
82614static UA_StatusCode function_namespace0_generated_497_begin(UA_Server *server, UA_UInt16* ns) {
82615UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82616UA_VariableAttributes attr = UA_VariableAttributes_default;
82617attr.minimumSamplingInterval = 0.000000;
82618attr.userAccessLevel = 1;
82619attr.accessLevel = 1;
82620/* Value rank inherited */
82621attr.valueRank = -2;
82622attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82623attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SetTriggeringCount");
82624retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82625requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3159LU),
82626parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82627referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82628browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SetTriggeringCount"),
82629typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82630attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82631if (retVal != UA_STATUSCODE_GOOD) return retVal;
82632return retVal;
82633}
82634
82635static UA_StatusCode function_namespace0_generated_497_finish(UA_Server *server, UA_UInt16* ns) {
82636return UA_Server_addNode_finish(server,
82637nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3159LU)
82638);
82639}
82640
82641/* SetMonitoringModeCount - ns=0;i=3158 */
82642
82643static UA_StatusCode function_namespace0_generated_498_begin(UA_Server *server, UA_UInt16* ns) {
82644UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82645UA_VariableAttributes attr = UA_VariableAttributes_default;
82646attr.minimumSamplingInterval = 0.000000;
82647attr.userAccessLevel = 1;
82648attr.accessLevel = 1;
82649/* Value rank inherited */
82650attr.valueRank = -2;
82651attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82652attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SetMonitoringModeCount");
82653retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82654requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3158LU),
82655parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82656referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82657browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SetMonitoringModeCount"),
82658typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82659attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82660if (retVal != UA_STATUSCODE_GOOD) return retVal;
82661return retVal;
82662}
82663
82664static UA_StatusCode function_namespace0_generated_498_finish(UA_Server *server, UA_UInt16* ns) {
82665return UA_Server_addNode_finish(server,
82666nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3158LU)
82667);
82668}
82669
82670/* ModifyMonitoredItemsCount - ns=0;i=3157 */
82671
82672static UA_StatusCode function_namespace0_generated_499_begin(UA_Server *server, UA_UInt16* ns) {
82673UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82674UA_VariableAttributes attr = UA_VariableAttributes_default;
82675attr.minimumSamplingInterval = 0.000000;
82676attr.userAccessLevel = 1;
82677attr.accessLevel = 1;
82678/* Value rank inherited */
82679attr.valueRank = -2;
82680attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82681attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ModifyMonitoredItemsCount");
82682retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82683requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3157LU),
82684parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82685referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82686browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ModifyMonitoredItemsCount"),
82687typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82688attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82689if (retVal != UA_STATUSCODE_GOOD) return retVal;
82690return retVal;
82691}
82692
82693static UA_StatusCode function_namespace0_generated_499_finish(UA_Server *server, UA_UInt16* ns) {
82694return UA_Server_addNode_finish(server,
82695nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3157LU)
82696);
82697}
82698
82699/* CreateMonitoredItemsCount - ns=0;i=3156 */
82700
82701static UA_StatusCode function_namespace0_generated_500_begin(UA_Server *server, UA_UInt16* ns) {
82702UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82703UA_VariableAttributes attr = UA_VariableAttributes_default;
82704attr.minimumSamplingInterval = 0.000000;
82705attr.userAccessLevel = 1;
82706attr.accessLevel = 1;
82707/* Value rank inherited */
82708attr.valueRank = -2;
82709attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82710attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CreateMonitoredItemsCount");
82711retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82712requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3156LU),
82713parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82714referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82715browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CreateMonitoredItemsCount"),
82716typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82717attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82718if (retVal != UA_STATUSCODE_GOOD) return retVal;
82719return retVal;
82720}
82721
82722static UA_StatusCode function_namespace0_generated_500_finish(UA_Server *server, UA_UInt16* ns) {
82723return UA_Server_addNode_finish(server,
82724nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3156LU)
82725);
82726}
82727
82728/* CallCount - ns=0;i=3155 */
82729
82730static UA_StatusCode function_namespace0_generated_501_begin(UA_Server *server, UA_UInt16* ns) {
82731UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82732UA_VariableAttributes attr = UA_VariableAttributes_default;
82733attr.minimumSamplingInterval = 0.000000;
82734attr.userAccessLevel = 1;
82735attr.accessLevel = 1;
82736/* Value rank inherited */
82737attr.valueRank = -2;
82738attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82739attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CallCount");
82740retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82741requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3155LU),
82742parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82743referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82744browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CallCount"),
82745typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82746attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82747if (retVal != UA_STATUSCODE_GOOD) return retVal;
82748return retVal;
82749}
82750
82751static UA_StatusCode function_namespace0_generated_501_finish(UA_Server *server, UA_UInt16* ns) {
82752return UA_Server_addNode_finish(server,
82753nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3155LU)
82754);
82755}
82756
82757/* HistoryUpdateCount - ns=0;i=3154 */
82758
82759static UA_StatusCode function_namespace0_generated_502_begin(UA_Server *server, UA_UInt16* ns) {
82760UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82761UA_VariableAttributes attr = UA_VariableAttributes_default;
82762attr.minimumSamplingInterval = 0.000000;
82763attr.userAccessLevel = 1;
82764attr.accessLevel = 1;
82765/* Value rank inherited */
82766attr.valueRank = -2;
82767attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82768attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HistoryUpdateCount");
82769retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82770requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3154LU),
82771parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82772referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82773browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HistoryUpdateCount"),
82774typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82775attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82776if (retVal != UA_STATUSCODE_GOOD) return retVal;
82777return retVal;
82778}
82779
82780static UA_StatusCode function_namespace0_generated_502_finish(UA_Server *server, UA_UInt16* ns) {
82781return UA_Server_addNode_finish(server,
82782nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3154LU)
82783);
82784}
82785
82786/* WriteCount - ns=0;i=3153 */
82787
82788static UA_StatusCode function_namespace0_generated_503_begin(UA_Server *server, UA_UInt16* ns) {
82789UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82790UA_VariableAttributes attr = UA_VariableAttributes_default;
82791attr.minimumSamplingInterval = 0.000000;
82792attr.userAccessLevel = 1;
82793attr.accessLevel = 1;
82794/* Value rank inherited */
82795attr.valueRank = -2;
82796attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82797attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "WriteCount");
82798retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82799requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3153LU),
82800parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82801referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82802browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "WriteCount"),
82803typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82804attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82805if (retVal != UA_STATUSCODE_GOOD) return retVal;
82806return retVal;
82807}
82808
82809static UA_StatusCode function_namespace0_generated_503_finish(UA_Server *server, UA_UInt16* ns) {
82810return UA_Server_addNode_finish(server,
82811nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3153LU)
82812);
82813}
82814
82815/* HistoryReadCount - ns=0;i=3152 */
82816
82817static UA_StatusCode function_namespace0_generated_504_begin(UA_Server *server, UA_UInt16* ns) {
82818UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82819UA_VariableAttributes attr = UA_VariableAttributes_default;
82820attr.minimumSamplingInterval = 0.000000;
82821attr.userAccessLevel = 1;
82822attr.accessLevel = 1;
82823/* Value rank inherited */
82824attr.valueRank = -2;
82825attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82826attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HistoryReadCount");
82827retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82828requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3152LU),
82829parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82830referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82831browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HistoryReadCount"),
82832typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82833attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82834if (retVal != UA_STATUSCODE_GOOD) return retVal;
82835return retVal;
82836}
82837
82838static UA_StatusCode function_namespace0_generated_504_finish(UA_Server *server, UA_UInt16* ns) {
82839return UA_Server_addNode_finish(server,
82840nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3152LU)
82841);
82842}
82843
82844/* ReadCount - ns=0;i=3151 */
82845
82846static UA_StatusCode function_namespace0_generated_505_begin(UA_Server *server, UA_UInt16* ns) {
82847UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82848UA_VariableAttributes attr = UA_VariableAttributes_default;
82849attr.minimumSamplingInterval = 0.000000;
82850attr.userAccessLevel = 1;
82851attr.accessLevel = 1;
82852/* Value rank inherited */
82853attr.valueRank = -2;
82854attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
82855attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ReadCount");
82856retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82857requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3151LU),
82858parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82859referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82860browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ReadCount"),
82861typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82862attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82863if (retVal != UA_STATUSCODE_GOOD) return retVal;
82864return retVal;
82865}
82866
82867static UA_StatusCode function_namespace0_generated_505_finish(UA_Server *server, UA_UInt16* ns) {
82868return UA_Server_addNode_finish(server,
82869nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3151LU)
82870);
82871}
82872
82873/* CurrentPublishRequestsInQueue - ns=0;i=3143 */
82874
82875static UA_StatusCode function_namespace0_generated_506_begin(UA_Server *server, UA_UInt16* ns) {
82876UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82877UA_VariableAttributes attr = UA_VariableAttributes_default;
82878attr.minimumSamplingInterval = 0.000000;
82879attr.userAccessLevel = 1;
82880attr.accessLevel = 1;
82881/* Value rank inherited */
82882attr.valueRank = -2;
82883attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
82884attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentPublishRequestsInQueue");
82885retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82886requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3143LU),
82887parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82888referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82889browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentPublishRequestsInQueue"),
82890typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82891attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82892if (retVal != UA_STATUSCODE_GOOD) return retVal;
82893return retVal;
82894}
82895
82896static UA_StatusCode function_namespace0_generated_506_finish(UA_Server *server, UA_UInt16* ns) {
82897return UA_Server_addNode_finish(server,
82898nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3143LU)
82899);
82900}
82901
82902/* CurrentMonitoredItemsCount - ns=0;i=3142 */
82903
82904static UA_StatusCode function_namespace0_generated_507_begin(UA_Server *server, UA_UInt16* ns) {
82905UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82906UA_VariableAttributes attr = UA_VariableAttributes_default;
82907attr.minimumSamplingInterval = 0.000000;
82908attr.userAccessLevel = 1;
82909attr.accessLevel = 1;
82910/* Value rank inherited */
82911attr.valueRank = -2;
82912attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
82913attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentMonitoredItemsCount");
82914retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82915requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3142LU),
82916parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82917referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82918browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentMonitoredItemsCount"),
82919typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82920attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82921if (retVal != UA_STATUSCODE_GOOD) return retVal;
82922return retVal;
82923}
82924
82925static UA_StatusCode function_namespace0_generated_507_finish(UA_Server *server, UA_UInt16* ns) {
82926return UA_Server_addNode_finish(server,
82927nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3142LU)
82928);
82929}
82930
82931/* CurrentSubscriptionsCount - ns=0;i=3141 */
82932
82933static UA_StatusCode function_namespace0_generated_508_begin(UA_Server *server, UA_UInt16* ns) {
82934UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82935UA_VariableAttributes attr = UA_VariableAttributes_default;
82936attr.minimumSamplingInterval = 0.000000;
82937attr.userAccessLevel = 1;
82938attr.accessLevel = 1;
82939/* Value rank inherited */
82940attr.valueRank = -2;
82941attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
82942attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentSubscriptionsCount");
82943retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82944requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3141LU),
82945parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82946referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82947browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentSubscriptionsCount"),
82948typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82949attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82950if (retVal != UA_STATUSCODE_GOOD) return retVal;
82951return retVal;
82952}
82953
82954static UA_StatusCode function_namespace0_generated_508_finish(UA_Server *server, UA_UInt16* ns) {
82955return UA_Server_addNode_finish(server,
82956nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3141LU)
82957);
82958}
82959
82960/* ClientLastContactTime - ns=0;i=3140 */
82961
82962static UA_StatusCode function_namespace0_generated_509_begin(UA_Server *server, UA_UInt16* ns) {
82963UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82964UA_VariableAttributes attr = UA_VariableAttributes_default;
82965attr.minimumSamplingInterval = 0.000000;
82966attr.userAccessLevel = 1;
82967attr.accessLevel = 1;
82968/* Value rank inherited */
82969attr.valueRank = -2;
82970attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
82971attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientLastContactTime");
82972retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
82973requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3140LU),
82974parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
82975referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
82976browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientLastContactTime"),
82977typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
82978attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
82979if (retVal != UA_STATUSCODE_GOOD) return retVal;
82980return retVal;
82981}
82982
82983static UA_StatusCode function_namespace0_generated_509_finish(UA_Server *server, UA_UInt16* ns) {
82984return UA_Server_addNode_finish(server,
82985nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3140LU)
82986);
82987}
82988
82989/* ClientConnectionTime - ns=0;i=3139 */
82990
82991static UA_StatusCode function_namespace0_generated_510_begin(UA_Server *server, UA_UInt16* ns) {
82992UA_StatusCode retVal = UA_STATUSCODE_GOOD;
82993UA_VariableAttributes attr = UA_VariableAttributes_default;
82994attr.minimumSamplingInterval = 0.000000;
82995attr.userAccessLevel = 1;
82996attr.accessLevel = 1;
82997/* Value rank inherited */
82998attr.valueRank = -2;
82999attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
83000attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientConnectionTime");
83001retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83002requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3139LU),
83003parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
83004referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83005browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientConnectionTime"),
83006typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83007attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83008if (retVal != UA_STATUSCODE_GOOD) return retVal;
83009return retVal;
83010}
83011
83012static UA_StatusCode function_namespace0_generated_510_finish(UA_Server *server, UA_UInt16* ns) {
83013return UA_Server_addNode_finish(server,
83014nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3139LU)
83015);
83016}
83017
83018/* MaxResponseMessageSize - ns=0;i=3138 */
83019
83020static UA_StatusCode function_namespace0_generated_511_begin(UA_Server *server, UA_UInt16* ns) {
83021UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83022UA_VariableAttributes attr = UA_VariableAttributes_default;
83023attr.minimumSamplingInterval = 0.000000;
83024attr.userAccessLevel = 1;
83025attr.accessLevel = 1;
83026/* Value rank inherited */
83027attr.valueRank = -2;
83028attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83029attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxResponseMessageSize");
83030retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83031requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3138LU),
83032parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
83033referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83034browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxResponseMessageSize"),
83035typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83036attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83037if (retVal != UA_STATUSCODE_GOOD) return retVal;
83038return retVal;
83039}
83040
83041static UA_StatusCode function_namespace0_generated_511_finish(UA_Server *server, UA_UInt16* ns) {
83042return UA_Server_addNode_finish(server,
83043nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3138LU)
83044);
83045}
83046
83047/* ActualSessionTimeout - ns=0;i=3137 */
83048
83049static UA_StatusCode function_namespace0_generated_512_begin(UA_Server *server, UA_UInt16* ns) {
83050UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83051UA_VariableAttributes attr = UA_VariableAttributes_default;
83052attr.minimumSamplingInterval = 0.000000;
83053attr.userAccessLevel = 1;
83054attr.accessLevel = 1;
83055/* Value rank inherited */
83056attr.valueRank = -2;
83057attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU);
83058attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ActualSessionTimeout");
83059retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83060requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3137LU),
83061parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
83062referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83063browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ActualSessionTimeout"),
83064typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83065attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83066if (retVal != UA_STATUSCODE_GOOD) return retVal;
83067return retVal;
83068}
83069
83070static UA_StatusCode function_namespace0_generated_512_finish(UA_Server *server, UA_UInt16* ns) {
83071return UA_Server_addNode_finish(server,
83072nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3137LU)
83073);
83074}
83075
83076/* LocaleIds - ns=0;i=3136 */
83077
83078static UA_StatusCode function_namespace0_generated_513_begin(UA_Server *server, UA_UInt16* ns) {
83079UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83080UA_VariableAttributes attr = UA_VariableAttributes_default;
83081attr.minimumSamplingInterval = 0.000000;
83082attr.userAccessLevel = 1;
83083attr.accessLevel = 1;
83084attr.valueRank = 1;
83085attr.arrayDimensionsSize = 1;
83086UA_UInt32 arrayDimensions[1];
83087arrayDimensions[0] = 0;
83088attr.arrayDimensions = &arrayDimensions[0];
83089attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 295LU);
83090attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "LocaleIds");
83091retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83092requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3136LU),
83093parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
83094referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83095browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "LocaleIds"),
83096typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83097attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83098if (retVal != UA_STATUSCODE_GOOD) return retVal;
83099return retVal;
83100}
83101
83102static UA_StatusCode function_namespace0_generated_513_finish(UA_Server *server, UA_UInt16* ns) {
83103return UA_Server_addNode_finish(server,
83104nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3136LU)
83105);
83106}
83107
83108/* EndpointUrl - ns=0;i=3135 */
83109
83110static UA_StatusCode function_namespace0_generated_514_begin(UA_Server *server, UA_UInt16* ns) {
83111UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83112UA_VariableAttributes attr = UA_VariableAttributes_default;
83113attr.minimumSamplingInterval = 0.000000;
83114attr.userAccessLevel = 1;
83115attr.accessLevel = 1;
83116/* Value rank inherited */
83117attr.valueRank = -2;
83118attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
83119attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EndpointUrl");
83120retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83121requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3135LU),
83122parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
83123referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83124browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EndpointUrl"),
83125typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83126attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83127if (retVal != UA_STATUSCODE_GOOD) return retVal;
83128return retVal;
83129}
83130
83131static UA_StatusCode function_namespace0_generated_514_finish(UA_Server *server, UA_UInt16* ns) {
83132return UA_Server_addNode_finish(server,
83133nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3135LU)
83134);
83135}
83136
83137/* ServerUri - ns=0;i=3134 */
83138
83139static UA_StatusCode function_namespace0_generated_515_begin(UA_Server *server, UA_UInt16* ns) {
83140UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83141UA_VariableAttributes attr = UA_VariableAttributes_default;
83142attr.minimumSamplingInterval = 0.000000;
83143attr.userAccessLevel = 1;
83144attr.accessLevel = 1;
83145/* Value rank inherited */
83146attr.valueRank = -2;
83147attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
83148attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerUri");
83149retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83150requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3134LU),
83151parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
83152referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83153browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerUri"),
83154typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83155attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83156if (retVal != UA_STATUSCODE_GOOD) return retVal;
83157return retVal;
83158}
83159
83160static UA_StatusCode function_namespace0_generated_515_finish(UA_Server *server, UA_UInt16* ns) {
83161return UA_Server_addNode_finish(server,
83162nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3134LU)
83163);
83164}
83165
83166/* ClientDescription - ns=0;i=3133 */
83167
83168static UA_StatusCode function_namespace0_generated_516_begin(UA_Server *server, UA_UInt16* ns) {
83169UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83170UA_VariableAttributes attr = UA_VariableAttributes_default;
83171attr.minimumSamplingInterval = 0.000000;
83172attr.userAccessLevel = 1;
83173attr.accessLevel = 1;
83174/* Value rank inherited */
83175attr.valueRank = -2;
83176attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 308LU);
83177attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientDescription");
83178retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83179requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3133LU),
83180parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
83181referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83182browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientDescription"),
83183typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83184attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83185if (retVal != UA_STATUSCODE_GOOD) return retVal;
83186return retVal;
83187}
83188
83189static UA_StatusCode function_namespace0_generated_516_finish(UA_Server *server, UA_UInt16* ns) {
83190return UA_Server_addNode_finish(server,
83191nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3133LU)
83192);
83193}
83194
83195/* SessionName - ns=0;i=3132 */
83196
83197static UA_StatusCode function_namespace0_generated_517_begin(UA_Server *server, UA_UInt16* ns) {
83198UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83199UA_VariableAttributes attr = UA_VariableAttributes_default;
83200attr.minimumSamplingInterval = 0.000000;
83201attr.userAccessLevel = 1;
83202attr.accessLevel = 1;
83203/* Value rank inherited */
83204attr.valueRank = -2;
83205attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
83206attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionName");
83207retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83208requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3132LU),
83209parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
83210referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83211browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionName"),
83212typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83213attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83214if (retVal != UA_STATUSCODE_GOOD) return retVal;
83215return retVal;
83216}
83217
83218static UA_StatusCode function_namespace0_generated_517_finish(UA_Server *server, UA_UInt16* ns) {
83219return UA_Server_addNode_finish(server,
83220nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3132LU)
83221);
83222}
83223
83224/* SessionId - ns=0;i=3131 */
83225
83226static UA_StatusCode function_namespace0_generated_518_begin(UA_Server *server, UA_UInt16* ns) {
83227UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83228UA_VariableAttributes attr = UA_VariableAttributes_default;
83229attr.minimumSamplingInterval = 0.000000;
83230attr.userAccessLevel = 1;
83231attr.accessLevel = 1;
83232/* Value rank inherited */
83233attr.valueRank = -2;
83234attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
83235attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionId");
83236retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83237requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3131LU),
83238parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
83239referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83240browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionId"),
83241typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83242attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83243if (retVal != UA_STATUSCODE_GOOD) return retVal;
83244return retVal;
83245}
83246
83247static UA_StatusCode function_namespace0_generated_518_finish(UA_Server *server, UA_UInt16* ns) {
83248return UA_Server_addNode_finish(server,
83249nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3131LU)
83250);
83251}
83252
83253/* UnauthorizedRequestCount - ns=0;i=11891 */
83254
83255static UA_StatusCode function_namespace0_generated_519_begin(UA_Server *server, UA_UInt16* ns) {
83256UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83257UA_VariableAttributes attr = UA_VariableAttributes_default;
83258attr.minimumSamplingInterval = 0.000000;
83259attr.userAccessLevel = 1;
83260attr.accessLevel = 1;
83261/* Value rank inherited */
83262attr.valueRank = -2;
83263attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83264attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UnauthorizedRequestCount");
83265retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83266requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11891LU),
83267parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU),
83268referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83269browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UnauthorizedRequestCount"),
83270typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83271attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83272if (retVal != UA_STATUSCODE_GOOD) return retVal;
83273return retVal;
83274}
83275
83276static UA_StatusCode function_namespace0_generated_519_finish(UA_Server *server, UA_UInt16* ns) {
83277return UA_Server_addNode_finish(server,
83278nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11891LU)
83279);
83280}
83281
83282/* ServerDiagnosticsSummaryType - ns=0;i=2150 */
83283
83284static UA_StatusCode function_namespace0_generated_520_begin(UA_Server *server, UA_UInt16* ns) {
83285UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83286UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
83287/* Value rank inherited */
83288attr.valueRank = -2;
83289attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 859LU);
83290attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerDiagnosticsSummaryType");
83291retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
83292requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
83293parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83294referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
83295browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerDiagnosticsSummaryType"),
83296typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
83297attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
83298if (retVal != UA_STATUSCODE_GOOD) return retVal;
83299return retVal;
83300}
83301
83302static UA_StatusCode function_namespace0_generated_520_finish(UA_Server *server, UA_UInt16* ns) {
83303return UA_Server_addNode_finish(server,
83304nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU)
83305);
83306}
83307
83308/* RejectedRequestsCount - ns=0;i=2163 */
83309
83310static UA_StatusCode function_namespace0_generated_521_begin(UA_Server *server, UA_UInt16* ns) {
83311UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83312UA_VariableAttributes attr = UA_VariableAttributes_default;
83313attr.minimumSamplingInterval = 0.000000;
83314attr.userAccessLevel = 1;
83315attr.accessLevel = 1;
83316/* Value rank inherited */
83317attr.valueRank = -2;
83318attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83319attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RejectedRequestsCount");
83320retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83321requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2163LU),
83322parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
83323referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83324browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RejectedRequestsCount"),
83325typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83326attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83327if (retVal != UA_STATUSCODE_GOOD) return retVal;
83328return retVal;
83329}
83330
83331static UA_StatusCode function_namespace0_generated_521_finish(UA_Server *server, UA_UInt16* ns) {
83332return UA_Server_addNode_finish(server,
83333nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2163LU)
83334);
83335}
83336
83337/* SecurityRejectedRequestsCount - ns=0;i=2162 */
83338
83339static UA_StatusCode function_namespace0_generated_522_begin(UA_Server *server, UA_UInt16* ns) {
83340UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83341UA_VariableAttributes attr = UA_VariableAttributes_default;
83342attr.minimumSamplingInterval = 0.000000;
83343attr.userAccessLevel = 1;
83344attr.accessLevel = 1;
83345/* Value rank inherited */
83346attr.valueRank = -2;
83347attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83348attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityRejectedRequestsCount");
83349retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83350requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2162LU),
83351parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
83352referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83353browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityRejectedRequestsCount"),
83354typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83355attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83356if (retVal != UA_STATUSCODE_GOOD) return retVal;
83357return retVal;
83358}
83359
83360static UA_StatusCode function_namespace0_generated_522_finish(UA_Server *server, UA_UInt16* ns) {
83361return UA_Server_addNode_finish(server,
83362nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2162LU)
83363);
83364}
83365
83366/* CumulatedSubscriptionCount - ns=0;i=2161 */
83367
83368static UA_StatusCode function_namespace0_generated_523_begin(UA_Server *server, UA_UInt16* ns) {
83369UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83370UA_VariableAttributes attr = UA_VariableAttributes_default;
83371attr.minimumSamplingInterval = 0.000000;
83372attr.userAccessLevel = 1;
83373attr.accessLevel = 1;
83374/* Value rank inherited */
83375attr.valueRank = -2;
83376attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83377attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CumulatedSubscriptionCount");
83378retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83379requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2161LU),
83380parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
83381referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83382browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CumulatedSubscriptionCount"),
83383typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83384attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83385if (retVal != UA_STATUSCODE_GOOD) return retVal;
83386return retVal;
83387}
83388
83389static UA_StatusCode function_namespace0_generated_523_finish(UA_Server *server, UA_UInt16* ns) {
83390return UA_Server_addNode_finish(server,
83391nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2161LU)
83392);
83393}
83394
83395/* CurrentSubscriptionCount - ns=0;i=2160 */
83396
83397static UA_StatusCode function_namespace0_generated_524_begin(UA_Server *server, UA_UInt16* ns) {
83398UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83399UA_VariableAttributes attr = UA_VariableAttributes_default;
83400attr.minimumSamplingInterval = 0.000000;
83401attr.userAccessLevel = 1;
83402attr.accessLevel = 1;
83403/* Value rank inherited */
83404attr.valueRank = -2;
83405attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83406attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentSubscriptionCount");
83407retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83408requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2160LU),
83409parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
83410referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83411browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentSubscriptionCount"),
83412typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83413attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83414if (retVal != UA_STATUSCODE_GOOD) return retVal;
83415return retVal;
83416}
83417
83418static UA_StatusCode function_namespace0_generated_524_finish(UA_Server *server, UA_UInt16* ns) {
83419return UA_Server_addNode_finish(server,
83420nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2160LU)
83421);
83422}
83423
83424/* PublishingIntervalCount - ns=0;i=2159 */
83425
83426static UA_StatusCode function_namespace0_generated_525_begin(UA_Server *server, UA_UInt16* ns) {
83427UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83428UA_VariableAttributes attr = UA_VariableAttributes_default;
83429attr.minimumSamplingInterval = 0.000000;
83430attr.userAccessLevel = 1;
83431attr.accessLevel = 1;
83432/* Value rank inherited */
83433attr.valueRank = -2;
83434attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83435attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishingIntervalCount");
83436retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83437requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2159LU),
83438parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
83439referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83440browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishingIntervalCount"),
83441typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83442attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83443if (retVal != UA_STATUSCODE_GOOD) return retVal;
83444return retVal;
83445}
83446
83447static UA_StatusCode function_namespace0_generated_525_finish(UA_Server *server, UA_UInt16* ns) {
83448return UA_Server_addNode_finish(server,
83449nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2159LU)
83450);
83451}
83452
83453/* SessionAbortCount - ns=0;i=2157 */
83454
83455static UA_StatusCode function_namespace0_generated_526_begin(UA_Server *server, UA_UInt16* ns) {
83456UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83457UA_VariableAttributes attr = UA_VariableAttributes_default;
83458attr.minimumSamplingInterval = 0.000000;
83459attr.userAccessLevel = 1;
83460attr.accessLevel = 1;
83461/* Value rank inherited */
83462attr.valueRank = -2;
83463attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83464attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionAbortCount");
83465retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83466requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2157LU),
83467parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
83468referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83469browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionAbortCount"),
83470typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83471attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83472if (retVal != UA_STATUSCODE_GOOD) return retVal;
83473return retVal;
83474}
83475
83476static UA_StatusCode function_namespace0_generated_526_finish(UA_Server *server, UA_UInt16* ns) {
83477return UA_Server_addNode_finish(server,
83478nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2157LU)
83479);
83480}
83481
83482/* SessionTimeoutCount - ns=0;i=2156 */
83483
83484static UA_StatusCode function_namespace0_generated_527_begin(UA_Server *server, UA_UInt16* ns) {
83485UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83486UA_VariableAttributes attr = UA_VariableAttributes_default;
83487attr.minimumSamplingInterval = 0.000000;
83488attr.userAccessLevel = 1;
83489attr.accessLevel = 1;
83490/* Value rank inherited */
83491attr.valueRank = -2;
83492attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83493attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionTimeoutCount");
83494retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83495requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2156LU),
83496parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
83497referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83498browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionTimeoutCount"),
83499typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83500attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83501if (retVal != UA_STATUSCODE_GOOD) return retVal;
83502return retVal;
83503}
83504
83505static UA_StatusCode function_namespace0_generated_527_finish(UA_Server *server, UA_UInt16* ns) {
83506return UA_Server_addNode_finish(server,
83507nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2156LU)
83508);
83509}
83510
83511/* RejectedSessionCount - ns=0;i=2155 */
83512
83513static UA_StatusCode function_namespace0_generated_528_begin(UA_Server *server, UA_UInt16* ns) {
83514UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83515UA_VariableAttributes attr = UA_VariableAttributes_default;
83516attr.minimumSamplingInterval = 0.000000;
83517attr.userAccessLevel = 1;
83518attr.accessLevel = 1;
83519/* Value rank inherited */
83520attr.valueRank = -2;
83521attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83522attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RejectedSessionCount");
83523retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83524requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2155LU),
83525parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
83526referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83527browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RejectedSessionCount"),
83528typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83529attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83530if (retVal != UA_STATUSCODE_GOOD) return retVal;
83531return retVal;
83532}
83533
83534static UA_StatusCode function_namespace0_generated_528_finish(UA_Server *server, UA_UInt16* ns) {
83535return UA_Server_addNode_finish(server,
83536nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2155LU)
83537);
83538}
83539
83540/* SecurityRejectedSessionCount - ns=0;i=2154 */
83541
83542static UA_StatusCode function_namespace0_generated_529_begin(UA_Server *server, UA_UInt16* ns) {
83543UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83544UA_VariableAttributes attr = UA_VariableAttributes_default;
83545attr.minimumSamplingInterval = 0.000000;
83546attr.userAccessLevel = 1;
83547attr.accessLevel = 1;
83548/* Value rank inherited */
83549attr.valueRank = -2;
83550attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83551attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityRejectedSessionCount");
83552retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83553requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2154LU),
83554parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
83555referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83556browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityRejectedSessionCount"),
83557typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83558attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83559if (retVal != UA_STATUSCODE_GOOD) return retVal;
83560return retVal;
83561}
83562
83563static UA_StatusCode function_namespace0_generated_529_finish(UA_Server *server, UA_UInt16* ns) {
83564return UA_Server_addNode_finish(server,
83565nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2154LU)
83566);
83567}
83568
83569/* CumulatedSessionCount - ns=0;i=2153 */
83570
83571static UA_StatusCode function_namespace0_generated_530_begin(UA_Server *server, UA_UInt16* ns) {
83572UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83573UA_VariableAttributes attr = UA_VariableAttributes_default;
83574attr.minimumSamplingInterval = 0.000000;
83575attr.userAccessLevel = 1;
83576attr.accessLevel = 1;
83577/* Value rank inherited */
83578attr.valueRank = -2;
83579attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83580attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CumulatedSessionCount");
83581retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83582requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2153LU),
83583parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
83584referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83585browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CumulatedSessionCount"),
83586typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83587attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83588if (retVal != UA_STATUSCODE_GOOD) return retVal;
83589return retVal;
83590}
83591
83592static UA_StatusCode function_namespace0_generated_530_finish(UA_Server *server, UA_UInt16* ns) {
83593return UA_Server_addNode_finish(server,
83594nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2153LU)
83595);
83596}
83597
83598/* CurrentSessionCount - ns=0;i=2152 */
83599
83600static UA_StatusCode function_namespace0_generated_531_begin(UA_Server *server, UA_UInt16* ns) {
83601UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83602UA_VariableAttributes attr = UA_VariableAttributes_default;
83603attr.minimumSamplingInterval = 0.000000;
83604attr.userAccessLevel = 1;
83605attr.accessLevel = 1;
83606/* Value rank inherited */
83607attr.valueRank = -2;
83608attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83609attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentSessionCount");
83610retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83611requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2152LU),
83612parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
83613referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83614browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentSessionCount"),
83615typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83616attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83617if (retVal != UA_STATUSCODE_GOOD) return retVal;
83618return retVal;
83619}
83620
83621static UA_StatusCode function_namespace0_generated_531_finish(UA_Server *server, UA_UInt16* ns) {
83622return UA_Server_addNode_finish(server,
83623nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2152LU)
83624);
83625}
83626
83627/* ServerViewCount - ns=0;i=2151 */
83628
83629static UA_StatusCode function_namespace0_generated_532_begin(UA_Server *server, UA_UInt16* ns) {
83630UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83631UA_VariableAttributes attr = UA_VariableAttributes_default;
83632attr.minimumSamplingInterval = 0.000000;
83633attr.userAccessLevel = 1;
83634attr.accessLevel = 1;
83635/* Value rank inherited */
83636attr.valueRank = -2;
83637attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83638attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerViewCount");
83639retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83640requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2151LU),
83641parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
83642referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83643browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerViewCount"),
83644typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83645attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83646if (retVal != UA_STATUSCODE_GOOD) return retVal;
83647return retVal;
83648}
83649
83650static UA_StatusCode function_namespace0_generated_532_finish(UA_Server *server, UA_UInt16* ns) {
83651return UA_Server_addNode_finish(server,
83652nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2151LU)
83653);
83654}
83655
83656/* SamplingIntervalDiagnosticsType - ns=0;i=2165 */
83657
83658static UA_StatusCode function_namespace0_generated_533_begin(UA_Server *server, UA_UInt16* ns) {
83659UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83660UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
83661/* Value rank inherited */
83662attr.valueRank = -2;
83663attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 856LU);
83664attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SamplingIntervalDiagnosticsType");
83665retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
83666requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2165LU),
83667parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83668referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
83669browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SamplingIntervalDiagnosticsType"),
83670typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
83671attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
83672if (retVal != UA_STATUSCODE_GOOD) return retVal;
83673return retVal;
83674}
83675
83676static UA_StatusCode function_namespace0_generated_533_finish(UA_Server *server, UA_UInt16* ns) {
83677return UA_Server_addNode_finish(server,
83678nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2165LU)
83679);
83680}
83681
83682/* SamplingInterval - ns=0;i=2166 */
83683
83684static UA_StatusCode function_namespace0_generated_534_begin(UA_Server *server, UA_UInt16* ns) {
83685UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83686UA_VariableAttributes attr = UA_VariableAttributes_default;
83687attr.minimumSamplingInterval = 0.000000;
83688attr.userAccessLevel = 1;
83689attr.accessLevel = 1;
83690/* Value rank inherited */
83691attr.valueRank = -2;
83692attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU);
83693attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SamplingInterval");
83694retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83695requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2166LU),
83696parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2165LU),
83697referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83698browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SamplingInterval"),
83699typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83700attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83701if (retVal != UA_STATUSCODE_GOOD) return retVal;
83702return retVal;
83703}
83704
83705static UA_StatusCode function_namespace0_generated_534_finish(UA_Server *server, UA_UInt16* ns) {
83706return UA_Server_addNode_finish(server,
83707nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2166LU)
83708);
83709}
83710
83711/* DisabledMonitoredItemsSamplingCount - ns=0;i=11699 */
83712
83713static UA_StatusCode function_namespace0_generated_535_begin(UA_Server *server, UA_UInt16* ns) {
83714UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83715UA_VariableAttributes attr = UA_VariableAttributes_default;
83716attr.minimumSamplingInterval = 0.000000;
83717attr.userAccessLevel = 1;
83718attr.accessLevel = 1;
83719/* Value rank inherited */
83720attr.valueRank = -2;
83721attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83722attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DisabledMonitoredItemsSamplingCount");
83723retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83724requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11699LU),
83725parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2165LU),
83726referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83727browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DisabledMonitoredItemsSamplingCount"),
83728typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83729attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83730if (retVal != UA_STATUSCODE_GOOD) return retVal;
83731return retVal;
83732}
83733
83734static UA_StatusCode function_namespace0_generated_535_finish(UA_Server *server, UA_UInt16* ns) {
83735return UA_Server_addNode_finish(server,
83736nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11699LU)
83737);
83738}
83739
83740/* MaxSampledMonitoredItemsCount - ns=0;i=11698 */
83741
83742static UA_StatusCode function_namespace0_generated_536_begin(UA_Server *server, UA_UInt16* ns) {
83743UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83744UA_VariableAttributes attr = UA_VariableAttributes_default;
83745attr.minimumSamplingInterval = 0.000000;
83746attr.userAccessLevel = 1;
83747attr.accessLevel = 1;
83748/* Value rank inherited */
83749attr.valueRank = -2;
83750attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83751attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxSampledMonitoredItemsCount");
83752retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83753requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11698LU),
83754parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2165LU),
83755referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83756browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxSampledMonitoredItemsCount"),
83757typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83758attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83759if (retVal != UA_STATUSCODE_GOOD) return retVal;
83760return retVal;
83761}
83762
83763static UA_StatusCode function_namespace0_generated_536_finish(UA_Server *server, UA_UInt16* ns) {
83764return UA_Server_addNode_finish(server,
83765nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11698LU)
83766);
83767}
83768
83769/* SampledMonitoredItemsCount - ns=0;i=11697 */
83770
83771static UA_StatusCode function_namespace0_generated_537_begin(UA_Server *server, UA_UInt16* ns) {
83772UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83773UA_VariableAttributes attr = UA_VariableAttributes_default;
83774attr.minimumSamplingInterval = 0.000000;
83775attr.userAccessLevel = 1;
83776attr.accessLevel = 1;
83777/* Value rank inherited */
83778attr.valueRank = -2;
83779attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83780attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SampledMonitoredItemsCount");
83781retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83782requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11697LU),
83783parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2165LU),
83784referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83785browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SampledMonitoredItemsCount"),
83786typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83787attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83788if (retVal != UA_STATUSCODE_GOOD) return retVal;
83789return retVal;
83790}
83791
83792static UA_StatusCode function_namespace0_generated_537_finish(UA_Server *server, UA_UInt16* ns) {
83793return UA_Server_addNode_finish(server,
83794nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11697LU)
83795);
83796}
83797
83798/* SamplingIntervalDiagnosticsArrayType - ns=0;i=2164 */
83799
83800static UA_StatusCode function_namespace0_generated_538_begin(UA_Server *server, UA_UInt16* ns) {
83801UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83802UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
83803attr.valueRank = 1;
83804attr.arrayDimensionsSize = 1;
83805UA_UInt32 arrayDimensions[1];
83806arrayDimensions[0] = 0;
83807attr.arrayDimensions = &arrayDimensions[0];
83808attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 856LU);
83809attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SamplingIntervalDiagnosticsArrayType");
83810retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
83811requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2164LU),
83812parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83813referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
83814browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SamplingIntervalDiagnosticsArrayType"),
83815typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
83816attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
83817if (retVal != UA_STATUSCODE_GOOD) return retVal;
83818return retVal;
83819}
83820
83821static UA_StatusCode function_namespace0_generated_538_finish(UA_Server *server, UA_UInt16* ns) {
83822return UA_Server_addNode_finish(server,
83823nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2164LU)
83824);
83825}
83826
83827/* SamplingIntervalDiagnostics - ns=0;i=12779 */
83828
83829static UA_StatusCode function_namespace0_generated_539_begin(UA_Server *server, UA_UInt16* ns) {
83830UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83831UA_VariableAttributes attr = UA_VariableAttributes_default;
83832attr.minimumSamplingInterval = 0.000000;
83833attr.userAccessLevel = 1;
83834attr.accessLevel = 1;
83835/* Value rank inherited */
83836attr.valueRank = -2;
83837attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 856LU);
83838attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SamplingIntervalDiagnostics");
83839retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83840requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12779LU),
83841parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2164LU),
83842referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83843browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SamplingIntervalDiagnostics"),
83844typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2165LU),
83845attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83846if (retVal != UA_STATUSCODE_GOOD) return retVal;
83847return retVal;
83848}
83849
83850static UA_StatusCode function_namespace0_generated_539_finish(UA_Server *server, UA_UInt16* ns) {
83851return UA_Server_addNode_finish(server,
83852nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12779LU)
83853);
83854}
83855
83856/* DisabledMonitoredItemsSamplingCount - ns=0;i=12783 */
83857
83858static UA_StatusCode function_namespace0_generated_540_begin(UA_Server *server, UA_UInt16* ns) {
83859UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83860UA_VariableAttributes attr = UA_VariableAttributes_default;
83861attr.minimumSamplingInterval = 0.000000;
83862attr.userAccessLevel = 1;
83863attr.accessLevel = 1;
83864/* Value rank inherited */
83865attr.valueRank = -2;
83866attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83867attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DisabledMonitoredItemsSamplingCount");
83868retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83869requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12783LU),
83870parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12779LU),
83871referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83872browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DisabledMonitoredItemsSamplingCount"),
83873typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83874attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83875if (retVal != UA_STATUSCODE_GOOD) return retVal;
83876return retVal;
83877}
83878
83879static UA_StatusCode function_namespace0_generated_540_finish(UA_Server *server, UA_UInt16* ns) {
83880return UA_Server_addNode_finish(server,
83881nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12783LU)
83882);
83883}
83884
83885/* MaxSampledMonitoredItemsCount - ns=0;i=12782 */
83886
83887static UA_StatusCode function_namespace0_generated_541_begin(UA_Server *server, UA_UInt16* ns) {
83888UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83889UA_VariableAttributes attr = UA_VariableAttributes_default;
83890attr.minimumSamplingInterval = 0.000000;
83891attr.userAccessLevel = 1;
83892attr.accessLevel = 1;
83893/* Value rank inherited */
83894attr.valueRank = -2;
83895attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83896attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxSampledMonitoredItemsCount");
83897retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83898requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12782LU),
83899parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12779LU),
83900referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83901browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxSampledMonitoredItemsCount"),
83902typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83903attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83904if (retVal != UA_STATUSCODE_GOOD) return retVal;
83905return retVal;
83906}
83907
83908static UA_StatusCode function_namespace0_generated_541_finish(UA_Server *server, UA_UInt16* ns) {
83909return UA_Server_addNode_finish(server,
83910nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12782LU)
83911);
83912}
83913
83914/* SampledMonitoredItemsCount - ns=0;i=12781 */
83915
83916static UA_StatusCode function_namespace0_generated_542_begin(UA_Server *server, UA_UInt16* ns) {
83917UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83918UA_VariableAttributes attr = UA_VariableAttributes_default;
83919attr.minimumSamplingInterval = 0.000000;
83920attr.userAccessLevel = 1;
83921attr.accessLevel = 1;
83922/* Value rank inherited */
83923attr.valueRank = -2;
83924attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
83925attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SampledMonitoredItemsCount");
83926retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83927requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12781LU),
83928parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12779LU),
83929referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83930browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SampledMonitoredItemsCount"),
83931typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83932attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83933if (retVal != UA_STATUSCODE_GOOD) return retVal;
83934return retVal;
83935}
83936
83937static UA_StatusCode function_namespace0_generated_542_finish(UA_Server *server, UA_UInt16* ns) {
83938return UA_Server_addNode_finish(server,
83939nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12781LU)
83940);
83941}
83942
83943/* SamplingInterval - ns=0;i=12780 */
83944
83945static UA_StatusCode function_namespace0_generated_543_begin(UA_Server *server, UA_UInt16* ns) {
83946UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83947UA_VariableAttributes attr = UA_VariableAttributes_default;
83948attr.minimumSamplingInterval = 0.000000;
83949attr.userAccessLevel = 1;
83950attr.accessLevel = 1;
83951/* Value rank inherited */
83952attr.valueRank = -2;
83953attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU);
83954attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SamplingInterval");
83955retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
83956requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12780LU),
83957parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12779LU),
83958referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
83959browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SamplingInterval"),
83960typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83961attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
83962if (retVal != UA_STATUSCODE_GOOD) return retVal;
83963return retVal;
83964}
83965
83966static UA_StatusCode function_namespace0_generated_543_finish(UA_Server *server, UA_UInt16* ns) {
83967return UA_Server_addNode_finish(server,
83968nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12780LU)
83969);
83970}
83971
83972/* SessionDiagnosticsArrayType - ns=0;i=2196 */
83973
83974static UA_StatusCode function_namespace0_generated_544_begin(UA_Server *server, UA_UInt16* ns) {
83975UA_StatusCode retVal = UA_STATUSCODE_GOOD;
83976UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
83977attr.valueRank = 1;
83978attr.arrayDimensionsSize = 1;
83979UA_UInt32 arrayDimensions[1];
83980arrayDimensions[0] = 0;
83981attr.arrayDimensions = &arrayDimensions[0];
83982attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 865LU);
83983attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionDiagnosticsArrayType");
83984retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
83985requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2196LU),
83986parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
83987referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
83988browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionDiagnosticsArrayType"),
83989typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
83990attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
83991if (retVal != UA_STATUSCODE_GOOD) return retVal;
83992return retVal;
83993}
83994
83995static UA_StatusCode function_namespace0_generated_544_finish(UA_Server *server, UA_UInt16* ns) {
83996return UA_Server_addNode_finish(server,
83997nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2196LU)
83998);
83999}
84000
84001/* SessionDiagnostics - ns=0;i=12816 */
84002
84003static UA_StatusCode function_namespace0_generated_545_begin(UA_Server *server, UA_UInt16* ns) {
84004UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84005UA_VariableAttributes attr = UA_VariableAttributes_default;
84006attr.minimumSamplingInterval = 0.000000;
84007attr.userAccessLevel = 1;
84008attr.accessLevel = 1;
84009/* Value rank inherited */
84010attr.valueRank = -2;
84011attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 865LU);
84012attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionDiagnostics");
84013retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84014requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84015parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2196LU),
84016referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84017browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionDiagnostics"),
84018typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
84019attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84020if (retVal != UA_STATUSCODE_GOOD) return retVal;
84021return retVal;
84022}
84023
84024static UA_StatusCode function_namespace0_generated_545_finish(UA_Server *server, UA_UInt16* ns) {
84025return UA_Server_addNode_finish(server,
84026nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU)
84027);
84028}
84029
84030/* UnregisterNodesCount - ns=0;i=12859 */
84031
84032static UA_StatusCode function_namespace0_generated_546_begin(UA_Server *server, UA_UInt16* ns) {
84033UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84034UA_VariableAttributes attr = UA_VariableAttributes_default;
84035attr.minimumSamplingInterval = 0.000000;
84036attr.userAccessLevel = 1;
84037attr.accessLevel = 1;
84038/* Value rank inherited */
84039attr.valueRank = -2;
84040attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84041attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UnregisterNodesCount");
84042retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84043requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12859LU),
84044parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84045referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84046browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UnregisterNodesCount"),
84047typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84048attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84049if (retVal != UA_STATUSCODE_GOOD) return retVal;
84050return retVal;
84051}
84052
84053static UA_StatusCode function_namespace0_generated_546_finish(UA_Server *server, UA_UInt16* ns) {
84054return UA_Server_addNode_finish(server,
84055nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12859LU)
84056);
84057}
84058
84059/* RegisterNodesCount - ns=0;i=12858 */
84060
84061static UA_StatusCode function_namespace0_generated_547_begin(UA_Server *server, UA_UInt16* ns) {
84062UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84063UA_VariableAttributes attr = UA_VariableAttributes_default;
84064attr.minimumSamplingInterval = 0.000000;
84065attr.userAccessLevel = 1;
84066attr.accessLevel = 1;
84067/* Value rank inherited */
84068attr.valueRank = -2;
84069attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84070attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RegisterNodesCount");
84071retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84072requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12858LU),
84073parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84074referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84075browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RegisterNodesCount"),
84076typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84077attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84078if (retVal != UA_STATUSCODE_GOOD) return retVal;
84079return retVal;
84080}
84081
84082static UA_StatusCode function_namespace0_generated_547_finish(UA_Server *server, UA_UInt16* ns) {
84083return UA_Server_addNode_finish(server,
84084nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12858LU)
84085);
84086}
84087
84088/* QueryNextCount - ns=0;i=12857 */
84089
84090static UA_StatusCode function_namespace0_generated_548_begin(UA_Server *server, UA_UInt16* ns) {
84091UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84092UA_VariableAttributes attr = UA_VariableAttributes_default;
84093attr.minimumSamplingInterval = 0.000000;
84094attr.userAccessLevel = 1;
84095attr.accessLevel = 1;
84096/* Value rank inherited */
84097attr.valueRank = -2;
84098attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84099attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "QueryNextCount");
84100retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84101requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12857LU),
84102parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84103referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84104browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "QueryNextCount"),
84105typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84106attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84107if (retVal != UA_STATUSCODE_GOOD) return retVal;
84108return retVal;
84109}
84110
84111static UA_StatusCode function_namespace0_generated_548_finish(UA_Server *server, UA_UInt16* ns) {
84112return UA_Server_addNode_finish(server,
84113nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12857LU)
84114);
84115}
84116
84117/* QueryFirstCount - ns=0;i=12856 */
84118
84119static UA_StatusCode function_namespace0_generated_549_begin(UA_Server *server, UA_UInt16* ns) {
84120UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84121UA_VariableAttributes attr = UA_VariableAttributes_default;
84122attr.minimumSamplingInterval = 0.000000;
84123attr.userAccessLevel = 1;
84124attr.accessLevel = 1;
84125/* Value rank inherited */
84126attr.valueRank = -2;
84127attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84128attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "QueryFirstCount");
84129retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84130requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12856LU),
84131parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84132referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84133browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "QueryFirstCount"),
84134typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84135attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84136if (retVal != UA_STATUSCODE_GOOD) return retVal;
84137return retVal;
84138}
84139
84140static UA_StatusCode function_namespace0_generated_549_finish(UA_Server *server, UA_UInt16* ns) {
84141return UA_Server_addNode_finish(server,
84142nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12856LU)
84143);
84144}
84145
84146/* TranslateBrowsePathsToNodeIdsCount - ns=0;i=12855 */
84147
84148static UA_StatusCode function_namespace0_generated_550_begin(UA_Server *server, UA_UInt16* ns) {
84149UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84150UA_VariableAttributes attr = UA_VariableAttributes_default;
84151attr.minimumSamplingInterval = 0.000000;
84152attr.userAccessLevel = 1;
84153attr.accessLevel = 1;
84154/* Value rank inherited */
84155attr.valueRank = -2;
84156attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84157attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TranslateBrowsePathsToNodeIdsCount");
84158retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84159requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12855LU),
84160parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84161referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84162browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TranslateBrowsePathsToNodeIdsCount"),
84163typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84164attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84165if (retVal != UA_STATUSCODE_GOOD) return retVal;
84166return retVal;
84167}
84168
84169static UA_StatusCode function_namespace0_generated_550_finish(UA_Server *server, UA_UInt16* ns) {
84170return UA_Server_addNode_finish(server,
84171nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12855LU)
84172);
84173}
84174
84175/* BrowseNextCount - ns=0;i=12854 */
84176
84177static UA_StatusCode function_namespace0_generated_551_begin(UA_Server *server, UA_UInt16* ns) {
84178UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84179UA_VariableAttributes attr = UA_VariableAttributes_default;
84180attr.minimumSamplingInterval = 0.000000;
84181attr.userAccessLevel = 1;
84182attr.accessLevel = 1;
84183/* Value rank inherited */
84184attr.valueRank = -2;
84185attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84186attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BrowseNextCount");
84187retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84188requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12854LU),
84189parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84190referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84191browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BrowseNextCount"),
84192typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84193attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84194if (retVal != UA_STATUSCODE_GOOD) return retVal;
84195return retVal;
84196}
84197
84198static UA_StatusCode function_namespace0_generated_551_finish(UA_Server *server, UA_UInt16* ns) {
84199return UA_Server_addNode_finish(server,
84200nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12854LU)
84201);
84202}
84203
84204/* BrowseCount - ns=0;i=12853 */
84205
84206static UA_StatusCode function_namespace0_generated_552_begin(UA_Server *server, UA_UInt16* ns) {
84207UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84208UA_VariableAttributes attr = UA_VariableAttributes_default;
84209attr.minimumSamplingInterval = 0.000000;
84210attr.userAccessLevel = 1;
84211attr.accessLevel = 1;
84212/* Value rank inherited */
84213attr.valueRank = -2;
84214attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84215attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BrowseCount");
84216retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84217requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12853LU),
84218parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84219referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84220browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BrowseCount"),
84221typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84222attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84223if (retVal != UA_STATUSCODE_GOOD) return retVal;
84224return retVal;
84225}
84226
84227static UA_StatusCode function_namespace0_generated_552_finish(UA_Server *server, UA_UInt16* ns) {
84228return UA_Server_addNode_finish(server,
84229nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12853LU)
84230);
84231}
84232
84233/* DeleteReferencesCount - ns=0;i=12852 */
84234
84235static UA_StatusCode function_namespace0_generated_553_begin(UA_Server *server, UA_UInt16* ns) {
84236UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84237UA_VariableAttributes attr = UA_VariableAttributes_default;
84238attr.minimumSamplingInterval = 0.000000;
84239attr.userAccessLevel = 1;
84240attr.accessLevel = 1;
84241/* Value rank inherited */
84242attr.valueRank = -2;
84243attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84244attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteReferencesCount");
84245retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84246requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12852LU),
84247parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84248referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84249browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteReferencesCount"),
84250typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84251attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84252if (retVal != UA_STATUSCODE_GOOD) return retVal;
84253return retVal;
84254}
84255
84256static UA_StatusCode function_namespace0_generated_553_finish(UA_Server *server, UA_UInt16* ns) {
84257return UA_Server_addNode_finish(server,
84258nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12852LU)
84259);
84260}
84261
84262/* DeleteNodesCount - ns=0;i=12851 */
84263
84264static UA_StatusCode function_namespace0_generated_554_begin(UA_Server *server, UA_UInt16* ns) {
84265UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84266UA_VariableAttributes attr = UA_VariableAttributes_default;
84267attr.minimumSamplingInterval = 0.000000;
84268attr.userAccessLevel = 1;
84269attr.accessLevel = 1;
84270/* Value rank inherited */
84271attr.valueRank = -2;
84272attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84273attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteNodesCount");
84274retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84275requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12851LU),
84276parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84277referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84278browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteNodesCount"),
84279typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84280attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84281if (retVal != UA_STATUSCODE_GOOD) return retVal;
84282return retVal;
84283}
84284
84285static UA_StatusCode function_namespace0_generated_554_finish(UA_Server *server, UA_UInt16* ns) {
84286return UA_Server_addNode_finish(server,
84287nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12851LU)
84288);
84289}
84290
84291/* AddReferencesCount - ns=0;i=12850 */
84292
84293static UA_StatusCode function_namespace0_generated_555_begin(UA_Server *server, UA_UInt16* ns) {
84294UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84295UA_VariableAttributes attr = UA_VariableAttributes_default;
84296attr.minimumSamplingInterval = 0.000000;
84297attr.userAccessLevel = 1;
84298attr.accessLevel = 1;
84299/* Value rank inherited */
84300attr.valueRank = -2;
84301attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84302attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddReferencesCount");
84303retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84304requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12850LU),
84305parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84306referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84307browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddReferencesCount"),
84308typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84309attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84310if (retVal != UA_STATUSCODE_GOOD) return retVal;
84311return retVal;
84312}
84313
84314static UA_StatusCode function_namespace0_generated_555_finish(UA_Server *server, UA_UInt16* ns) {
84315return UA_Server_addNode_finish(server,
84316nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12850LU)
84317);
84318}
84319
84320/* AddNodesCount - ns=0;i=12849 */
84321
84322static UA_StatusCode function_namespace0_generated_556_begin(UA_Server *server, UA_UInt16* ns) {
84323UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84324UA_VariableAttributes attr = UA_VariableAttributes_default;
84325attr.minimumSamplingInterval = 0.000000;
84326attr.userAccessLevel = 1;
84327attr.accessLevel = 1;
84328/* Value rank inherited */
84329attr.valueRank = -2;
84330attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84331attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddNodesCount");
84332retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84333requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12849LU),
84334parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84335referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84336browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddNodesCount"),
84337typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84338attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84339if (retVal != UA_STATUSCODE_GOOD) return retVal;
84340return retVal;
84341}
84342
84343static UA_StatusCode function_namespace0_generated_556_finish(UA_Server *server, UA_UInt16* ns) {
84344return UA_Server_addNode_finish(server,
84345nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12849LU)
84346);
84347}
84348
84349/* DeleteSubscriptionsCount - ns=0;i=12848 */
84350
84351static UA_StatusCode function_namespace0_generated_557_begin(UA_Server *server, UA_UInt16* ns) {
84352UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84353UA_VariableAttributes attr = UA_VariableAttributes_default;
84354attr.minimumSamplingInterval = 0.000000;
84355attr.userAccessLevel = 1;
84356attr.accessLevel = 1;
84357/* Value rank inherited */
84358attr.valueRank = -2;
84359attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84360attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteSubscriptionsCount");
84361retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84362requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12848LU),
84363parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84364referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84365browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteSubscriptionsCount"),
84366typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84367attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84368if (retVal != UA_STATUSCODE_GOOD) return retVal;
84369return retVal;
84370}
84371
84372static UA_StatusCode function_namespace0_generated_557_finish(UA_Server *server, UA_UInt16* ns) {
84373return UA_Server_addNode_finish(server,
84374nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12848LU)
84375);
84376}
84377
84378/* TransferSubscriptionsCount - ns=0;i=12847 */
84379
84380static UA_StatusCode function_namespace0_generated_558_begin(UA_Server *server, UA_UInt16* ns) {
84381UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84382UA_VariableAttributes attr = UA_VariableAttributes_default;
84383attr.minimumSamplingInterval = 0.000000;
84384attr.userAccessLevel = 1;
84385attr.accessLevel = 1;
84386/* Value rank inherited */
84387attr.valueRank = -2;
84388attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84389attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransferSubscriptionsCount");
84390retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84391requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12847LU),
84392parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84393referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84394browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransferSubscriptionsCount"),
84395typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84396attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84397if (retVal != UA_STATUSCODE_GOOD) return retVal;
84398return retVal;
84399}
84400
84401static UA_StatusCode function_namespace0_generated_558_finish(UA_Server *server, UA_UInt16* ns) {
84402return UA_Server_addNode_finish(server,
84403nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12847LU)
84404);
84405}
84406
84407/* RepublishCount - ns=0;i=12846 */
84408
84409static UA_StatusCode function_namespace0_generated_559_begin(UA_Server *server, UA_UInt16* ns) {
84410UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84411UA_VariableAttributes attr = UA_VariableAttributes_default;
84412attr.minimumSamplingInterval = 0.000000;
84413attr.userAccessLevel = 1;
84414attr.accessLevel = 1;
84415/* Value rank inherited */
84416attr.valueRank = -2;
84417attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84418attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RepublishCount");
84419retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84420requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12846LU),
84421parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84422referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84423browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RepublishCount"),
84424typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84425attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84426if (retVal != UA_STATUSCODE_GOOD) return retVal;
84427return retVal;
84428}
84429
84430static UA_StatusCode function_namespace0_generated_559_finish(UA_Server *server, UA_UInt16* ns) {
84431return UA_Server_addNode_finish(server,
84432nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12846LU)
84433);
84434}
84435
84436/* PublishCount - ns=0;i=12845 */
84437
84438static UA_StatusCode function_namespace0_generated_560_begin(UA_Server *server, UA_UInt16* ns) {
84439UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84440UA_VariableAttributes attr = UA_VariableAttributes_default;
84441attr.minimumSamplingInterval = 0.000000;
84442attr.userAccessLevel = 1;
84443attr.accessLevel = 1;
84444/* Value rank inherited */
84445attr.valueRank = -2;
84446attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84447attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishCount");
84448retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84449requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12845LU),
84450parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84451referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84452browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishCount"),
84453typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84454attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84455if (retVal != UA_STATUSCODE_GOOD) return retVal;
84456return retVal;
84457}
84458
84459static UA_StatusCode function_namespace0_generated_560_finish(UA_Server *server, UA_UInt16* ns) {
84460return UA_Server_addNode_finish(server,
84461nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12845LU)
84462);
84463}
84464
84465/* SetPublishingModeCount - ns=0;i=12844 */
84466
84467static UA_StatusCode function_namespace0_generated_561_begin(UA_Server *server, UA_UInt16* ns) {
84468UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84469UA_VariableAttributes attr = UA_VariableAttributes_default;
84470attr.minimumSamplingInterval = 0.000000;
84471attr.userAccessLevel = 1;
84472attr.accessLevel = 1;
84473/* Value rank inherited */
84474attr.valueRank = -2;
84475attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84476attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SetPublishingModeCount");
84477retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84478requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12844LU),
84479parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84480referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84481browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SetPublishingModeCount"),
84482typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84483attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84484if (retVal != UA_STATUSCODE_GOOD) return retVal;
84485return retVal;
84486}
84487
84488static UA_StatusCode function_namespace0_generated_561_finish(UA_Server *server, UA_UInt16* ns) {
84489return UA_Server_addNode_finish(server,
84490nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12844LU)
84491);
84492}
84493
84494/* ModifySubscriptionCount - ns=0;i=12843 */
84495
84496static UA_StatusCode function_namespace0_generated_562_begin(UA_Server *server, UA_UInt16* ns) {
84497UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84498UA_VariableAttributes attr = UA_VariableAttributes_default;
84499attr.minimumSamplingInterval = 0.000000;
84500attr.userAccessLevel = 1;
84501attr.accessLevel = 1;
84502/* Value rank inherited */
84503attr.valueRank = -2;
84504attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84505attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ModifySubscriptionCount");
84506retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84507requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12843LU),
84508parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84509referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84510browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ModifySubscriptionCount"),
84511typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84512attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84513if (retVal != UA_STATUSCODE_GOOD) return retVal;
84514return retVal;
84515}
84516
84517static UA_StatusCode function_namespace0_generated_562_finish(UA_Server *server, UA_UInt16* ns) {
84518return UA_Server_addNode_finish(server,
84519nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12843LU)
84520);
84521}
84522
84523/* CreateSubscriptionCount - ns=0;i=12842 */
84524
84525static UA_StatusCode function_namespace0_generated_563_begin(UA_Server *server, UA_UInt16* ns) {
84526UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84527UA_VariableAttributes attr = UA_VariableAttributes_default;
84528attr.minimumSamplingInterval = 0.000000;
84529attr.userAccessLevel = 1;
84530attr.accessLevel = 1;
84531/* Value rank inherited */
84532attr.valueRank = -2;
84533attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84534attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CreateSubscriptionCount");
84535retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84536requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12842LU),
84537parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84538referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84539browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CreateSubscriptionCount"),
84540typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84541attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84542if (retVal != UA_STATUSCODE_GOOD) return retVal;
84543return retVal;
84544}
84545
84546static UA_StatusCode function_namespace0_generated_563_finish(UA_Server *server, UA_UInt16* ns) {
84547return UA_Server_addNode_finish(server,
84548nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12842LU)
84549);
84550}
84551
84552/* DeleteMonitoredItemsCount - ns=0;i=12841 */
84553
84554static UA_StatusCode function_namespace0_generated_564_begin(UA_Server *server, UA_UInt16* ns) {
84555UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84556UA_VariableAttributes attr = UA_VariableAttributes_default;
84557attr.minimumSamplingInterval = 0.000000;
84558attr.userAccessLevel = 1;
84559attr.accessLevel = 1;
84560/* Value rank inherited */
84561attr.valueRank = -2;
84562attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84563attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteMonitoredItemsCount");
84564retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84565requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12841LU),
84566parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84567referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84568browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteMonitoredItemsCount"),
84569typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84570attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84571if (retVal != UA_STATUSCODE_GOOD) return retVal;
84572return retVal;
84573}
84574
84575static UA_StatusCode function_namespace0_generated_564_finish(UA_Server *server, UA_UInt16* ns) {
84576return UA_Server_addNode_finish(server,
84577nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12841LU)
84578);
84579}
84580
84581/* SetTriggeringCount - ns=0;i=12840 */
84582
84583static UA_StatusCode function_namespace0_generated_565_begin(UA_Server *server, UA_UInt16* ns) {
84584UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84585UA_VariableAttributes attr = UA_VariableAttributes_default;
84586attr.minimumSamplingInterval = 0.000000;
84587attr.userAccessLevel = 1;
84588attr.accessLevel = 1;
84589/* Value rank inherited */
84590attr.valueRank = -2;
84591attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84592attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SetTriggeringCount");
84593retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84594requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12840LU),
84595parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84596referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84597browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SetTriggeringCount"),
84598typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84599attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84600if (retVal != UA_STATUSCODE_GOOD) return retVal;
84601return retVal;
84602}
84603
84604static UA_StatusCode function_namespace0_generated_565_finish(UA_Server *server, UA_UInt16* ns) {
84605return UA_Server_addNode_finish(server,
84606nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12840LU)
84607);
84608}
84609
84610/* SetMonitoringModeCount - ns=0;i=12839 */
84611
84612static UA_StatusCode function_namespace0_generated_566_begin(UA_Server *server, UA_UInt16* ns) {
84613UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84614UA_VariableAttributes attr = UA_VariableAttributes_default;
84615attr.minimumSamplingInterval = 0.000000;
84616attr.userAccessLevel = 1;
84617attr.accessLevel = 1;
84618/* Value rank inherited */
84619attr.valueRank = -2;
84620attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84621attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SetMonitoringModeCount");
84622retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84623requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12839LU),
84624parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84625referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84626browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SetMonitoringModeCount"),
84627typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84628attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84629if (retVal != UA_STATUSCODE_GOOD) return retVal;
84630return retVal;
84631}
84632
84633static UA_StatusCode function_namespace0_generated_566_finish(UA_Server *server, UA_UInt16* ns) {
84634return UA_Server_addNode_finish(server,
84635nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12839LU)
84636);
84637}
84638
84639/* ModifyMonitoredItemsCount - ns=0;i=12838 */
84640
84641static UA_StatusCode function_namespace0_generated_567_begin(UA_Server *server, UA_UInt16* ns) {
84642UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84643UA_VariableAttributes attr = UA_VariableAttributes_default;
84644attr.minimumSamplingInterval = 0.000000;
84645attr.userAccessLevel = 1;
84646attr.accessLevel = 1;
84647/* Value rank inherited */
84648attr.valueRank = -2;
84649attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84650attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ModifyMonitoredItemsCount");
84651retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84652requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12838LU),
84653parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84654referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84655browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ModifyMonitoredItemsCount"),
84656typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84657attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84658if (retVal != UA_STATUSCODE_GOOD) return retVal;
84659return retVal;
84660}
84661
84662static UA_StatusCode function_namespace0_generated_567_finish(UA_Server *server, UA_UInt16* ns) {
84663return UA_Server_addNode_finish(server,
84664nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12838LU)
84665);
84666}
84667
84668/* CreateMonitoredItemsCount - ns=0;i=12837 */
84669
84670static UA_StatusCode function_namespace0_generated_568_begin(UA_Server *server, UA_UInt16* ns) {
84671UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84672UA_VariableAttributes attr = UA_VariableAttributes_default;
84673attr.minimumSamplingInterval = 0.000000;
84674attr.userAccessLevel = 1;
84675attr.accessLevel = 1;
84676/* Value rank inherited */
84677attr.valueRank = -2;
84678attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84679attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CreateMonitoredItemsCount");
84680retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84681requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12837LU),
84682parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84683referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84684browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CreateMonitoredItemsCount"),
84685typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84686attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84687if (retVal != UA_STATUSCODE_GOOD) return retVal;
84688return retVal;
84689}
84690
84691static UA_StatusCode function_namespace0_generated_568_finish(UA_Server *server, UA_UInt16* ns) {
84692return UA_Server_addNode_finish(server,
84693nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12837LU)
84694);
84695}
84696
84697/* CallCount - ns=0;i=12836 */
84698
84699static UA_StatusCode function_namespace0_generated_569_begin(UA_Server *server, UA_UInt16* ns) {
84700UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84701UA_VariableAttributes attr = UA_VariableAttributes_default;
84702attr.minimumSamplingInterval = 0.000000;
84703attr.userAccessLevel = 1;
84704attr.accessLevel = 1;
84705/* Value rank inherited */
84706attr.valueRank = -2;
84707attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84708attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CallCount");
84709retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84710requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12836LU),
84711parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84712referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84713browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CallCount"),
84714typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84715attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84716if (retVal != UA_STATUSCODE_GOOD) return retVal;
84717return retVal;
84718}
84719
84720static UA_StatusCode function_namespace0_generated_569_finish(UA_Server *server, UA_UInt16* ns) {
84721return UA_Server_addNode_finish(server,
84722nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12836LU)
84723);
84724}
84725
84726/* HistoryUpdateCount - ns=0;i=12835 */
84727
84728static UA_StatusCode function_namespace0_generated_570_begin(UA_Server *server, UA_UInt16* ns) {
84729UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84730UA_VariableAttributes attr = UA_VariableAttributes_default;
84731attr.minimumSamplingInterval = 0.000000;
84732attr.userAccessLevel = 1;
84733attr.accessLevel = 1;
84734/* Value rank inherited */
84735attr.valueRank = -2;
84736attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84737attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HistoryUpdateCount");
84738retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84739requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12835LU),
84740parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84741referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84742browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HistoryUpdateCount"),
84743typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84744attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84745if (retVal != UA_STATUSCODE_GOOD) return retVal;
84746return retVal;
84747}
84748
84749static UA_StatusCode function_namespace0_generated_570_finish(UA_Server *server, UA_UInt16* ns) {
84750return UA_Server_addNode_finish(server,
84751nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12835LU)
84752);
84753}
84754
84755/* WriteCount - ns=0;i=12834 */
84756
84757static UA_StatusCode function_namespace0_generated_571_begin(UA_Server *server, UA_UInt16* ns) {
84758UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84759UA_VariableAttributes attr = UA_VariableAttributes_default;
84760attr.minimumSamplingInterval = 0.000000;
84761attr.userAccessLevel = 1;
84762attr.accessLevel = 1;
84763/* Value rank inherited */
84764attr.valueRank = -2;
84765attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84766attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "WriteCount");
84767retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84768requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12834LU),
84769parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84770referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84771browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "WriteCount"),
84772typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84773attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84774if (retVal != UA_STATUSCODE_GOOD) return retVal;
84775return retVal;
84776}
84777
84778static UA_StatusCode function_namespace0_generated_571_finish(UA_Server *server, UA_UInt16* ns) {
84779return UA_Server_addNode_finish(server,
84780nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12834LU)
84781);
84782}
84783
84784/* HistoryReadCount - ns=0;i=12833 */
84785
84786static UA_StatusCode function_namespace0_generated_572_begin(UA_Server *server, UA_UInt16* ns) {
84787UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84788UA_VariableAttributes attr = UA_VariableAttributes_default;
84789attr.minimumSamplingInterval = 0.000000;
84790attr.userAccessLevel = 1;
84791attr.accessLevel = 1;
84792/* Value rank inherited */
84793attr.valueRank = -2;
84794attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84795attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HistoryReadCount");
84796retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84797requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12833LU),
84798parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84799referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84800browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HistoryReadCount"),
84801typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84802attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84803if (retVal != UA_STATUSCODE_GOOD) return retVal;
84804return retVal;
84805}
84806
84807static UA_StatusCode function_namespace0_generated_572_finish(UA_Server *server, UA_UInt16* ns) {
84808return UA_Server_addNode_finish(server,
84809nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12833LU)
84810);
84811}
84812
84813/* ReadCount - ns=0;i=12832 */
84814
84815static UA_StatusCode function_namespace0_generated_573_begin(UA_Server *server, UA_UInt16* ns) {
84816UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84817UA_VariableAttributes attr = UA_VariableAttributes_default;
84818attr.minimumSamplingInterval = 0.000000;
84819attr.userAccessLevel = 1;
84820attr.accessLevel = 1;
84821/* Value rank inherited */
84822attr.valueRank = -2;
84823attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84824attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ReadCount");
84825retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84826requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12832LU),
84827parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84828referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84829browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ReadCount"),
84830typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84831attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84832if (retVal != UA_STATUSCODE_GOOD) return retVal;
84833return retVal;
84834}
84835
84836static UA_StatusCode function_namespace0_generated_573_finish(UA_Server *server, UA_UInt16* ns) {
84837return UA_Server_addNode_finish(server,
84838nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12832LU)
84839);
84840}
84841
84842/* UnauthorizedRequestCount - ns=0;i=12831 */
84843
84844static UA_StatusCode function_namespace0_generated_574_begin(UA_Server *server, UA_UInt16* ns) {
84845UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84846UA_VariableAttributes attr = UA_VariableAttributes_default;
84847attr.minimumSamplingInterval = 0.000000;
84848attr.userAccessLevel = 1;
84849attr.accessLevel = 1;
84850/* Value rank inherited */
84851attr.valueRank = -2;
84852attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
84853attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UnauthorizedRequestCount");
84854retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84855requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12831LU),
84856parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84857referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84858browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UnauthorizedRequestCount"),
84859typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84860attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84861if (retVal != UA_STATUSCODE_GOOD) return retVal;
84862return retVal;
84863}
84864
84865static UA_StatusCode function_namespace0_generated_574_finish(UA_Server *server, UA_UInt16* ns) {
84866return UA_Server_addNode_finish(server,
84867nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12831LU)
84868);
84869}
84870
84871/* TotalRequestCount - ns=0;i=12830 */
84872
84873static UA_StatusCode function_namespace0_generated_575_begin(UA_Server *server, UA_UInt16* ns) {
84874UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84875UA_VariableAttributes attr = UA_VariableAttributes_default;
84876attr.minimumSamplingInterval = 0.000000;
84877attr.userAccessLevel = 1;
84878attr.accessLevel = 1;
84879/* Value rank inherited */
84880attr.valueRank = -2;
84881attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
84882attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TotalRequestCount");
84883retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84884requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12830LU),
84885parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84886referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84887browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TotalRequestCount"),
84888typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84889attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84890if (retVal != UA_STATUSCODE_GOOD) return retVal;
84891return retVal;
84892}
84893
84894static UA_StatusCode function_namespace0_generated_575_finish(UA_Server *server, UA_UInt16* ns) {
84895return UA_Server_addNode_finish(server,
84896nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12830LU)
84897);
84898}
84899
84900/* CurrentPublishRequestsInQueue - ns=0;i=12829 */
84901
84902static UA_StatusCode function_namespace0_generated_576_begin(UA_Server *server, UA_UInt16* ns) {
84903UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84904UA_VariableAttributes attr = UA_VariableAttributes_default;
84905attr.minimumSamplingInterval = 0.000000;
84906attr.userAccessLevel = 1;
84907attr.accessLevel = 1;
84908/* Value rank inherited */
84909attr.valueRank = -2;
84910attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
84911attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentPublishRequestsInQueue");
84912retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84913requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12829LU),
84914parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84915referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84916browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentPublishRequestsInQueue"),
84917typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84918attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84919if (retVal != UA_STATUSCODE_GOOD) return retVal;
84920return retVal;
84921}
84922
84923static UA_StatusCode function_namespace0_generated_576_finish(UA_Server *server, UA_UInt16* ns) {
84924return UA_Server_addNode_finish(server,
84925nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12829LU)
84926);
84927}
84928
84929/* CurrentMonitoredItemsCount - ns=0;i=12828 */
84930
84931static UA_StatusCode function_namespace0_generated_577_begin(UA_Server *server, UA_UInt16* ns) {
84932UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84933UA_VariableAttributes attr = UA_VariableAttributes_default;
84934attr.minimumSamplingInterval = 0.000000;
84935attr.userAccessLevel = 1;
84936attr.accessLevel = 1;
84937/* Value rank inherited */
84938attr.valueRank = -2;
84939attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
84940attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentMonitoredItemsCount");
84941retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84942requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12828LU),
84943parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84944referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84945browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentMonitoredItemsCount"),
84946typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84947attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84948if (retVal != UA_STATUSCODE_GOOD) return retVal;
84949return retVal;
84950}
84951
84952static UA_StatusCode function_namespace0_generated_577_finish(UA_Server *server, UA_UInt16* ns) {
84953return UA_Server_addNode_finish(server,
84954nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12828LU)
84955);
84956}
84957
84958/* CurrentSubscriptionsCount - ns=0;i=12827 */
84959
84960static UA_StatusCode function_namespace0_generated_578_begin(UA_Server *server, UA_UInt16* ns) {
84961UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84962UA_VariableAttributes attr = UA_VariableAttributes_default;
84963attr.minimumSamplingInterval = 0.000000;
84964attr.userAccessLevel = 1;
84965attr.accessLevel = 1;
84966/* Value rank inherited */
84967attr.valueRank = -2;
84968attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
84969attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentSubscriptionsCount");
84970retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
84971requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12827LU),
84972parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
84973referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
84974browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentSubscriptionsCount"),
84975typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
84976attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
84977if (retVal != UA_STATUSCODE_GOOD) return retVal;
84978return retVal;
84979}
84980
84981static UA_StatusCode function_namespace0_generated_578_finish(UA_Server *server, UA_UInt16* ns) {
84982return UA_Server_addNode_finish(server,
84983nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12827LU)
84984);
84985}
84986
84987/* ClientLastContactTime - ns=0;i=12826 */
84988
84989static UA_StatusCode function_namespace0_generated_579_begin(UA_Server *server, UA_UInt16* ns) {
84990UA_StatusCode retVal = UA_STATUSCODE_GOOD;
84991UA_VariableAttributes attr = UA_VariableAttributes_default;
84992attr.minimumSamplingInterval = 0.000000;
84993attr.userAccessLevel = 1;
84994attr.accessLevel = 1;
84995/* Value rank inherited */
84996attr.valueRank = -2;
84997attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
84998attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientLastContactTime");
84999retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85000requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12826LU),
85001parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
85002referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85003browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientLastContactTime"),
85004typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85005attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85006if (retVal != UA_STATUSCODE_GOOD) return retVal;
85007return retVal;
85008}
85009
85010static UA_StatusCode function_namespace0_generated_579_finish(UA_Server *server, UA_UInt16* ns) {
85011return UA_Server_addNode_finish(server,
85012nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12826LU)
85013);
85014}
85015
85016/* ClientConnectionTime - ns=0;i=12825 */
85017
85018static UA_StatusCode function_namespace0_generated_580_begin(UA_Server *server, UA_UInt16* ns) {
85019UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85020UA_VariableAttributes attr = UA_VariableAttributes_default;
85021attr.minimumSamplingInterval = 0.000000;
85022attr.userAccessLevel = 1;
85023attr.accessLevel = 1;
85024/* Value rank inherited */
85025attr.valueRank = -2;
85026attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
85027attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientConnectionTime");
85028retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85029requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12825LU),
85030parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
85031referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85032browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientConnectionTime"),
85033typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85034attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85035if (retVal != UA_STATUSCODE_GOOD) return retVal;
85036return retVal;
85037}
85038
85039static UA_StatusCode function_namespace0_generated_580_finish(UA_Server *server, UA_UInt16* ns) {
85040return UA_Server_addNode_finish(server,
85041nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12825LU)
85042);
85043}
85044
85045/* MaxResponseMessageSize - ns=0;i=12824 */
85046
85047static UA_StatusCode function_namespace0_generated_581_begin(UA_Server *server, UA_UInt16* ns) {
85048UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85049UA_VariableAttributes attr = UA_VariableAttributes_default;
85050attr.minimumSamplingInterval = 0.000000;
85051attr.userAccessLevel = 1;
85052attr.accessLevel = 1;
85053/* Value rank inherited */
85054attr.valueRank = -2;
85055attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
85056attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxResponseMessageSize");
85057retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85058requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12824LU),
85059parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
85060referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85061browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxResponseMessageSize"),
85062typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85063attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85064if (retVal != UA_STATUSCODE_GOOD) return retVal;
85065return retVal;
85066}
85067
85068static UA_StatusCode function_namespace0_generated_581_finish(UA_Server *server, UA_UInt16* ns) {
85069return UA_Server_addNode_finish(server,
85070nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12824LU)
85071);
85072}
85073
85074/* ActualSessionTimeout - ns=0;i=12823 */
85075
85076static UA_StatusCode function_namespace0_generated_582_begin(UA_Server *server, UA_UInt16* ns) {
85077UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85078UA_VariableAttributes attr = UA_VariableAttributes_default;
85079attr.minimumSamplingInterval = 0.000000;
85080attr.userAccessLevel = 1;
85081attr.accessLevel = 1;
85082/* Value rank inherited */
85083attr.valueRank = -2;
85084attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU);
85085attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ActualSessionTimeout");
85086retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85087requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12823LU),
85088parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
85089referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85090browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ActualSessionTimeout"),
85091typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85092attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85093if (retVal != UA_STATUSCODE_GOOD) return retVal;
85094return retVal;
85095}
85096
85097static UA_StatusCode function_namespace0_generated_582_finish(UA_Server *server, UA_UInt16* ns) {
85098return UA_Server_addNode_finish(server,
85099nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12823LU)
85100);
85101}
85102
85103/* LocaleIds - ns=0;i=12822 */
85104
85105static UA_StatusCode function_namespace0_generated_583_begin(UA_Server *server, UA_UInt16* ns) {
85106UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85107UA_VariableAttributes attr = UA_VariableAttributes_default;
85108attr.minimumSamplingInterval = 0.000000;
85109attr.userAccessLevel = 1;
85110attr.accessLevel = 1;
85111attr.valueRank = 1;
85112attr.arrayDimensionsSize = 1;
85113UA_UInt32 arrayDimensions[1];
85114arrayDimensions[0] = 0;
85115attr.arrayDimensions = &arrayDimensions[0];
85116attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 295LU);
85117attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "LocaleIds");
85118retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85119requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12822LU),
85120parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
85121referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85122browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "LocaleIds"),
85123typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85124attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85125if (retVal != UA_STATUSCODE_GOOD) return retVal;
85126return retVal;
85127}
85128
85129static UA_StatusCode function_namespace0_generated_583_finish(UA_Server *server, UA_UInt16* ns) {
85130return UA_Server_addNode_finish(server,
85131nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12822LU)
85132);
85133}
85134
85135/* EndpointUrl - ns=0;i=12821 */
85136
85137static UA_StatusCode function_namespace0_generated_584_begin(UA_Server *server, UA_UInt16* ns) {
85138UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85139UA_VariableAttributes attr = UA_VariableAttributes_default;
85140attr.minimumSamplingInterval = 0.000000;
85141attr.userAccessLevel = 1;
85142attr.accessLevel = 1;
85143/* Value rank inherited */
85144attr.valueRank = -2;
85145attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85146attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EndpointUrl");
85147retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85148requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12821LU),
85149parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
85150referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85151browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EndpointUrl"),
85152typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85153attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85154if (retVal != UA_STATUSCODE_GOOD) return retVal;
85155return retVal;
85156}
85157
85158static UA_StatusCode function_namespace0_generated_584_finish(UA_Server *server, UA_UInt16* ns) {
85159return UA_Server_addNode_finish(server,
85160nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12821LU)
85161);
85162}
85163
85164/* ServerUri - ns=0;i=12820 */
85165
85166static UA_StatusCode function_namespace0_generated_585_begin(UA_Server *server, UA_UInt16* ns) {
85167UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85168UA_VariableAttributes attr = UA_VariableAttributes_default;
85169attr.minimumSamplingInterval = 0.000000;
85170attr.userAccessLevel = 1;
85171attr.accessLevel = 1;
85172/* Value rank inherited */
85173attr.valueRank = -2;
85174attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85175attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerUri");
85176retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85177requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12820LU),
85178parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
85179referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85180browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerUri"),
85181typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85182attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85183if (retVal != UA_STATUSCODE_GOOD) return retVal;
85184return retVal;
85185}
85186
85187static UA_StatusCode function_namespace0_generated_585_finish(UA_Server *server, UA_UInt16* ns) {
85188return UA_Server_addNode_finish(server,
85189nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12820LU)
85190);
85191}
85192
85193/* ClientDescription - ns=0;i=12819 */
85194
85195static UA_StatusCode function_namespace0_generated_586_begin(UA_Server *server, UA_UInt16* ns) {
85196UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85197UA_VariableAttributes attr = UA_VariableAttributes_default;
85198attr.minimumSamplingInterval = 0.000000;
85199attr.userAccessLevel = 1;
85200attr.accessLevel = 1;
85201/* Value rank inherited */
85202attr.valueRank = -2;
85203attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 308LU);
85204attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientDescription");
85205retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85206requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12819LU),
85207parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
85208referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85209browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientDescription"),
85210typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85211attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85212if (retVal != UA_STATUSCODE_GOOD) return retVal;
85213return retVal;
85214}
85215
85216static UA_StatusCode function_namespace0_generated_586_finish(UA_Server *server, UA_UInt16* ns) {
85217return UA_Server_addNode_finish(server,
85218nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12819LU)
85219);
85220}
85221
85222/* SessionName - ns=0;i=12818 */
85223
85224static UA_StatusCode function_namespace0_generated_587_begin(UA_Server *server, UA_UInt16* ns) {
85225UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85226UA_VariableAttributes attr = UA_VariableAttributes_default;
85227attr.minimumSamplingInterval = 0.000000;
85228attr.userAccessLevel = 1;
85229attr.accessLevel = 1;
85230/* Value rank inherited */
85231attr.valueRank = -2;
85232attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85233attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionName");
85234retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85235requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12818LU),
85236parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
85237referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85238browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionName"),
85239typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85240attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85241if (retVal != UA_STATUSCODE_GOOD) return retVal;
85242return retVal;
85243}
85244
85245static UA_StatusCode function_namespace0_generated_587_finish(UA_Server *server, UA_UInt16* ns) {
85246return UA_Server_addNode_finish(server,
85247nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12818LU)
85248);
85249}
85250
85251/* SessionId - ns=0;i=12817 */
85252
85253static UA_StatusCode function_namespace0_generated_588_begin(UA_Server *server, UA_UInt16* ns) {
85254UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85255UA_VariableAttributes attr = UA_VariableAttributes_default;
85256attr.minimumSamplingInterval = 0.000000;
85257attr.userAccessLevel = 1;
85258attr.accessLevel = 1;
85259/* Value rank inherited */
85260attr.valueRank = -2;
85261attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
85262attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionId");
85263retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85264requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12817LU),
85265parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU),
85266referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85267browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionId"),
85268typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85269attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85270if (retVal != UA_STATUSCODE_GOOD) return retVal;
85271return retVal;
85272}
85273
85274static UA_StatusCode function_namespace0_generated_588_finish(UA_Server *server, UA_UInt16* ns) {
85275return UA_Server_addNode_finish(server,
85276nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12817LU)
85277);
85278}
85279
85280/* SessionSecurityDiagnosticsArrayType - ns=0;i=2243 */
85281
85282static UA_StatusCode function_namespace0_generated_589_begin(UA_Server *server, UA_UInt16* ns) {
85283UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85284UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
85285attr.valueRank = 1;
85286attr.arrayDimensionsSize = 1;
85287UA_UInt32 arrayDimensions[1];
85288arrayDimensions[0] = 0;
85289attr.arrayDimensions = &arrayDimensions[0];
85290attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 868LU);
85291attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionSecurityDiagnosticsArrayType");
85292retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
85293requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2243LU),
85294parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85295referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
85296browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionSecurityDiagnosticsArrayType"),
85297typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
85298attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
85299if (retVal != UA_STATUSCODE_GOOD) return retVal;
85300return retVal;
85301}
85302
85303static UA_StatusCode function_namespace0_generated_589_finish(UA_Server *server, UA_UInt16* ns) {
85304return UA_Server_addNode_finish(server,
85305nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2243LU)
85306);
85307}
85308
85309/* SessionSecurityDiagnostics - ns=0;i=12860 */
85310
85311static UA_StatusCode function_namespace0_generated_590_begin(UA_Server *server, UA_UInt16* ns) {
85312UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85313UA_VariableAttributes attr = UA_VariableAttributes_default;
85314attr.minimumSamplingInterval = 0.000000;
85315attr.userAccessLevel = 1;
85316attr.accessLevel = 1;
85317/* Value rank inherited */
85318attr.valueRank = -2;
85319attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 868LU);
85320attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionSecurityDiagnostics");
85321retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85322requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12860LU),
85323parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2243LU),
85324referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85325browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionSecurityDiagnostics"),
85326typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU),
85327attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85328if (retVal != UA_STATUSCODE_GOOD) return retVal;
85329return retVal;
85330}
85331
85332static UA_StatusCode function_namespace0_generated_590_finish(UA_Server *server, UA_UInt16* ns) {
85333return UA_Server_addNode_finish(server,
85334nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12860LU)
85335);
85336}
85337
85338/* ClientCertificate - ns=0;i=12869 */
85339
85340static UA_StatusCode function_namespace0_generated_591_begin(UA_Server *server, UA_UInt16* ns) {
85341UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85342UA_VariableAttributes attr = UA_VariableAttributes_default;
85343attr.minimumSamplingInterval = 0.000000;
85344attr.userAccessLevel = 1;
85345attr.accessLevel = 1;
85346/* Value rank inherited */
85347attr.valueRank = -2;
85348attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15LU);
85349attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientCertificate");
85350retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85351requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12869LU),
85352parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12860LU),
85353referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85354browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientCertificate"),
85355typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85356attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85357if (retVal != UA_STATUSCODE_GOOD) return retVal;
85358return retVal;
85359}
85360
85361static UA_StatusCode function_namespace0_generated_591_finish(UA_Server *server, UA_UInt16* ns) {
85362return UA_Server_addNode_finish(server,
85363nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12869LU)
85364);
85365}
85366
85367/* SecurityPolicyUri - ns=0;i=12868 */
85368
85369static UA_StatusCode function_namespace0_generated_592_begin(UA_Server *server, UA_UInt16* ns) {
85370UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85371UA_VariableAttributes attr = UA_VariableAttributes_default;
85372attr.minimumSamplingInterval = 0.000000;
85373attr.userAccessLevel = 1;
85374attr.accessLevel = 1;
85375/* Value rank inherited */
85376attr.valueRank = -2;
85377attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85378attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityPolicyUri");
85379retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85380requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12868LU),
85381parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12860LU),
85382referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85383browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityPolicyUri"),
85384typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85385attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85386if (retVal != UA_STATUSCODE_GOOD) return retVal;
85387return retVal;
85388}
85389
85390static UA_StatusCode function_namespace0_generated_592_finish(UA_Server *server, UA_UInt16* ns) {
85391return UA_Server_addNode_finish(server,
85392nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12868LU)
85393);
85394}
85395
85396/* SecurityMode - ns=0;i=12867 */
85397
85398static UA_StatusCode function_namespace0_generated_593_begin(UA_Server *server, UA_UInt16* ns) {
85399UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85400UA_VariableAttributes attr = UA_VariableAttributes_default;
85401attr.minimumSamplingInterval = 0.000000;
85402attr.userAccessLevel = 1;
85403attr.accessLevel = 1;
85404/* Value rank inherited */
85405attr.valueRank = -2;
85406attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 302LU);
85407attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityMode");
85408retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85409requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12867LU),
85410parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12860LU),
85411referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85412browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityMode"),
85413typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85414attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85415if (retVal != UA_STATUSCODE_GOOD) return retVal;
85416return retVal;
85417}
85418
85419static UA_StatusCode function_namespace0_generated_593_finish(UA_Server *server, UA_UInt16* ns) {
85420return UA_Server_addNode_finish(server,
85421nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12867LU)
85422);
85423}
85424
85425/* TransportProtocol - ns=0;i=12866 */
85426
85427static UA_StatusCode function_namespace0_generated_594_begin(UA_Server *server, UA_UInt16* ns) {
85428UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85429UA_VariableAttributes attr = UA_VariableAttributes_default;
85430attr.minimumSamplingInterval = 0.000000;
85431attr.userAccessLevel = 1;
85432attr.accessLevel = 1;
85433/* Value rank inherited */
85434attr.valueRank = -2;
85435attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85436attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransportProtocol");
85437retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85438requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12866LU),
85439parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12860LU),
85440referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85441browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransportProtocol"),
85442typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85443attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85444if (retVal != UA_STATUSCODE_GOOD) return retVal;
85445return retVal;
85446}
85447
85448static UA_StatusCode function_namespace0_generated_594_finish(UA_Server *server, UA_UInt16* ns) {
85449return UA_Server_addNode_finish(server,
85450nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12866LU)
85451);
85452}
85453
85454/* Encoding - ns=0;i=12865 */
85455
85456static UA_StatusCode function_namespace0_generated_595_begin(UA_Server *server, UA_UInt16* ns) {
85457UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85458UA_VariableAttributes attr = UA_VariableAttributes_default;
85459attr.minimumSamplingInterval = 0.000000;
85460attr.userAccessLevel = 1;
85461attr.accessLevel = 1;
85462/* Value rank inherited */
85463attr.valueRank = -2;
85464attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85465attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Encoding");
85466retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85467requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12865LU),
85468parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12860LU),
85469referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85470browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Encoding"),
85471typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85472attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85473if (retVal != UA_STATUSCODE_GOOD) return retVal;
85474return retVal;
85475}
85476
85477static UA_StatusCode function_namespace0_generated_595_finish(UA_Server *server, UA_UInt16* ns) {
85478return UA_Server_addNode_finish(server,
85479nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12865LU)
85480);
85481}
85482
85483/* AuthenticationMechanism - ns=0;i=12864 */
85484
85485static UA_StatusCode function_namespace0_generated_596_begin(UA_Server *server, UA_UInt16* ns) {
85486UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85487UA_VariableAttributes attr = UA_VariableAttributes_default;
85488attr.minimumSamplingInterval = 0.000000;
85489attr.userAccessLevel = 1;
85490attr.accessLevel = 1;
85491/* Value rank inherited */
85492attr.valueRank = -2;
85493attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85494attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AuthenticationMechanism");
85495retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85496requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12864LU),
85497parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12860LU),
85498referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85499browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AuthenticationMechanism"),
85500typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85501attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85502if (retVal != UA_STATUSCODE_GOOD) return retVal;
85503return retVal;
85504}
85505
85506static UA_StatusCode function_namespace0_generated_596_finish(UA_Server *server, UA_UInt16* ns) {
85507return UA_Server_addNode_finish(server,
85508nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12864LU)
85509);
85510}
85511
85512/* ClientUserIdHistory - ns=0;i=12863 */
85513
85514static UA_StatusCode function_namespace0_generated_597_begin(UA_Server *server, UA_UInt16* ns) {
85515UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85516UA_VariableAttributes attr = UA_VariableAttributes_default;
85517attr.minimumSamplingInterval = 0.000000;
85518attr.userAccessLevel = 1;
85519attr.accessLevel = 1;
85520attr.valueRank = 1;
85521attr.arrayDimensionsSize = 1;
85522UA_UInt32 arrayDimensions[1];
85523arrayDimensions[0] = 0;
85524attr.arrayDimensions = &arrayDimensions[0];
85525attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85526attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientUserIdHistory");
85527retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85528requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12863LU),
85529parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12860LU),
85530referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85531browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientUserIdHistory"),
85532typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85533attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85534if (retVal != UA_STATUSCODE_GOOD) return retVal;
85535return retVal;
85536}
85537
85538static UA_StatusCode function_namespace0_generated_597_finish(UA_Server *server, UA_UInt16* ns) {
85539return UA_Server_addNode_finish(server,
85540nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12863LU)
85541);
85542}
85543
85544/* ClientUserIdOfSession - ns=0;i=12862 */
85545
85546static UA_StatusCode function_namespace0_generated_598_begin(UA_Server *server, UA_UInt16* ns) {
85547UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85548UA_VariableAttributes attr = UA_VariableAttributes_default;
85549attr.minimumSamplingInterval = 0.000000;
85550attr.userAccessLevel = 1;
85551attr.accessLevel = 1;
85552/* Value rank inherited */
85553attr.valueRank = -2;
85554attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85555attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientUserIdOfSession");
85556retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85557requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12862LU),
85558parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12860LU),
85559referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85560browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientUserIdOfSession"),
85561typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85562attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85563if (retVal != UA_STATUSCODE_GOOD) return retVal;
85564return retVal;
85565}
85566
85567static UA_StatusCode function_namespace0_generated_598_finish(UA_Server *server, UA_UInt16* ns) {
85568return UA_Server_addNode_finish(server,
85569nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12862LU)
85570);
85571}
85572
85573/* SessionId - ns=0;i=12861 */
85574
85575static UA_StatusCode function_namespace0_generated_599_begin(UA_Server *server, UA_UInt16* ns) {
85576UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85577UA_VariableAttributes attr = UA_VariableAttributes_default;
85578attr.minimumSamplingInterval = 0.000000;
85579attr.userAccessLevel = 1;
85580attr.accessLevel = 1;
85581/* Value rank inherited */
85582attr.valueRank = -2;
85583attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
85584attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionId");
85585retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85586requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12861LU),
85587parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12860LU),
85588referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85589browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionId"),
85590typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85591attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85592if (retVal != UA_STATUSCODE_GOOD) return retVal;
85593return retVal;
85594}
85595
85596static UA_StatusCode function_namespace0_generated_599_finish(UA_Server *server, UA_UInt16* ns) {
85597return UA_Server_addNode_finish(server,
85598nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12861LU)
85599);
85600}
85601
85602/* SessionsDiagnosticsSummaryType - ns=0;i=2026 */
85603
85604static UA_StatusCode function_namespace0_generated_600_begin(UA_Server *server, UA_UInt16* ns) {
85605UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85606UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
85607attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionsDiagnosticsSummaryType");
85608retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
85609requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2026LU),
85610parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
85611referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
85612browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionsDiagnosticsSummaryType"),
85613 typeDefinition: UA_NODEID_NULL,
85614attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
85615if (retVal != UA_STATUSCODE_GOOD) return retVal;
85616return retVal;
85617}
85618
85619static UA_StatusCode function_namespace0_generated_600_finish(UA_Server *server, UA_UInt16* ns) {
85620return UA_Server_addNode_finish(server,
85621nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2026LU)
85622);
85623}
85624
85625/* SessionSecurityDiagnosticsArray - ns=0;i=2028 */
85626
85627static UA_StatusCode function_namespace0_generated_601_begin(UA_Server *server, UA_UInt16* ns) {
85628UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85629UA_VariableAttributes attr = UA_VariableAttributes_default;
85630attr.minimumSamplingInterval = 0.000000;
85631attr.userAccessLevel = 1;
85632attr.accessLevel = 1;
85633attr.valueRank = 1;
85634attr.arrayDimensionsSize = 1;
85635UA_UInt32 arrayDimensions[1];
85636arrayDimensions[0] = 0;
85637attr.arrayDimensions = &arrayDimensions[0];
85638attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 868LU);
85639attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionSecurityDiagnosticsArray");
85640retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85641requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2028LU),
85642parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2026LU),
85643referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85644browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionSecurityDiagnosticsArray"),
85645typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2243LU),
85646attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85647if (retVal != UA_STATUSCODE_GOOD) return retVal;
85648return retVal;
85649}
85650
85651static UA_StatusCode function_namespace0_generated_601_finish(UA_Server *server, UA_UInt16* ns) {
85652return UA_Server_addNode_finish(server,
85653nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2028LU)
85654);
85655}
85656
85657/* SessionDiagnosticsArray - ns=0;i=2027 */
85658
85659static UA_StatusCode function_namespace0_generated_602_begin(UA_Server *server, UA_UInt16* ns) {
85660UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85661UA_VariableAttributes attr = UA_VariableAttributes_default;
85662attr.minimumSamplingInterval = 0.000000;
85663attr.userAccessLevel = 1;
85664attr.accessLevel = 1;
85665attr.valueRank = 1;
85666attr.arrayDimensionsSize = 1;
85667UA_UInt32 arrayDimensions[1];
85668arrayDimensions[0] = 0;
85669attr.arrayDimensions = &arrayDimensions[0];
85670attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 865LU);
85671attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionDiagnosticsArray");
85672retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85673requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2027LU),
85674parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2026LU),
85675referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85676browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionDiagnosticsArray"),
85677typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2196LU),
85678attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85679if (retVal != UA_STATUSCODE_GOOD) return retVal;
85680return retVal;
85681}
85682
85683static UA_StatusCode function_namespace0_generated_602_finish(UA_Server *server, UA_UInt16* ns) {
85684return UA_Server_addNode_finish(server,
85685nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2027LU)
85686);
85687}
85688
85689/* <ClientName> - ns=0;i=12097 */
85690
85691static UA_StatusCode function_namespace0_generated_603_begin(UA_Server *server, UA_UInt16* ns) {
85692UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85693UA_ObjectAttributes attr = UA_ObjectAttributes_default;
85694attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "<ClientName>");
85695retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
85696requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12097LU),
85697parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2026LU),
85698referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85699browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "<ClientName>"),
85700typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2029LU),
85701attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
85702if (retVal != UA_STATUSCODE_GOOD) return retVal;
85703return retVal;
85704}
85705
85706static UA_StatusCode function_namespace0_generated_603_finish(UA_Server *server, UA_UInt16* ns) {
85707return UA_Server_addNode_finish(server,
85708nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12097LU)
85709);
85710}
85711
85712/* SubscriptionDiagnosticsArray - ns=0;i=12152 */
85713
85714static UA_StatusCode function_namespace0_generated_604_begin(UA_Server *server, UA_UInt16* ns) {
85715UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85716UA_VariableAttributes attr = UA_VariableAttributes_default;
85717attr.minimumSamplingInterval = 0.000000;
85718attr.userAccessLevel = 1;
85719attr.accessLevel = 1;
85720attr.valueRank = 1;
85721attr.arrayDimensionsSize = 1;
85722UA_UInt32 arrayDimensions[1];
85723arrayDimensions[0] = 0;
85724attr.arrayDimensions = &arrayDimensions[0];
85725attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 874LU);
85726attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscriptionDiagnosticsArray");
85727retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85728requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12152LU),
85729parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12097LU),
85730referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85731browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscriptionDiagnosticsArray"),
85732typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2171LU),
85733attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85734if (retVal != UA_STATUSCODE_GOOD) return retVal;
85735return retVal;
85736}
85737
85738static UA_StatusCode function_namespace0_generated_604_finish(UA_Server *server, UA_UInt16* ns) {
85739return UA_Server_addNode_finish(server,
85740nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12152LU)
85741);
85742}
85743
85744/* SessionSecurityDiagnostics - ns=0;i=12142 */
85745
85746static UA_StatusCode function_namespace0_generated_605_begin(UA_Server *server, UA_UInt16* ns) {
85747UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85748UA_VariableAttributes attr = UA_VariableAttributes_default;
85749attr.minimumSamplingInterval = 0.000000;
85750attr.userAccessLevel = 1;
85751attr.accessLevel = 1;
85752/* Value rank inherited */
85753attr.valueRank = -2;
85754attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 868LU);
85755attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionSecurityDiagnostics");
85756retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85757requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12142LU),
85758parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12097LU),
85759referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85760browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionSecurityDiagnostics"),
85761typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2244LU),
85762attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85763if (retVal != UA_STATUSCODE_GOOD) return retVal;
85764return retVal;
85765}
85766
85767static UA_StatusCode function_namespace0_generated_605_finish(UA_Server *server, UA_UInt16* ns) {
85768return UA_Server_addNode_finish(server,
85769nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12142LU)
85770);
85771}
85772
85773/* ClientCertificate - ns=0;i=12151 */
85774
85775static UA_StatusCode function_namespace0_generated_606_begin(UA_Server *server, UA_UInt16* ns) {
85776UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85777UA_VariableAttributes attr = UA_VariableAttributes_default;
85778attr.minimumSamplingInterval = 0.000000;
85779attr.userAccessLevel = 1;
85780attr.accessLevel = 1;
85781/* Value rank inherited */
85782attr.valueRank = -2;
85783attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15LU);
85784attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientCertificate");
85785retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85786requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12151LU),
85787parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12142LU),
85788referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85789browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientCertificate"),
85790typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85791attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85792if (retVal != UA_STATUSCODE_GOOD) return retVal;
85793return retVal;
85794}
85795
85796static UA_StatusCode function_namespace0_generated_606_finish(UA_Server *server, UA_UInt16* ns) {
85797return UA_Server_addNode_finish(server,
85798nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12151LU)
85799);
85800}
85801
85802/* SecurityPolicyUri - ns=0;i=12150 */
85803
85804static UA_StatusCode function_namespace0_generated_607_begin(UA_Server *server, UA_UInt16* ns) {
85805UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85806UA_VariableAttributes attr = UA_VariableAttributes_default;
85807attr.minimumSamplingInterval = 0.000000;
85808attr.userAccessLevel = 1;
85809attr.accessLevel = 1;
85810/* Value rank inherited */
85811attr.valueRank = -2;
85812attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85813attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityPolicyUri");
85814retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85815requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12150LU),
85816parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12142LU),
85817referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85818browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityPolicyUri"),
85819typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85820attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85821if (retVal != UA_STATUSCODE_GOOD) return retVal;
85822return retVal;
85823}
85824
85825static UA_StatusCode function_namespace0_generated_607_finish(UA_Server *server, UA_UInt16* ns) {
85826return UA_Server_addNode_finish(server,
85827nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12150LU)
85828);
85829}
85830
85831/* SecurityMode - ns=0;i=12149 */
85832
85833static UA_StatusCode function_namespace0_generated_608_begin(UA_Server *server, UA_UInt16* ns) {
85834UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85835UA_VariableAttributes attr = UA_VariableAttributes_default;
85836attr.minimumSamplingInterval = 0.000000;
85837attr.userAccessLevel = 1;
85838attr.accessLevel = 1;
85839/* Value rank inherited */
85840attr.valueRank = -2;
85841attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 302LU);
85842attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityMode");
85843retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85844requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12149LU),
85845parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12142LU),
85846referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85847browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityMode"),
85848typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85849attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85850if (retVal != UA_STATUSCODE_GOOD) return retVal;
85851return retVal;
85852}
85853
85854static UA_StatusCode function_namespace0_generated_608_finish(UA_Server *server, UA_UInt16* ns) {
85855return UA_Server_addNode_finish(server,
85856nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12149LU)
85857);
85858}
85859
85860/* TransportProtocol - ns=0;i=12148 */
85861
85862static UA_StatusCode function_namespace0_generated_609_begin(UA_Server *server, UA_UInt16* ns) {
85863UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85864UA_VariableAttributes attr = UA_VariableAttributes_default;
85865attr.minimumSamplingInterval = 0.000000;
85866attr.userAccessLevel = 1;
85867attr.accessLevel = 1;
85868/* Value rank inherited */
85869attr.valueRank = -2;
85870attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85871attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransportProtocol");
85872retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85873requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12148LU),
85874parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12142LU),
85875referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85876browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransportProtocol"),
85877typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85878attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85879if (retVal != UA_STATUSCODE_GOOD) return retVal;
85880return retVal;
85881}
85882
85883static UA_StatusCode function_namespace0_generated_609_finish(UA_Server *server, UA_UInt16* ns) {
85884return UA_Server_addNode_finish(server,
85885nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12148LU)
85886);
85887}
85888
85889/* Encoding - ns=0;i=12147 */
85890
85891static UA_StatusCode function_namespace0_generated_610_begin(UA_Server *server, UA_UInt16* ns) {
85892UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85893UA_VariableAttributes attr = UA_VariableAttributes_default;
85894attr.minimumSamplingInterval = 0.000000;
85895attr.userAccessLevel = 1;
85896attr.accessLevel = 1;
85897/* Value rank inherited */
85898attr.valueRank = -2;
85899attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85900attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Encoding");
85901retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85902requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12147LU),
85903parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12142LU),
85904referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85905browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Encoding"),
85906typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85907attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85908if (retVal != UA_STATUSCODE_GOOD) return retVal;
85909return retVal;
85910}
85911
85912static UA_StatusCode function_namespace0_generated_610_finish(UA_Server *server, UA_UInt16* ns) {
85913return UA_Server_addNode_finish(server,
85914nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12147LU)
85915);
85916}
85917
85918/* AuthenticationMechanism - ns=0;i=12146 */
85919
85920static UA_StatusCode function_namespace0_generated_611_begin(UA_Server *server, UA_UInt16* ns) {
85921UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85922UA_VariableAttributes attr = UA_VariableAttributes_default;
85923attr.minimumSamplingInterval = 0.000000;
85924attr.userAccessLevel = 1;
85925attr.accessLevel = 1;
85926/* Value rank inherited */
85927attr.valueRank = -2;
85928attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85929attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AuthenticationMechanism");
85930retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85931requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12146LU),
85932parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12142LU),
85933referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85934browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AuthenticationMechanism"),
85935typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85936attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85937if (retVal != UA_STATUSCODE_GOOD) return retVal;
85938return retVal;
85939}
85940
85941static UA_StatusCode function_namespace0_generated_611_finish(UA_Server *server, UA_UInt16* ns) {
85942return UA_Server_addNode_finish(server,
85943nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12146LU)
85944);
85945}
85946
85947/* ClientUserIdHistory - ns=0;i=12145 */
85948
85949static UA_StatusCode function_namespace0_generated_612_begin(UA_Server *server, UA_UInt16* ns) {
85950UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85951UA_VariableAttributes attr = UA_VariableAttributes_default;
85952attr.minimumSamplingInterval = 0.000000;
85953attr.userAccessLevel = 1;
85954attr.accessLevel = 1;
85955attr.valueRank = 1;
85956attr.arrayDimensionsSize = 1;
85957UA_UInt32 arrayDimensions[1];
85958arrayDimensions[0] = 0;
85959attr.arrayDimensions = &arrayDimensions[0];
85960attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85961attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientUserIdHistory");
85962retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85963requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12145LU),
85964parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12142LU),
85965referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85966browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientUserIdHistory"),
85967typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85968attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85969if (retVal != UA_STATUSCODE_GOOD) return retVal;
85970return retVal;
85971}
85972
85973static UA_StatusCode function_namespace0_generated_612_finish(UA_Server *server, UA_UInt16* ns) {
85974return UA_Server_addNode_finish(server,
85975nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12145LU)
85976);
85977}
85978
85979/* ClientUserIdOfSession - ns=0;i=12144 */
85980
85981static UA_StatusCode function_namespace0_generated_613_begin(UA_Server *server, UA_UInt16* ns) {
85982UA_StatusCode retVal = UA_STATUSCODE_GOOD;
85983UA_VariableAttributes attr = UA_VariableAttributes_default;
85984attr.minimumSamplingInterval = 0.000000;
85985attr.userAccessLevel = 1;
85986attr.accessLevel = 1;
85987/* Value rank inherited */
85988attr.valueRank = -2;
85989attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
85990attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientUserIdOfSession");
85991retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
85992requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12144LU),
85993parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12142LU),
85994referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
85995browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientUserIdOfSession"),
85996typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
85997attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
85998if (retVal != UA_STATUSCODE_GOOD) return retVal;
85999return retVal;
86000}
86001
86002static UA_StatusCode function_namespace0_generated_613_finish(UA_Server *server, UA_UInt16* ns) {
86003return UA_Server_addNode_finish(server,
86004nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12144LU)
86005);
86006}
86007
86008/* SessionId - ns=0;i=12143 */
86009
86010static UA_StatusCode function_namespace0_generated_614_begin(UA_Server *server, UA_UInt16* ns) {
86011UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86012UA_VariableAttributes attr = UA_VariableAttributes_default;
86013attr.minimumSamplingInterval = 0.000000;
86014attr.userAccessLevel = 1;
86015attr.accessLevel = 1;
86016/* Value rank inherited */
86017attr.valueRank = -2;
86018attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
86019attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionId");
86020retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86021requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12143LU),
86022parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12142LU),
86023referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86024browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionId"),
86025typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86026attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86027if (retVal != UA_STATUSCODE_GOOD) return retVal;
86028return retVal;
86029}
86030
86031static UA_StatusCode function_namespace0_generated_614_finish(UA_Server *server, UA_UInt16* ns) {
86032return UA_Server_addNode_finish(server,
86033nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12143LU)
86034);
86035}
86036
86037/* SessionDiagnostics - ns=0;i=12098 */
86038
86039static UA_StatusCode function_namespace0_generated_615_begin(UA_Server *server, UA_UInt16* ns) {
86040UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86041UA_VariableAttributes attr = UA_VariableAttributes_default;
86042attr.minimumSamplingInterval = 0.000000;
86043attr.userAccessLevel = 1;
86044attr.accessLevel = 1;
86045/* Value rank inherited */
86046attr.valueRank = -2;
86047attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 865LU);
86048attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionDiagnostics");
86049retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86050requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86051parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12097LU),
86052referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86053browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionDiagnostics"),
86054typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2197LU),
86055attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86056if (retVal != UA_STATUSCODE_GOOD) return retVal;
86057return retVal;
86058}
86059
86060static UA_StatusCode function_namespace0_generated_615_finish(UA_Server *server, UA_UInt16* ns) {
86061return UA_Server_addNode_finish(server,
86062nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU)
86063);
86064}
86065
86066/* UnregisterNodesCount - ns=0;i=12141 */
86067
86068static UA_StatusCode function_namespace0_generated_616_begin(UA_Server *server, UA_UInt16* ns) {
86069UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86070UA_VariableAttributes attr = UA_VariableAttributes_default;
86071attr.minimumSamplingInterval = 0.000000;
86072attr.userAccessLevel = 1;
86073attr.accessLevel = 1;
86074/* Value rank inherited */
86075attr.valueRank = -2;
86076attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86077attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UnregisterNodesCount");
86078retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86079requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12141LU),
86080parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86081referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86082browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UnregisterNodesCount"),
86083typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86084attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86085if (retVal != UA_STATUSCODE_GOOD) return retVal;
86086return retVal;
86087}
86088
86089static UA_StatusCode function_namespace0_generated_616_finish(UA_Server *server, UA_UInt16* ns) {
86090return UA_Server_addNode_finish(server,
86091nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12141LU)
86092);
86093}
86094
86095/* RegisterNodesCount - ns=0;i=12140 */
86096
86097static UA_StatusCode function_namespace0_generated_617_begin(UA_Server *server, UA_UInt16* ns) {
86098UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86099UA_VariableAttributes attr = UA_VariableAttributes_default;
86100attr.minimumSamplingInterval = 0.000000;
86101attr.userAccessLevel = 1;
86102attr.accessLevel = 1;
86103/* Value rank inherited */
86104attr.valueRank = -2;
86105attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86106attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RegisterNodesCount");
86107retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86108requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12140LU),
86109parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86110referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86111browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RegisterNodesCount"),
86112typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86113attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86114if (retVal != UA_STATUSCODE_GOOD) return retVal;
86115return retVal;
86116}
86117
86118static UA_StatusCode function_namespace0_generated_617_finish(UA_Server *server, UA_UInt16* ns) {
86119return UA_Server_addNode_finish(server,
86120nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12140LU)
86121);
86122}
86123
86124/* QueryNextCount - ns=0;i=12139 */
86125
86126static UA_StatusCode function_namespace0_generated_618_begin(UA_Server *server, UA_UInt16* ns) {
86127UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86128UA_VariableAttributes attr = UA_VariableAttributes_default;
86129attr.minimumSamplingInterval = 0.000000;
86130attr.userAccessLevel = 1;
86131attr.accessLevel = 1;
86132/* Value rank inherited */
86133attr.valueRank = -2;
86134attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86135attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "QueryNextCount");
86136retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86137requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12139LU),
86138parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86139referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86140browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "QueryNextCount"),
86141typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86142attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86143if (retVal != UA_STATUSCODE_GOOD) return retVal;
86144return retVal;
86145}
86146
86147static UA_StatusCode function_namespace0_generated_618_finish(UA_Server *server, UA_UInt16* ns) {
86148return UA_Server_addNode_finish(server,
86149nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12139LU)
86150);
86151}
86152
86153/* QueryFirstCount - ns=0;i=12138 */
86154
86155static UA_StatusCode function_namespace0_generated_619_begin(UA_Server *server, UA_UInt16* ns) {
86156UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86157UA_VariableAttributes attr = UA_VariableAttributes_default;
86158attr.minimumSamplingInterval = 0.000000;
86159attr.userAccessLevel = 1;
86160attr.accessLevel = 1;
86161/* Value rank inherited */
86162attr.valueRank = -2;
86163attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86164attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "QueryFirstCount");
86165retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86166requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12138LU),
86167parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86168referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86169browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "QueryFirstCount"),
86170typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86171attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86172if (retVal != UA_STATUSCODE_GOOD) return retVal;
86173return retVal;
86174}
86175
86176static UA_StatusCode function_namespace0_generated_619_finish(UA_Server *server, UA_UInt16* ns) {
86177return UA_Server_addNode_finish(server,
86178nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12138LU)
86179);
86180}
86181
86182/* TranslateBrowsePathsToNodeIdsCount - ns=0;i=12137 */
86183
86184static UA_StatusCode function_namespace0_generated_620_begin(UA_Server *server, UA_UInt16* ns) {
86185UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86186UA_VariableAttributes attr = UA_VariableAttributes_default;
86187attr.minimumSamplingInterval = 0.000000;
86188attr.userAccessLevel = 1;
86189attr.accessLevel = 1;
86190/* Value rank inherited */
86191attr.valueRank = -2;
86192attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86193attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TranslateBrowsePathsToNodeIdsCount");
86194retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86195requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12137LU),
86196parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86197referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86198browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TranslateBrowsePathsToNodeIdsCount"),
86199typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86200attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86201if (retVal != UA_STATUSCODE_GOOD) return retVal;
86202return retVal;
86203}
86204
86205static UA_StatusCode function_namespace0_generated_620_finish(UA_Server *server, UA_UInt16* ns) {
86206return UA_Server_addNode_finish(server,
86207nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12137LU)
86208);
86209}
86210
86211/* BrowseNextCount - ns=0;i=12136 */
86212
86213static UA_StatusCode function_namespace0_generated_621_begin(UA_Server *server, UA_UInt16* ns) {
86214UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86215UA_VariableAttributes attr = UA_VariableAttributes_default;
86216attr.minimumSamplingInterval = 0.000000;
86217attr.userAccessLevel = 1;
86218attr.accessLevel = 1;
86219/* Value rank inherited */
86220attr.valueRank = -2;
86221attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86222attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BrowseNextCount");
86223retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86224requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12136LU),
86225parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86226referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86227browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BrowseNextCount"),
86228typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86229attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86230if (retVal != UA_STATUSCODE_GOOD) return retVal;
86231return retVal;
86232}
86233
86234static UA_StatusCode function_namespace0_generated_621_finish(UA_Server *server, UA_UInt16* ns) {
86235return UA_Server_addNode_finish(server,
86236nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12136LU)
86237);
86238}
86239
86240/* BrowseCount - ns=0;i=12135 */
86241
86242static UA_StatusCode function_namespace0_generated_622_begin(UA_Server *server, UA_UInt16* ns) {
86243UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86244UA_VariableAttributes attr = UA_VariableAttributes_default;
86245attr.minimumSamplingInterval = 0.000000;
86246attr.userAccessLevel = 1;
86247attr.accessLevel = 1;
86248/* Value rank inherited */
86249attr.valueRank = -2;
86250attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86251attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BrowseCount");
86252retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86253requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12135LU),
86254parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86255referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86256browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BrowseCount"),
86257typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86258attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86259if (retVal != UA_STATUSCODE_GOOD) return retVal;
86260return retVal;
86261}
86262
86263static UA_StatusCode function_namespace0_generated_622_finish(UA_Server *server, UA_UInt16* ns) {
86264return UA_Server_addNode_finish(server,
86265nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12135LU)
86266);
86267}
86268
86269/* DeleteReferencesCount - ns=0;i=12134 */
86270
86271static UA_StatusCode function_namespace0_generated_623_begin(UA_Server *server, UA_UInt16* ns) {
86272UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86273UA_VariableAttributes attr = UA_VariableAttributes_default;
86274attr.minimumSamplingInterval = 0.000000;
86275attr.userAccessLevel = 1;
86276attr.accessLevel = 1;
86277/* Value rank inherited */
86278attr.valueRank = -2;
86279attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86280attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteReferencesCount");
86281retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86282requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12134LU),
86283parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86284referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86285browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteReferencesCount"),
86286typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86287attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86288if (retVal != UA_STATUSCODE_GOOD) return retVal;
86289return retVal;
86290}
86291
86292static UA_StatusCode function_namespace0_generated_623_finish(UA_Server *server, UA_UInt16* ns) {
86293return UA_Server_addNode_finish(server,
86294nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12134LU)
86295);
86296}
86297
86298/* DeleteNodesCount - ns=0;i=12133 */
86299
86300static UA_StatusCode function_namespace0_generated_624_begin(UA_Server *server, UA_UInt16* ns) {
86301UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86302UA_VariableAttributes attr = UA_VariableAttributes_default;
86303attr.minimumSamplingInterval = 0.000000;
86304attr.userAccessLevel = 1;
86305attr.accessLevel = 1;
86306/* Value rank inherited */
86307attr.valueRank = -2;
86308attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86309attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteNodesCount");
86310retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86311requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12133LU),
86312parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86313referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86314browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteNodesCount"),
86315typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86316attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86317if (retVal != UA_STATUSCODE_GOOD) return retVal;
86318return retVal;
86319}
86320
86321static UA_StatusCode function_namespace0_generated_624_finish(UA_Server *server, UA_UInt16* ns) {
86322return UA_Server_addNode_finish(server,
86323nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12133LU)
86324);
86325}
86326
86327/* AddReferencesCount - ns=0;i=12132 */
86328
86329static UA_StatusCode function_namespace0_generated_625_begin(UA_Server *server, UA_UInt16* ns) {
86330UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86331UA_VariableAttributes attr = UA_VariableAttributes_default;
86332attr.minimumSamplingInterval = 0.000000;
86333attr.userAccessLevel = 1;
86334attr.accessLevel = 1;
86335/* Value rank inherited */
86336attr.valueRank = -2;
86337attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86338attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddReferencesCount");
86339retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86340requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12132LU),
86341parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86342referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86343browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddReferencesCount"),
86344typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86345attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86346if (retVal != UA_STATUSCODE_GOOD) return retVal;
86347return retVal;
86348}
86349
86350static UA_StatusCode function_namespace0_generated_625_finish(UA_Server *server, UA_UInt16* ns) {
86351return UA_Server_addNode_finish(server,
86352nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12132LU)
86353);
86354}
86355
86356/* AddNodesCount - ns=0;i=12131 */
86357
86358static UA_StatusCode function_namespace0_generated_626_begin(UA_Server *server, UA_UInt16* ns) {
86359UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86360UA_VariableAttributes attr = UA_VariableAttributes_default;
86361attr.minimumSamplingInterval = 0.000000;
86362attr.userAccessLevel = 1;
86363attr.accessLevel = 1;
86364/* Value rank inherited */
86365attr.valueRank = -2;
86366attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86367attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddNodesCount");
86368retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86369requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12131LU),
86370parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86371referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86372browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddNodesCount"),
86373typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86374attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86375if (retVal != UA_STATUSCODE_GOOD) return retVal;
86376return retVal;
86377}
86378
86379static UA_StatusCode function_namespace0_generated_626_finish(UA_Server *server, UA_UInt16* ns) {
86380return UA_Server_addNode_finish(server,
86381nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12131LU)
86382);
86383}
86384
86385/* DeleteSubscriptionsCount - ns=0;i=12130 */
86386
86387static UA_StatusCode function_namespace0_generated_627_begin(UA_Server *server, UA_UInt16* ns) {
86388UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86389UA_VariableAttributes attr = UA_VariableAttributes_default;
86390attr.minimumSamplingInterval = 0.000000;
86391attr.userAccessLevel = 1;
86392attr.accessLevel = 1;
86393/* Value rank inherited */
86394attr.valueRank = -2;
86395attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86396attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteSubscriptionsCount");
86397retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86398requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12130LU),
86399parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86400referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86401browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteSubscriptionsCount"),
86402typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86403attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86404if (retVal != UA_STATUSCODE_GOOD) return retVal;
86405return retVal;
86406}
86407
86408static UA_StatusCode function_namespace0_generated_627_finish(UA_Server *server, UA_UInt16* ns) {
86409return UA_Server_addNode_finish(server,
86410nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12130LU)
86411);
86412}
86413
86414/* TransferSubscriptionsCount - ns=0;i=12129 */
86415
86416static UA_StatusCode function_namespace0_generated_628_begin(UA_Server *server, UA_UInt16* ns) {
86417UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86418UA_VariableAttributes attr = UA_VariableAttributes_default;
86419attr.minimumSamplingInterval = 0.000000;
86420attr.userAccessLevel = 1;
86421attr.accessLevel = 1;
86422/* Value rank inherited */
86423attr.valueRank = -2;
86424attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86425attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TransferSubscriptionsCount");
86426retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86427requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12129LU),
86428parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86429referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86430browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TransferSubscriptionsCount"),
86431typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86432attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86433if (retVal != UA_STATUSCODE_GOOD) return retVal;
86434return retVal;
86435}
86436
86437static UA_StatusCode function_namespace0_generated_628_finish(UA_Server *server, UA_UInt16* ns) {
86438return UA_Server_addNode_finish(server,
86439nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12129LU)
86440);
86441}
86442
86443/* RepublishCount - ns=0;i=12128 */
86444
86445static UA_StatusCode function_namespace0_generated_629_begin(UA_Server *server, UA_UInt16* ns) {
86446UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86447UA_VariableAttributes attr = UA_VariableAttributes_default;
86448attr.minimumSamplingInterval = 0.000000;
86449attr.userAccessLevel = 1;
86450attr.accessLevel = 1;
86451/* Value rank inherited */
86452attr.valueRank = -2;
86453attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86454attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RepublishCount");
86455retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86456requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12128LU),
86457parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86458referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86459browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RepublishCount"),
86460typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86461attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86462if (retVal != UA_STATUSCODE_GOOD) return retVal;
86463return retVal;
86464}
86465
86466static UA_StatusCode function_namespace0_generated_629_finish(UA_Server *server, UA_UInt16* ns) {
86467return UA_Server_addNode_finish(server,
86468nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12128LU)
86469);
86470}
86471
86472/* PublishCount - ns=0;i=12127 */
86473
86474static UA_StatusCode function_namespace0_generated_630_begin(UA_Server *server, UA_UInt16* ns) {
86475UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86476UA_VariableAttributes attr = UA_VariableAttributes_default;
86477attr.minimumSamplingInterval = 0.000000;
86478attr.userAccessLevel = 1;
86479attr.accessLevel = 1;
86480/* Value rank inherited */
86481attr.valueRank = -2;
86482attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86483attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishCount");
86484retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86485requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12127LU),
86486parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86487referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86488browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishCount"),
86489typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86490attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86491if (retVal != UA_STATUSCODE_GOOD) return retVal;
86492return retVal;
86493}
86494
86495static UA_StatusCode function_namespace0_generated_630_finish(UA_Server *server, UA_UInt16* ns) {
86496return UA_Server_addNode_finish(server,
86497nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12127LU)
86498);
86499}
86500
86501/* SetPublishingModeCount - ns=0;i=12126 */
86502
86503static UA_StatusCode function_namespace0_generated_631_begin(UA_Server *server, UA_UInt16* ns) {
86504UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86505UA_VariableAttributes attr = UA_VariableAttributes_default;
86506attr.minimumSamplingInterval = 0.000000;
86507attr.userAccessLevel = 1;
86508attr.accessLevel = 1;
86509/* Value rank inherited */
86510attr.valueRank = -2;
86511attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86512attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SetPublishingModeCount");
86513retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86514requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12126LU),
86515parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86516referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86517browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SetPublishingModeCount"),
86518typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86519attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86520if (retVal != UA_STATUSCODE_GOOD) return retVal;
86521return retVal;
86522}
86523
86524static UA_StatusCode function_namespace0_generated_631_finish(UA_Server *server, UA_UInt16* ns) {
86525return UA_Server_addNode_finish(server,
86526nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12126LU)
86527);
86528}
86529
86530/* ModifySubscriptionCount - ns=0;i=12125 */
86531
86532static UA_StatusCode function_namespace0_generated_632_begin(UA_Server *server, UA_UInt16* ns) {
86533UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86534UA_VariableAttributes attr = UA_VariableAttributes_default;
86535attr.minimumSamplingInterval = 0.000000;
86536attr.userAccessLevel = 1;
86537attr.accessLevel = 1;
86538/* Value rank inherited */
86539attr.valueRank = -2;
86540attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86541attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ModifySubscriptionCount");
86542retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86543requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12125LU),
86544parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86545referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86546browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ModifySubscriptionCount"),
86547typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86548attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86549if (retVal != UA_STATUSCODE_GOOD) return retVal;
86550return retVal;
86551}
86552
86553static UA_StatusCode function_namespace0_generated_632_finish(UA_Server *server, UA_UInt16* ns) {
86554return UA_Server_addNode_finish(server,
86555nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12125LU)
86556);
86557}
86558
86559/* CreateSubscriptionCount - ns=0;i=12124 */
86560
86561static UA_StatusCode function_namespace0_generated_633_begin(UA_Server *server, UA_UInt16* ns) {
86562UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86563UA_VariableAttributes attr = UA_VariableAttributes_default;
86564attr.minimumSamplingInterval = 0.000000;
86565attr.userAccessLevel = 1;
86566attr.accessLevel = 1;
86567/* Value rank inherited */
86568attr.valueRank = -2;
86569attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86570attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CreateSubscriptionCount");
86571retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86572requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12124LU),
86573parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86574referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86575browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CreateSubscriptionCount"),
86576typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86577attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86578if (retVal != UA_STATUSCODE_GOOD) return retVal;
86579return retVal;
86580}
86581
86582static UA_StatusCode function_namespace0_generated_633_finish(UA_Server *server, UA_UInt16* ns) {
86583return UA_Server_addNode_finish(server,
86584nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12124LU)
86585);
86586}
86587
86588/* DeleteMonitoredItemsCount - ns=0;i=12123 */
86589
86590static UA_StatusCode function_namespace0_generated_634_begin(UA_Server *server, UA_UInt16* ns) {
86591UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86592UA_VariableAttributes attr = UA_VariableAttributes_default;
86593attr.minimumSamplingInterval = 0.000000;
86594attr.userAccessLevel = 1;
86595attr.accessLevel = 1;
86596/* Value rank inherited */
86597attr.valueRank = -2;
86598attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86599attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteMonitoredItemsCount");
86600retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86601requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12123LU),
86602parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86603referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86604browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteMonitoredItemsCount"),
86605typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86606attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86607if (retVal != UA_STATUSCODE_GOOD) return retVal;
86608return retVal;
86609}
86610
86611static UA_StatusCode function_namespace0_generated_634_finish(UA_Server *server, UA_UInt16* ns) {
86612return UA_Server_addNode_finish(server,
86613nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12123LU)
86614);
86615}
86616
86617/* SetTriggeringCount - ns=0;i=12122 */
86618
86619static UA_StatusCode function_namespace0_generated_635_begin(UA_Server *server, UA_UInt16* ns) {
86620UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86621UA_VariableAttributes attr = UA_VariableAttributes_default;
86622attr.minimumSamplingInterval = 0.000000;
86623attr.userAccessLevel = 1;
86624attr.accessLevel = 1;
86625/* Value rank inherited */
86626attr.valueRank = -2;
86627attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86628attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SetTriggeringCount");
86629retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86630requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12122LU),
86631parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86632referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86633browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SetTriggeringCount"),
86634typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86635attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86636if (retVal != UA_STATUSCODE_GOOD) return retVal;
86637return retVal;
86638}
86639
86640static UA_StatusCode function_namespace0_generated_635_finish(UA_Server *server, UA_UInt16* ns) {
86641return UA_Server_addNode_finish(server,
86642nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12122LU)
86643);
86644}
86645
86646/* SetMonitoringModeCount - ns=0;i=12121 */
86647
86648static UA_StatusCode function_namespace0_generated_636_begin(UA_Server *server, UA_UInt16* ns) {
86649UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86650UA_VariableAttributes attr = UA_VariableAttributes_default;
86651attr.minimumSamplingInterval = 0.000000;
86652attr.userAccessLevel = 1;
86653attr.accessLevel = 1;
86654/* Value rank inherited */
86655attr.valueRank = -2;
86656attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86657attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SetMonitoringModeCount");
86658retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86659requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12121LU),
86660parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86661referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86662browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SetMonitoringModeCount"),
86663typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86664attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86665if (retVal != UA_STATUSCODE_GOOD) return retVal;
86666return retVal;
86667}
86668
86669static UA_StatusCode function_namespace0_generated_636_finish(UA_Server *server, UA_UInt16* ns) {
86670return UA_Server_addNode_finish(server,
86671nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12121LU)
86672);
86673}
86674
86675/* ModifyMonitoredItemsCount - ns=0;i=12120 */
86676
86677static UA_StatusCode function_namespace0_generated_637_begin(UA_Server *server, UA_UInt16* ns) {
86678UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86679UA_VariableAttributes attr = UA_VariableAttributes_default;
86680attr.minimumSamplingInterval = 0.000000;
86681attr.userAccessLevel = 1;
86682attr.accessLevel = 1;
86683/* Value rank inherited */
86684attr.valueRank = -2;
86685attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86686attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ModifyMonitoredItemsCount");
86687retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86688requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12120LU),
86689parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86690referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86691browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ModifyMonitoredItemsCount"),
86692typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86693attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86694if (retVal != UA_STATUSCODE_GOOD) return retVal;
86695return retVal;
86696}
86697
86698static UA_StatusCode function_namespace0_generated_637_finish(UA_Server *server, UA_UInt16* ns) {
86699return UA_Server_addNode_finish(server,
86700nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12120LU)
86701);
86702}
86703
86704/* CreateMonitoredItemsCount - ns=0;i=12119 */
86705
86706static UA_StatusCode function_namespace0_generated_638_begin(UA_Server *server, UA_UInt16* ns) {
86707UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86708UA_VariableAttributes attr = UA_VariableAttributes_default;
86709attr.minimumSamplingInterval = 0.000000;
86710attr.userAccessLevel = 1;
86711attr.accessLevel = 1;
86712/* Value rank inherited */
86713attr.valueRank = -2;
86714attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86715attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CreateMonitoredItemsCount");
86716retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86717requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12119LU),
86718parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86719referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86720browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CreateMonitoredItemsCount"),
86721typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86722attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86723if (retVal != UA_STATUSCODE_GOOD) return retVal;
86724return retVal;
86725}
86726
86727static UA_StatusCode function_namespace0_generated_638_finish(UA_Server *server, UA_UInt16* ns) {
86728return UA_Server_addNode_finish(server,
86729nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12119LU)
86730);
86731}
86732
86733/* CallCount - ns=0;i=12118 */
86734
86735static UA_StatusCode function_namespace0_generated_639_begin(UA_Server *server, UA_UInt16* ns) {
86736UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86737UA_VariableAttributes attr = UA_VariableAttributes_default;
86738attr.minimumSamplingInterval = 0.000000;
86739attr.userAccessLevel = 1;
86740attr.accessLevel = 1;
86741/* Value rank inherited */
86742attr.valueRank = -2;
86743attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86744attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CallCount");
86745retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86746requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12118LU),
86747parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86748referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86749browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CallCount"),
86750typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86751attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86752if (retVal != UA_STATUSCODE_GOOD) return retVal;
86753return retVal;
86754}
86755
86756static UA_StatusCode function_namespace0_generated_639_finish(UA_Server *server, UA_UInt16* ns) {
86757return UA_Server_addNode_finish(server,
86758nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12118LU)
86759);
86760}
86761
86762/* HistoryUpdateCount - ns=0;i=12117 */
86763
86764static UA_StatusCode function_namespace0_generated_640_begin(UA_Server *server, UA_UInt16* ns) {
86765UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86766UA_VariableAttributes attr = UA_VariableAttributes_default;
86767attr.minimumSamplingInterval = 0.000000;
86768attr.userAccessLevel = 1;
86769attr.accessLevel = 1;
86770/* Value rank inherited */
86771attr.valueRank = -2;
86772attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86773attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HistoryUpdateCount");
86774retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86775requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12117LU),
86776parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86777referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86778browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HistoryUpdateCount"),
86779typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86780attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86781if (retVal != UA_STATUSCODE_GOOD) return retVal;
86782return retVal;
86783}
86784
86785static UA_StatusCode function_namespace0_generated_640_finish(UA_Server *server, UA_UInt16* ns) {
86786return UA_Server_addNode_finish(server,
86787nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12117LU)
86788);
86789}
86790
86791/* WriteCount - ns=0;i=12116 */
86792
86793static UA_StatusCode function_namespace0_generated_641_begin(UA_Server *server, UA_UInt16* ns) {
86794UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86795UA_VariableAttributes attr = UA_VariableAttributes_default;
86796attr.minimumSamplingInterval = 0.000000;
86797attr.userAccessLevel = 1;
86798attr.accessLevel = 1;
86799/* Value rank inherited */
86800attr.valueRank = -2;
86801attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86802attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "WriteCount");
86803retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86804requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12116LU),
86805parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86806referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86807browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "WriteCount"),
86808typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86809attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86810if (retVal != UA_STATUSCODE_GOOD) return retVal;
86811return retVal;
86812}
86813
86814static UA_StatusCode function_namespace0_generated_641_finish(UA_Server *server, UA_UInt16* ns) {
86815return UA_Server_addNode_finish(server,
86816nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12116LU)
86817);
86818}
86819
86820/* HistoryReadCount - ns=0;i=12115 */
86821
86822static UA_StatusCode function_namespace0_generated_642_begin(UA_Server *server, UA_UInt16* ns) {
86823UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86824UA_VariableAttributes attr = UA_VariableAttributes_default;
86825attr.minimumSamplingInterval = 0.000000;
86826attr.userAccessLevel = 1;
86827attr.accessLevel = 1;
86828/* Value rank inherited */
86829attr.valueRank = -2;
86830attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86831attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HistoryReadCount");
86832retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86833requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12115LU),
86834parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86835referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86836browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HistoryReadCount"),
86837typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86838attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86839if (retVal != UA_STATUSCODE_GOOD) return retVal;
86840return retVal;
86841}
86842
86843static UA_StatusCode function_namespace0_generated_642_finish(UA_Server *server, UA_UInt16* ns) {
86844return UA_Server_addNode_finish(server,
86845nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12115LU)
86846);
86847}
86848
86849/* ReadCount - ns=0;i=12114 */
86850
86851static UA_StatusCode function_namespace0_generated_643_begin(UA_Server *server, UA_UInt16* ns) {
86852UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86853UA_VariableAttributes attr = UA_VariableAttributes_default;
86854attr.minimumSamplingInterval = 0.000000;
86855attr.userAccessLevel = 1;
86856attr.accessLevel = 1;
86857/* Value rank inherited */
86858attr.valueRank = -2;
86859attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86860attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ReadCount");
86861retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86862requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12114LU),
86863parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86864referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86865browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ReadCount"),
86866typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86867attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86868if (retVal != UA_STATUSCODE_GOOD) return retVal;
86869return retVal;
86870}
86871
86872static UA_StatusCode function_namespace0_generated_643_finish(UA_Server *server, UA_UInt16* ns) {
86873return UA_Server_addNode_finish(server,
86874nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12114LU)
86875);
86876}
86877
86878/* UnauthorizedRequestCount - ns=0;i=12113 */
86879
86880static UA_StatusCode function_namespace0_generated_644_begin(UA_Server *server, UA_UInt16* ns) {
86881UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86882UA_VariableAttributes attr = UA_VariableAttributes_default;
86883attr.minimumSamplingInterval = 0.000000;
86884attr.userAccessLevel = 1;
86885attr.accessLevel = 1;
86886/* Value rank inherited */
86887attr.valueRank = -2;
86888attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
86889attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UnauthorizedRequestCount");
86890retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86891requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12113LU),
86892parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86893referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86894browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UnauthorizedRequestCount"),
86895typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86896attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86897if (retVal != UA_STATUSCODE_GOOD) return retVal;
86898return retVal;
86899}
86900
86901static UA_StatusCode function_namespace0_generated_644_finish(UA_Server *server, UA_UInt16* ns) {
86902return UA_Server_addNode_finish(server,
86903nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12113LU)
86904);
86905}
86906
86907/* TotalRequestCount - ns=0;i=12112 */
86908
86909static UA_StatusCode function_namespace0_generated_645_begin(UA_Server *server, UA_UInt16* ns) {
86910UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86911UA_VariableAttributes attr = UA_VariableAttributes_default;
86912attr.minimumSamplingInterval = 0.000000;
86913attr.userAccessLevel = 1;
86914attr.accessLevel = 1;
86915/* Value rank inherited */
86916attr.valueRank = -2;
86917attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 871LU);
86918attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "TotalRequestCount");
86919retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86920requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12112LU),
86921parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86922referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86923browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "TotalRequestCount"),
86924typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86925attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86926if (retVal != UA_STATUSCODE_GOOD) return retVal;
86927return retVal;
86928}
86929
86930static UA_StatusCode function_namespace0_generated_645_finish(UA_Server *server, UA_UInt16* ns) {
86931return UA_Server_addNode_finish(server,
86932nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12112LU)
86933);
86934}
86935
86936/* CurrentPublishRequestsInQueue - ns=0;i=12111 */
86937
86938static UA_StatusCode function_namespace0_generated_646_begin(UA_Server *server, UA_UInt16* ns) {
86939UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86940UA_VariableAttributes attr = UA_VariableAttributes_default;
86941attr.minimumSamplingInterval = 0.000000;
86942attr.userAccessLevel = 1;
86943attr.accessLevel = 1;
86944/* Value rank inherited */
86945attr.valueRank = -2;
86946attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
86947attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentPublishRequestsInQueue");
86948retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86949requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12111LU),
86950parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86951referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86952browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentPublishRequestsInQueue"),
86953typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86954attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86955if (retVal != UA_STATUSCODE_GOOD) return retVal;
86956return retVal;
86957}
86958
86959static UA_StatusCode function_namespace0_generated_646_finish(UA_Server *server, UA_UInt16* ns) {
86960return UA_Server_addNode_finish(server,
86961nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12111LU)
86962);
86963}
86964
86965/* CurrentMonitoredItemsCount - ns=0;i=12110 */
86966
86967static UA_StatusCode function_namespace0_generated_647_begin(UA_Server *server, UA_UInt16* ns) {
86968UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86969UA_VariableAttributes attr = UA_VariableAttributes_default;
86970attr.minimumSamplingInterval = 0.000000;
86971attr.userAccessLevel = 1;
86972attr.accessLevel = 1;
86973/* Value rank inherited */
86974attr.valueRank = -2;
86975attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
86976attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentMonitoredItemsCount");
86977retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
86978requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12110LU),
86979parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
86980referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
86981browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentMonitoredItemsCount"),
86982typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
86983attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
86984if (retVal != UA_STATUSCODE_GOOD) return retVal;
86985return retVal;
86986}
86987
86988static UA_StatusCode function_namespace0_generated_647_finish(UA_Server *server, UA_UInt16* ns) {
86989return UA_Server_addNode_finish(server,
86990nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12110LU)
86991);
86992}
86993
86994/* CurrentSubscriptionsCount - ns=0;i=12109 */
86995
86996static UA_StatusCode function_namespace0_generated_648_begin(UA_Server *server, UA_UInt16* ns) {
86997UA_StatusCode retVal = UA_STATUSCODE_GOOD;
86998UA_VariableAttributes attr = UA_VariableAttributes_default;
86999attr.minimumSamplingInterval = 0.000000;
87000attr.userAccessLevel = 1;
87001attr.accessLevel = 1;
87002/* Value rank inherited */
87003attr.valueRank = -2;
87004attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
87005attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentSubscriptionsCount");
87006retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87007requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12109LU),
87008parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
87009referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87010browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentSubscriptionsCount"),
87011typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87012attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87013if (retVal != UA_STATUSCODE_GOOD) return retVal;
87014return retVal;
87015}
87016
87017static UA_StatusCode function_namespace0_generated_648_finish(UA_Server *server, UA_UInt16* ns) {
87018return UA_Server_addNode_finish(server,
87019nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12109LU)
87020);
87021}
87022
87023/* ClientLastContactTime - ns=0;i=12108 */
87024
87025static UA_StatusCode function_namespace0_generated_649_begin(UA_Server *server, UA_UInt16* ns) {
87026UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87027UA_VariableAttributes attr = UA_VariableAttributes_default;
87028attr.minimumSamplingInterval = 0.000000;
87029attr.userAccessLevel = 1;
87030attr.accessLevel = 1;
87031/* Value rank inherited */
87032attr.valueRank = -2;
87033attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
87034attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientLastContactTime");
87035retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87036requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12108LU),
87037parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
87038referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87039browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientLastContactTime"),
87040typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87041attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87042if (retVal != UA_STATUSCODE_GOOD) return retVal;
87043return retVal;
87044}
87045
87046static UA_StatusCode function_namespace0_generated_649_finish(UA_Server *server, UA_UInt16* ns) {
87047return UA_Server_addNode_finish(server,
87048nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12108LU)
87049);
87050}
87051
87052/* ClientConnectionTime - ns=0;i=12107 */
87053
87054static UA_StatusCode function_namespace0_generated_650_begin(UA_Server *server, UA_UInt16* ns) {
87055UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87056UA_VariableAttributes attr = UA_VariableAttributes_default;
87057attr.minimumSamplingInterval = 0.000000;
87058attr.userAccessLevel = 1;
87059attr.accessLevel = 1;
87060/* Value rank inherited */
87061attr.valueRank = -2;
87062attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
87063attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientConnectionTime");
87064retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87065requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12107LU),
87066parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
87067referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87068browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientConnectionTime"),
87069typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87070attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87071if (retVal != UA_STATUSCODE_GOOD) return retVal;
87072return retVal;
87073}
87074
87075static UA_StatusCode function_namespace0_generated_650_finish(UA_Server *server, UA_UInt16* ns) {
87076return UA_Server_addNode_finish(server,
87077nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12107LU)
87078);
87079}
87080
87081/* MaxResponseMessageSize - ns=0;i=12106 */
87082
87083static UA_StatusCode function_namespace0_generated_651_begin(UA_Server *server, UA_UInt16* ns) {
87084UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87085UA_VariableAttributes attr = UA_VariableAttributes_default;
87086attr.minimumSamplingInterval = 0.000000;
87087attr.userAccessLevel = 1;
87088attr.accessLevel = 1;
87089/* Value rank inherited */
87090attr.valueRank = -2;
87091attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
87092attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxResponseMessageSize");
87093retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87094requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12106LU),
87095parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
87096referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87097browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxResponseMessageSize"),
87098typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87099attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87100if (retVal != UA_STATUSCODE_GOOD) return retVal;
87101return retVal;
87102}
87103
87104static UA_StatusCode function_namespace0_generated_651_finish(UA_Server *server, UA_UInt16* ns) {
87105return UA_Server_addNode_finish(server,
87106nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12106LU)
87107);
87108}
87109
87110/* ActualSessionTimeout - ns=0;i=12105 */
87111
87112static UA_StatusCode function_namespace0_generated_652_begin(UA_Server *server, UA_UInt16* ns) {
87113UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87114UA_VariableAttributes attr = UA_VariableAttributes_default;
87115attr.minimumSamplingInterval = 0.000000;
87116attr.userAccessLevel = 1;
87117attr.accessLevel = 1;
87118/* Value rank inherited */
87119attr.valueRank = -2;
87120attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU);
87121attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ActualSessionTimeout");
87122retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87123requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12105LU),
87124parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
87125referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87126browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ActualSessionTimeout"),
87127typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87128attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87129if (retVal != UA_STATUSCODE_GOOD) return retVal;
87130return retVal;
87131}
87132
87133static UA_StatusCode function_namespace0_generated_652_finish(UA_Server *server, UA_UInt16* ns) {
87134return UA_Server_addNode_finish(server,
87135nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12105LU)
87136);
87137}
87138
87139/* LocaleIds - ns=0;i=12104 */
87140
87141static UA_StatusCode function_namespace0_generated_653_begin(UA_Server *server, UA_UInt16* ns) {
87142UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87143UA_VariableAttributes attr = UA_VariableAttributes_default;
87144attr.minimumSamplingInterval = 0.000000;
87145attr.userAccessLevel = 1;
87146attr.accessLevel = 1;
87147attr.valueRank = 1;
87148attr.arrayDimensionsSize = 1;
87149UA_UInt32 arrayDimensions[1];
87150arrayDimensions[0] = 0;
87151attr.arrayDimensions = &arrayDimensions[0];
87152attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 295LU);
87153attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "LocaleIds");
87154retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87155requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12104LU),
87156parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
87157referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87158browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "LocaleIds"),
87159typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87160attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87161if (retVal != UA_STATUSCODE_GOOD) return retVal;
87162return retVal;
87163}
87164
87165static UA_StatusCode function_namespace0_generated_653_finish(UA_Server *server, UA_UInt16* ns) {
87166return UA_Server_addNode_finish(server,
87167nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12104LU)
87168);
87169}
87170
87171/* EndpointUrl - ns=0;i=12103 */
87172
87173static UA_StatusCode function_namespace0_generated_654_begin(UA_Server *server, UA_UInt16* ns) {
87174UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87175UA_VariableAttributes attr = UA_VariableAttributes_default;
87176attr.minimumSamplingInterval = 0.000000;
87177attr.userAccessLevel = 1;
87178attr.accessLevel = 1;
87179/* Value rank inherited */
87180attr.valueRank = -2;
87181attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
87182attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EndpointUrl");
87183retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87184requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12103LU),
87185parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
87186referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87187browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EndpointUrl"),
87188typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87189attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87190if (retVal != UA_STATUSCODE_GOOD) return retVal;
87191return retVal;
87192}
87193
87194static UA_StatusCode function_namespace0_generated_654_finish(UA_Server *server, UA_UInt16* ns) {
87195return UA_Server_addNode_finish(server,
87196nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12103LU)
87197);
87198}
87199
87200/* ServerUri - ns=0;i=12102 */
87201
87202static UA_StatusCode function_namespace0_generated_655_begin(UA_Server *server, UA_UInt16* ns) {
87203UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87204UA_VariableAttributes attr = UA_VariableAttributes_default;
87205attr.minimumSamplingInterval = 0.000000;
87206attr.userAccessLevel = 1;
87207attr.accessLevel = 1;
87208/* Value rank inherited */
87209attr.valueRank = -2;
87210attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
87211attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerUri");
87212retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87213requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12102LU),
87214parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
87215referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87216browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerUri"),
87217typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87218attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87219if (retVal != UA_STATUSCODE_GOOD) return retVal;
87220return retVal;
87221}
87222
87223static UA_StatusCode function_namespace0_generated_655_finish(UA_Server *server, UA_UInt16* ns) {
87224return UA_Server_addNode_finish(server,
87225nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12102LU)
87226);
87227}
87228
87229/* ClientDescription - ns=0;i=12101 */
87230
87231static UA_StatusCode function_namespace0_generated_656_begin(UA_Server *server, UA_UInt16* ns) {
87232UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87233UA_VariableAttributes attr = UA_VariableAttributes_default;
87234attr.minimumSamplingInterval = 0.000000;
87235attr.userAccessLevel = 1;
87236attr.accessLevel = 1;
87237/* Value rank inherited */
87238attr.valueRank = -2;
87239attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 308LU);
87240attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ClientDescription");
87241retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87242requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12101LU),
87243parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
87244referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87245browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ClientDescription"),
87246typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87247attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87248if (retVal != UA_STATUSCODE_GOOD) return retVal;
87249return retVal;
87250}
87251
87252static UA_StatusCode function_namespace0_generated_656_finish(UA_Server *server, UA_UInt16* ns) {
87253return UA_Server_addNode_finish(server,
87254nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12101LU)
87255);
87256}
87257
87258/* SessionName - ns=0;i=12100 */
87259
87260static UA_StatusCode function_namespace0_generated_657_begin(UA_Server *server, UA_UInt16* ns) {
87261UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87262UA_VariableAttributes attr = UA_VariableAttributes_default;
87263attr.minimumSamplingInterval = 0.000000;
87264attr.userAccessLevel = 1;
87265attr.accessLevel = 1;
87266/* Value rank inherited */
87267attr.valueRank = -2;
87268attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
87269attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionName");
87270retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87271requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12100LU),
87272parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
87273referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87274browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionName"),
87275typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87276attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87277if (retVal != UA_STATUSCODE_GOOD) return retVal;
87278return retVal;
87279}
87280
87281static UA_StatusCode function_namespace0_generated_657_finish(UA_Server *server, UA_UInt16* ns) {
87282return UA_Server_addNode_finish(server,
87283nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12100LU)
87284);
87285}
87286
87287/* SessionId - ns=0;i=12099 */
87288
87289static UA_StatusCode function_namespace0_generated_658_begin(UA_Server *server, UA_UInt16* ns) {
87290UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87291UA_VariableAttributes attr = UA_VariableAttributes_default;
87292attr.minimumSamplingInterval = 0.000000;
87293attr.userAccessLevel = 1;
87294attr.accessLevel = 1;
87295/* Value rank inherited */
87296attr.valueRank = -2;
87297attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
87298attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionId");
87299retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87300requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12099LU),
87301parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU),
87302referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87303browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionId"),
87304typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87305attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87306if (retVal != UA_STATUSCODE_GOOD) return retVal;
87307return retVal;
87308}
87309
87310static UA_StatusCode function_namespace0_generated_658_finish(UA_Server *server, UA_UInt16* ns) {
87311return UA_Server_addNode_finish(server,
87312nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12099LU)
87313);
87314}
87315
87316/* InterfaceTypes - ns=0;i=17708 */
87317
87318static UA_StatusCode function_namespace0_generated_659_begin(UA_Server *server, UA_UInt16* ns) {
87319UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87320UA_ObjectAttributes attr = UA_ObjectAttributes_default;
87321attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InterfaceTypes");
87322retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
87323requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17708LU),
87324parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 86LU),
87325referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 35LU),
87326browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InterfaceTypes"),
87327typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 61LU),
87328attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
87329if (retVal != UA_STATUSCODE_GOOD) return retVal;
87330return retVal;
87331}
87332
87333static UA_StatusCode function_namespace0_generated_659_finish(UA_Server *server, UA_UInt16* ns) {
87334return UA_Server_addNode_finish(server,
87335nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17708LU)
87336);
87337}
87338
87339/* BaseInterfaceType - ns=0;i=17602 */
87340
87341static UA_StatusCode function_namespace0_generated_660_begin(UA_Server *server, UA_UInt16* ns) {
87342UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87343UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
87344attr.isAbstract = true;
87345attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BaseInterfaceType");
87346retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
87347requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17602LU),
87348parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
87349referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
87350browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BaseInterfaceType"),
87351 typeDefinition: UA_NODEID_NULL,
87352attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
87353if (retVal != UA_STATUSCODE_GOOD) return retVal;
87354retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17602LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 35LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17708LU), false);
87355if (retVal != UA_STATUSCODE_GOOD) return retVal;
87356return retVal;
87357}
87358
87359static UA_StatusCode function_namespace0_generated_660_finish(UA_Server *server, UA_UInt16* ns) {
87360return UA_Server_addNode_finish(server,
87361nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17602LU)
87362);
87363}
87364
87365/* BuildInfoType - ns=0;i=3051 */
87366
87367static UA_StatusCode function_namespace0_generated_661_begin(UA_Server *server, UA_UInt16* ns) {
87368UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87369UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
87370/* Value rank inherited */
87371attr.valueRank = -2;
87372attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 338LU);
87373attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BuildInfoType");
87374retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
87375requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3051LU),
87376parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87377referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
87378browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BuildInfoType"),
87379typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
87380attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
87381if (retVal != UA_STATUSCODE_GOOD) return retVal;
87382return retVal;
87383}
87384
87385static UA_StatusCode function_namespace0_generated_661_finish(UA_Server *server, UA_UInt16* ns) {
87386return UA_Server_addNode_finish(server,
87387nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3051LU)
87388);
87389}
87390
87391/* ServerStatusType - ns=0;i=2138 */
87392
87393static UA_StatusCode function_namespace0_generated_662_begin(UA_Server *server, UA_UInt16* ns) {
87394UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87395UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
87396/* Value rank inherited */
87397attr.valueRank = -2;
87398attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 862LU);
87399attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerStatusType");
87400retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
87401requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2138LU),
87402parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87403referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
87404browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerStatusType"),
87405typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
87406attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
87407if (retVal != UA_STATUSCODE_GOOD) return retVal;
87408return retVal;
87409}
87410
87411static UA_StatusCode function_namespace0_generated_662_finish(UA_Server *server, UA_UInt16* ns) {
87412return UA_Server_addNode_finish(server,
87413nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2138LU)
87414);
87415}
87416
87417/* OperationLimitsType - ns=0;i=11564 */
87418
87419static UA_StatusCode function_namespace0_generated_663_begin(UA_Server *server, UA_UInt16* ns) {
87420UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87421UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
87422attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OperationLimitsType");
87423retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
87424requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11564LU),
87425parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 61LU),
87426referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
87427browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OperationLimitsType"),
87428 typeDefinition: UA_NODEID_NULL,
87429attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
87430if (retVal != UA_STATUSCODE_GOOD) return retVal;
87431return retVal;
87432}
87433
87434static UA_StatusCode function_namespace0_generated_663_finish(UA_Server *server, UA_UInt16* ns) {
87435return UA_Server_addNode_finish(server,
87436nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11564LU)
87437);
87438}
87439
87440/* MaxMonitoredItemsPerCall - ns=0;i=11574 */
87441
87442static UA_StatusCode function_namespace0_generated_664_begin(UA_Server *server, UA_UInt16* ns) {
87443UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87444UA_VariableAttributes attr = UA_VariableAttributes_default;
87445attr.minimumSamplingInterval = 0.000000;
87446attr.userAccessLevel = 1;
87447attr.accessLevel = 1;
87448/* Value rank inherited */
87449attr.valueRank = -2;
87450attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
87451attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxMonitoredItemsPerCall");
87452retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87453requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11574LU),
87454parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11564LU),
87455referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
87456browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxMonitoredItemsPerCall"),
87457typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
87458attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87459if (retVal != UA_STATUSCODE_GOOD) return retVal;
87460return retVal;
87461}
87462
87463static UA_StatusCode function_namespace0_generated_664_finish(UA_Server *server, UA_UInt16* ns) {
87464return UA_Server_addNode_finish(server,
87465nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11574LU)
87466);
87467}
87468
87469/* MaxNodesPerNodeManagement - ns=0;i=11573 */
87470
87471static UA_StatusCode function_namespace0_generated_665_begin(UA_Server *server, UA_UInt16* ns) {
87472UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87473UA_VariableAttributes attr = UA_VariableAttributes_default;
87474attr.minimumSamplingInterval = 0.000000;
87475attr.userAccessLevel = 1;
87476attr.accessLevel = 1;
87477/* Value rank inherited */
87478attr.valueRank = -2;
87479attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
87480attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerNodeManagement");
87481retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87482requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11573LU),
87483parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11564LU),
87484referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
87485browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerNodeManagement"),
87486typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
87487attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87488if (retVal != UA_STATUSCODE_GOOD) return retVal;
87489return retVal;
87490}
87491
87492static UA_StatusCode function_namespace0_generated_665_finish(UA_Server *server, UA_UInt16* ns) {
87493return UA_Server_addNode_finish(server,
87494nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11573LU)
87495);
87496}
87497
87498/* MaxNodesPerTranslateBrowsePathsToNodeIds - ns=0;i=11572 */
87499
87500static UA_StatusCode function_namespace0_generated_666_begin(UA_Server *server, UA_UInt16* ns) {
87501UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87502UA_VariableAttributes attr = UA_VariableAttributes_default;
87503attr.minimumSamplingInterval = 0.000000;
87504attr.userAccessLevel = 1;
87505attr.accessLevel = 1;
87506/* Value rank inherited */
87507attr.valueRank = -2;
87508attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
87509attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerTranslateBrowsePathsToNodeIds");
87510retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87511requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11572LU),
87512parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11564LU),
87513referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
87514browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerTranslateBrowsePathsToNodeIds"),
87515typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
87516attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87517if (retVal != UA_STATUSCODE_GOOD) return retVal;
87518return retVal;
87519}
87520
87521static UA_StatusCode function_namespace0_generated_666_finish(UA_Server *server, UA_UInt16* ns) {
87522return UA_Server_addNode_finish(server,
87523nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11572LU)
87524);
87525}
87526
87527/* MaxNodesPerRegisterNodes - ns=0;i=11571 */
87528
87529static UA_StatusCode function_namespace0_generated_667_begin(UA_Server *server, UA_UInt16* ns) {
87530UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87531UA_VariableAttributes attr = UA_VariableAttributes_default;
87532attr.minimumSamplingInterval = 0.000000;
87533attr.userAccessLevel = 1;
87534attr.accessLevel = 1;
87535/* Value rank inherited */
87536attr.valueRank = -2;
87537attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
87538attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerRegisterNodes");
87539retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87540requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11571LU),
87541parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11564LU),
87542referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
87543browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerRegisterNodes"),
87544typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
87545attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87546if (retVal != UA_STATUSCODE_GOOD) return retVal;
87547return retVal;
87548}
87549
87550static UA_StatusCode function_namespace0_generated_667_finish(UA_Server *server, UA_UInt16* ns) {
87551return UA_Server_addNode_finish(server,
87552nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11571LU)
87553);
87554}
87555
87556/* MaxNodesPerBrowse - ns=0;i=11570 */
87557
87558static UA_StatusCode function_namespace0_generated_668_begin(UA_Server *server, UA_UInt16* ns) {
87559UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87560UA_VariableAttributes attr = UA_VariableAttributes_default;
87561attr.minimumSamplingInterval = 0.000000;
87562attr.userAccessLevel = 1;
87563attr.accessLevel = 1;
87564/* Value rank inherited */
87565attr.valueRank = -2;
87566attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
87567attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerBrowse");
87568retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87569requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11570LU),
87570parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11564LU),
87571referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
87572browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerBrowse"),
87573typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
87574attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87575if (retVal != UA_STATUSCODE_GOOD) return retVal;
87576return retVal;
87577}
87578
87579static UA_StatusCode function_namespace0_generated_668_finish(UA_Server *server, UA_UInt16* ns) {
87580return UA_Server_addNode_finish(server,
87581nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11570LU)
87582);
87583}
87584
87585/* MaxNodesPerMethodCall - ns=0;i=11569 */
87586
87587static UA_StatusCode function_namespace0_generated_669_begin(UA_Server *server, UA_UInt16* ns) {
87588UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87589UA_VariableAttributes attr = UA_VariableAttributes_default;
87590attr.minimumSamplingInterval = 0.000000;
87591attr.userAccessLevel = 1;
87592attr.accessLevel = 1;
87593/* Value rank inherited */
87594attr.valueRank = -2;
87595attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
87596attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerMethodCall");
87597retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87598requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11569LU),
87599parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11564LU),
87600referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
87601browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerMethodCall"),
87602typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
87603attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87604if (retVal != UA_STATUSCODE_GOOD) return retVal;
87605return retVal;
87606}
87607
87608static UA_StatusCode function_namespace0_generated_669_finish(UA_Server *server, UA_UInt16* ns) {
87609return UA_Server_addNode_finish(server,
87610nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11569LU)
87611);
87612}
87613
87614/* MaxNodesPerWrite - ns=0;i=11567 */
87615
87616static UA_StatusCode function_namespace0_generated_670_begin(UA_Server *server, UA_UInt16* ns) {
87617UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87618UA_VariableAttributes attr = UA_VariableAttributes_default;
87619attr.minimumSamplingInterval = 0.000000;
87620attr.userAccessLevel = 1;
87621attr.accessLevel = 1;
87622/* Value rank inherited */
87623attr.valueRank = -2;
87624attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
87625attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerWrite");
87626retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87627requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11567LU),
87628parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11564LU),
87629referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
87630browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerWrite"),
87631typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
87632attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87633if (retVal != UA_STATUSCODE_GOOD) return retVal;
87634return retVal;
87635}
87636
87637static UA_StatusCode function_namespace0_generated_670_finish(UA_Server *server, UA_UInt16* ns) {
87638return UA_Server_addNode_finish(server,
87639nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11567LU)
87640);
87641}
87642
87643/* MaxNodesPerRead - ns=0;i=11565 */
87644
87645static UA_StatusCode function_namespace0_generated_671_begin(UA_Server *server, UA_UInt16* ns) {
87646UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87647UA_VariableAttributes attr = UA_VariableAttributes_default;
87648attr.minimumSamplingInterval = 0.000000;
87649attr.userAccessLevel = 1;
87650attr.accessLevel = 1;
87651/* Value rank inherited */
87652attr.valueRank = -2;
87653attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
87654attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerRead");
87655retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87656requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11565LU),
87657parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11564LU),
87658referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
87659browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerRead"),
87660typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
87661attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87662if (retVal != UA_STATUSCODE_GOOD) return retVal;
87663return retVal;
87664}
87665
87666static UA_StatusCode function_namespace0_generated_671_finish(UA_Server *server, UA_UInt16* ns) {
87667return UA_Server_addNode_finish(server,
87668nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11565LU)
87669);
87670}
87671
87672/* ServerRedundancyType - ns=0;i=2034 */
87673
87674static UA_StatusCode function_namespace0_generated_672_begin(UA_Server *server, UA_UInt16* ns) {
87675UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87676UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
87677attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerRedundancyType");
87678retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
87679requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2034LU),
87680parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
87681referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
87682browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerRedundancyType"),
87683 typeDefinition: UA_NODEID_NULL,
87684attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
87685if (retVal != UA_STATUSCODE_GOOD) return retVal;
87686return retVal;
87687}
87688
87689static UA_StatusCode function_namespace0_generated_672_finish(UA_Server *server, UA_UInt16* ns) {
87690return UA_Server_addNode_finish(server,
87691nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2034LU)
87692);
87693}
87694
87695/* RedundancySupport - ns=0;i=2035 */
87696
87697static UA_StatusCode function_namespace0_generated_673_begin(UA_Server *server, UA_UInt16* ns) {
87698UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87699UA_VariableAttributes attr = UA_VariableAttributes_default;
87700attr.minimumSamplingInterval = 0.000000;
87701attr.userAccessLevel = 1;
87702attr.accessLevel = 1;
87703/* Value rank inherited */
87704attr.valueRank = -2;
87705attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 851LU);
87706attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RedundancySupport");
87707retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87708requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2035LU),
87709parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2034LU),
87710referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
87711browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RedundancySupport"),
87712typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
87713attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87714if (retVal != UA_STATUSCODE_GOOD) return retVal;
87715return retVal;
87716}
87717
87718static UA_StatusCode function_namespace0_generated_673_finish(UA_Server *server, UA_UInt16* ns) {
87719return UA_Server_addNode_finish(server,
87720nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2035LU)
87721);
87722}
87723
87724/* VendorServerInfoType - ns=0;i=2033 */
87725
87726static UA_StatusCode function_namespace0_generated_674_begin(UA_Server *server, UA_UInt16* ns) {
87727UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87728UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
87729attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "VendorServerInfoType");
87730retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
87731requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2033LU),
87732parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
87733referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
87734browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "VendorServerInfoType"),
87735 typeDefinition: UA_NODEID_NULL,
87736attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
87737if (retVal != UA_STATUSCODE_GOOD) return retVal;
87738return retVal;
87739}
87740
87741static UA_StatusCode function_namespace0_generated_674_finish(UA_Server *server, UA_UInt16* ns) {
87742return UA_Server_addNode_finish(server,
87743nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2033LU)
87744);
87745}
87746
87747/* ServerDiagnosticsType - ns=0;i=2020 */
87748
87749static UA_StatusCode function_namespace0_generated_675_begin(UA_Server *server, UA_UInt16* ns) {
87750UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87751UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
87752attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerDiagnosticsType");
87753retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
87754requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2020LU),
87755parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
87756referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
87757browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerDiagnosticsType"),
87758 typeDefinition: UA_NODEID_NULL,
87759attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
87760if (retVal != UA_STATUSCODE_GOOD) return retVal;
87761return retVal;
87762}
87763
87764static UA_StatusCode function_namespace0_generated_675_finish(UA_Server *server, UA_UInt16* ns) {
87765return UA_Server_addNode_finish(server,
87766nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2020LU)
87767);
87768}
87769
87770/* SessionsDiagnosticsSummary - ns=0;i=2744 */
87771
87772static UA_StatusCode function_namespace0_generated_676_begin(UA_Server *server, UA_UInt16* ns) {
87773UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87774UA_ObjectAttributes attr = UA_ObjectAttributes_default;
87775attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionsDiagnosticsSummary");
87776retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
87777requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2744LU),
87778parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2020LU),
87779referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87780browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionsDiagnosticsSummary"),
87781typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2026LU),
87782attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
87783if (retVal != UA_STATUSCODE_GOOD) return retVal;
87784return retVal;
87785}
87786
87787static UA_StatusCode function_namespace0_generated_676_finish(UA_Server *server, UA_UInt16* ns) {
87788return UA_Server_addNode_finish(server,
87789nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2744LU)
87790);
87791}
87792
87793/* SessionSecurityDiagnosticsArray - ns=0;i=3130 */
87794
87795static UA_StatusCode function_namespace0_generated_677_begin(UA_Server *server, UA_UInt16* ns) {
87796UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87797UA_VariableAttributes attr = UA_VariableAttributes_default;
87798attr.minimumSamplingInterval = 0.000000;
87799attr.userAccessLevel = 1;
87800attr.accessLevel = 1;
87801attr.valueRank = 1;
87802attr.arrayDimensionsSize = 1;
87803UA_UInt32 arrayDimensions[1];
87804arrayDimensions[0] = 0;
87805attr.arrayDimensions = &arrayDimensions[0];
87806attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 868LU);
87807attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionSecurityDiagnosticsArray");
87808retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87809requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3130LU),
87810parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2744LU),
87811referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87812browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionSecurityDiagnosticsArray"),
87813typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2243LU),
87814attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87815if (retVal != UA_STATUSCODE_GOOD) return retVal;
87816return retVal;
87817}
87818
87819static UA_StatusCode function_namespace0_generated_677_finish(UA_Server *server, UA_UInt16* ns) {
87820return UA_Server_addNode_finish(server,
87821nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3130LU)
87822);
87823}
87824
87825/* SessionDiagnosticsArray - ns=0;i=3129 */
87826
87827static UA_StatusCode function_namespace0_generated_678_begin(UA_Server *server, UA_UInt16* ns) {
87828UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87829UA_VariableAttributes attr = UA_VariableAttributes_default;
87830attr.minimumSamplingInterval = 0.000000;
87831attr.userAccessLevel = 1;
87832attr.accessLevel = 1;
87833attr.valueRank = 1;
87834attr.arrayDimensionsSize = 1;
87835UA_UInt32 arrayDimensions[1];
87836arrayDimensions[0] = 0;
87837attr.arrayDimensions = &arrayDimensions[0];
87838attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 865LU);
87839attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionDiagnosticsArray");
87840retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87841requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3129LU),
87842parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2744LU),
87843referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87844browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionDiagnosticsArray"),
87845typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2196LU),
87846attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87847if (retVal != UA_STATUSCODE_GOOD) return retVal;
87848return retVal;
87849}
87850
87851static UA_StatusCode function_namespace0_generated_678_finish(UA_Server *server, UA_UInt16* ns) {
87852return UA_Server_addNode_finish(server,
87853nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3129LU)
87854);
87855}
87856
87857/* EnabledFlag - ns=0;i=2025 */
87858
87859static UA_StatusCode function_namespace0_generated_679_begin(UA_Server *server, UA_UInt16* ns) {
87860UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87861UA_VariableAttributes attr = UA_VariableAttributes_default;
87862attr.minimumSamplingInterval = 0.000000;
87863attr.userAccessLevel = 1;
87864attr.accessLevel = 3;
87865/* Value rank inherited */
87866attr.valueRank = -2;
87867attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
87868attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnabledFlag");
87869retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87870requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2025LU),
87871parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2020LU),
87872referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
87873browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnabledFlag"),
87874typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
87875attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87876if (retVal != UA_STATUSCODE_GOOD) return retVal;
87877return retVal;
87878}
87879
87880static UA_StatusCode function_namespace0_generated_679_finish(UA_Server *server, UA_UInt16* ns) {
87881return UA_Server_addNode_finish(server,
87882nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2025LU)
87883);
87884}
87885
87886/* SubscriptionDiagnosticsArray - ns=0;i=2023 */
87887
87888static UA_StatusCode function_namespace0_generated_680_begin(UA_Server *server, UA_UInt16* ns) {
87889UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87890UA_VariableAttributes attr = UA_VariableAttributes_default;
87891attr.minimumSamplingInterval = 0.000000;
87892attr.userAccessLevel = 1;
87893attr.accessLevel = 1;
87894attr.valueRank = 1;
87895attr.arrayDimensionsSize = 1;
87896UA_UInt32 arrayDimensions[1];
87897arrayDimensions[0] = 0;
87898attr.arrayDimensions = &arrayDimensions[0];
87899attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 874LU);
87900attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscriptionDiagnosticsArray");
87901retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87902requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2023LU),
87903parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2020LU),
87904referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87905browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscriptionDiagnosticsArray"),
87906typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2171LU),
87907attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87908if (retVal != UA_STATUSCODE_GOOD) return retVal;
87909return retVal;
87910}
87911
87912static UA_StatusCode function_namespace0_generated_680_finish(UA_Server *server, UA_UInt16* ns) {
87913return UA_Server_addNode_finish(server,
87914nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2023LU)
87915);
87916}
87917
87918/* SamplingIntervalDiagnosticsArray - ns=0;i=2022 */
87919
87920static UA_StatusCode function_namespace0_generated_681_begin(UA_Server *server, UA_UInt16* ns) {
87921UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87922UA_VariableAttributes attr = UA_VariableAttributes_default;
87923attr.minimumSamplingInterval = 0.000000;
87924attr.userAccessLevel = 1;
87925attr.accessLevel = 1;
87926attr.valueRank = 1;
87927attr.arrayDimensionsSize = 1;
87928UA_UInt32 arrayDimensions[1];
87929arrayDimensions[0] = 0;
87930attr.arrayDimensions = &arrayDimensions[0];
87931attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 856LU);
87932attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SamplingIntervalDiagnosticsArray");
87933retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87934requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2022LU),
87935parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2020LU),
87936referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87937browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SamplingIntervalDiagnosticsArray"),
87938typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2164LU),
87939attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87940if (retVal != UA_STATUSCODE_GOOD) return retVal;
87941return retVal;
87942}
87943
87944static UA_StatusCode function_namespace0_generated_681_finish(UA_Server *server, UA_UInt16* ns) {
87945return UA_Server_addNode_finish(server,
87946nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2022LU)
87947);
87948}
87949
87950/* ServerDiagnosticsSummary - ns=0;i=2021 */
87951
87952static UA_StatusCode function_namespace0_generated_682_begin(UA_Server *server, UA_UInt16* ns) {
87953UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87954UA_VariableAttributes attr = UA_VariableAttributes_default;
87955attr.minimumSamplingInterval = 0.000000;
87956attr.userAccessLevel = 1;
87957attr.accessLevel = 1;
87958/* Value rank inherited */
87959attr.valueRank = -2;
87960attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 859LU);
87961attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerDiagnosticsSummary");
87962retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87963requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU),
87964parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2020LU),
87965referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87966browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerDiagnosticsSummary"),
87967typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
87968attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87969if (retVal != UA_STATUSCODE_GOOD) return retVal;
87970return retVal;
87971}
87972
87973static UA_StatusCode function_namespace0_generated_682_finish(UA_Server *server, UA_UInt16* ns) {
87974return UA_Server_addNode_finish(server,
87975nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU)
87976);
87977}
87978
87979/* RejectedRequestsCount - ns=0;i=3128 */
87980
87981static UA_StatusCode function_namespace0_generated_683_begin(UA_Server *server, UA_UInt16* ns) {
87982UA_StatusCode retVal = UA_STATUSCODE_GOOD;
87983UA_VariableAttributes attr = UA_VariableAttributes_default;
87984attr.minimumSamplingInterval = 0.000000;
87985attr.userAccessLevel = 1;
87986attr.accessLevel = 1;
87987/* Value rank inherited */
87988attr.valueRank = -2;
87989attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
87990attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RejectedRequestsCount");
87991retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
87992requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3128LU),
87993parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU),
87994referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
87995browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RejectedRequestsCount"),
87996typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
87997attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
87998if (retVal != UA_STATUSCODE_GOOD) return retVal;
87999return retVal;
88000}
88001
88002static UA_StatusCode function_namespace0_generated_683_finish(UA_Server *server, UA_UInt16* ns) {
88003return UA_Server_addNode_finish(server,
88004nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3128LU)
88005);
88006}
88007
88008/* SecurityRejectedRequestsCount - ns=0;i=3127 */
88009
88010static UA_StatusCode function_namespace0_generated_684_begin(UA_Server *server, UA_UInt16* ns) {
88011UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88012UA_VariableAttributes attr = UA_VariableAttributes_default;
88013attr.minimumSamplingInterval = 0.000000;
88014attr.userAccessLevel = 1;
88015attr.accessLevel = 1;
88016/* Value rank inherited */
88017attr.valueRank = -2;
88018attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88019attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityRejectedRequestsCount");
88020retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88021requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3127LU),
88022parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU),
88023referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88024browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityRejectedRequestsCount"),
88025typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88026attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88027if (retVal != UA_STATUSCODE_GOOD) return retVal;
88028return retVal;
88029}
88030
88031static UA_StatusCode function_namespace0_generated_684_finish(UA_Server *server, UA_UInt16* ns) {
88032return UA_Server_addNode_finish(server,
88033nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3127LU)
88034);
88035}
88036
88037/* CumulatedSubscriptionCount - ns=0;i=3126 */
88038
88039static UA_StatusCode function_namespace0_generated_685_begin(UA_Server *server, UA_UInt16* ns) {
88040UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88041UA_VariableAttributes attr = UA_VariableAttributes_default;
88042attr.minimumSamplingInterval = 0.000000;
88043attr.userAccessLevel = 1;
88044attr.accessLevel = 1;
88045/* Value rank inherited */
88046attr.valueRank = -2;
88047attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88048attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CumulatedSubscriptionCount");
88049retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88050requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3126LU),
88051parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU),
88052referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88053browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CumulatedSubscriptionCount"),
88054typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88055attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88056if (retVal != UA_STATUSCODE_GOOD) return retVal;
88057return retVal;
88058}
88059
88060static UA_StatusCode function_namespace0_generated_685_finish(UA_Server *server, UA_UInt16* ns) {
88061return UA_Server_addNode_finish(server,
88062nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3126LU)
88063);
88064}
88065
88066/* CurrentSubscriptionCount - ns=0;i=3125 */
88067
88068static UA_StatusCode function_namespace0_generated_686_begin(UA_Server *server, UA_UInt16* ns) {
88069UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88070UA_VariableAttributes attr = UA_VariableAttributes_default;
88071attr.minimumSamplingInterval = 0.000000;
88072attr.userAccessLevel = 1;
88073attr.accessLevel = 1;
88074/* Value rank inherited */
88075attr.valueRank = -2;
88076attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88077attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentSubscriptionCount");
88078retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88079requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3125LU),
88080parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU),
88081referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88082browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentSubscriptionCount"),
88083typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88084attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88085if (retVal != UA_STATUSCODE_GOOD) return retVal;
88086return retVal;
88087}
88088
88089static UA_StatusCode function_namespace0_generated_686_finish(UA_Server *server, UA_UInt16* ns) {
88090return UA_Server_addNode_finish(server,
88091nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3125LU)
88092);
88093}
88094
88095/* PublishingIntervalCount - ns=0;i=3124 */
88096
88097static UA_StatusCode function_namespace0_generated_687_begin(UA_Server *server, UA_UInt16* ns) {
88098UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88099UA_VariableAttributes attr = UA_VariableAttributes_default;
88100attr.minimumSamplingInterval = 0.000000;
88101attr.userAccessLevel = 1;
88102attr.accessLevel = 1;
88103/* Value rank inherited */
88104attr.valueRank = -2;
88105attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88106attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishingIntervalCount");
88107retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88108requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3124LU),
88109parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU),
88110referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88111browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishingIntervalCount"),
88112typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88113attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88114if (retVal != UA_STATUSCODE_GOOD) return retVal;
88115return retVal;
88116}
88117
88118static UA_StatusCode function_namespace0_generated_687_finish(UA_Server *server, UA_UInt16* ns) {
88119return UA_Server_addNode_finish(server,
88120nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3124LU)
88121);
88122}
88123
88124/* SessionAbortCount - ns=0;i=3122 */
88125
88126static UA_StatusCode function_namespace0_generated_688_begin(UA_Server *server, UA_UInt16* ns) {
88127UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88128UA_VariableAttributes attr = UA_VariableAttributes_default;
88129attr.minimumSamplingInterval = 0.000000;
88130attr.userAccessLevel = 1;
88131attr.accessLevel = 1;
88132/* Value rank inherited */
88133attr.valueRank = -2;
88134attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88135attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionAbortCount");
88136retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88137requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3122LU),
88138parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU),
88139referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88140browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionAbortCount"),
88141typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88142attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88143if (retVal != UA_STATUSCODE_GOOD) return retVal;
88144return retVal;
88145}
88146
88147static UA_StatusCode function_namespace0_generated_688_finish(UA_Server *server, UA_UInt16* ns) {
88148return UA_Server_addNode_finish(server,
88149nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3122LU)
88150);
88151}
88152
88153/* SessionTimeoutCount - ns=0;i=3121 */
88154
88155static UA_StatusCode function_namespace0_generated_689_begin(UA_Server *server, UA_UInt16* ns) {
88156UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88157UA_VariableAttributes attr = UA_VariableAttributes_default;
88158attr.minimumSamplingInterval = 0.000000;
88159attr.userAccessLevel = 1;
88160attr.accessLevel = 1;
88161/* Value rank inherited */
88162attr.valueRank = -2;
88163attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88164attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionTimeoutCount");
88165retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88166requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3121LU),
88167parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU),
88168referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88169browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionTimeoutCount"),
88170typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88171attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88172if (retVal != UA_STATUSCODE_GOOD) return retVal;
88173return retVal;
88174}
88175
88176static UA_StatusCode function_namespace0_generated_689_finish(UA_Server *server, UA_UInt16* ns) {
88177return UA_Server_addNode_finish(server,
88178nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3121LU)
88179);
88180}
88181
88182/* RejectedSessionCount - ns=0;i=3120 */
88183
88184static UA_StatusCode function_namespace0_generated_690_begin(UA_Server *server, UA_UInt16* ns) {
88185UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88186UA_VariableAttributes attr = UA_VariableAttributes_default;
88187attr.minimumSamplingInterval = 0.000000;
88188attr.userAccessLevel = 1;
88189attr.accessLevel = 1;
88190/* Value rank inherited */
88191attr.valueRank = -2;
88192attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88193attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RejectedSessionCount");
88194retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88195requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3120LU),
88196parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU),
88197referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88198browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RejectedSessionCount"),
88199typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88200attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88201if (retVal != UA_STATUSCODE_GOOD) return retVal;
88202return retVal;
88203}
88204
88205static UA_StatusCode function_namespace0_generated_690_finish(UA_Server *server, UA_UInt16* ns) {
88206return UA_Server_addNode_finish(server,
88207nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3120LU)
88208);
88209}
88210
88211/* SecurityRejectedSessionCount - ns=0;i=3119 */
88212
88213static UA_StatusCode function_namespace0_generated_691_begin(UA_Server *server, UA_UInt16* ns) {
88214UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88215UA_VariableAttributes attr = UA_VariableAttributes_default;
88216attr.minimumSamplingInterval = 0.000000;
88217attr.userAccessLevel = 1;
88218attr.accessLevel = 1;
88219/* Value rank inherited */
88220attr.valueRank = -2;
88221attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88222attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityRejectedSessionCount");
88223retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88224requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3119LU),
88225parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU),
88226referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88227browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityRejectedSessionCount"),
88228typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88229attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88230if (retVal != UA_STATUSCODE_GOOD) return retVal;
88231return retVal;
88232}
88233
88234static UA_StatusCode function_namespace0_generated_691_finish(UA_Server *server, UA_UInt16* ns) {
88235return UA_Server_addNode_finish(server,
88236nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3119LU)
88237);
88238}
88239
88240/* CumulatedSessionCount - ns=0;i=3118 */
88241
88242static UA_StatusCode function_namespace0_generated_692_begin(UA_Server *server, UA_UInt16* ns) {
88243UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88244UA_VariableAttributes attr = UA_VariableAttributes_default;
88245attr.minimumSamplingInterval = 0.000000;
88246attr.userAccessLevel = 1;
88247attr.accessLevel = 1;
88248/* Value rank inherited */
88249attr.valueRank = -2;
88250attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88251attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CumulatedSessionCount");
88252retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88253requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3118LU),
88254parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU),
88255referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88256browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CumulatedSessionCount"),
88257typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88258attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88259if (retVal != UA_STATUSCODE_GOOD) return retVal;
88260return retVal;
88261}
88262
88263static UA_StatusCode function_namespace0_generated_692_finish(UA_Server *server, UA_UInt16* ns) {
88264return UA_Server_addNode_finish(server,
88265nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3118LU)
88266);
88267}
88268
88269/* CurrentSessionCount - ns=0;i=3117 */
88270
88271static UA_StatusCode function_namespace0_generated_693_begin(UA_Server *server, UA_UInt16* ns) {
88272UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88273UA_VariableAttributes attr = UA_VariableAttributes_default;
88274attr.minimumSamplingInterval = 0.000000;
88275attr.userAccessLevel = 1;
88276attr.accessLevel = 1;
88277/* Value rank inherited */
88278attr.valueRank = -2;
88279attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88280attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentSessionCount");
88281retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88282requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3117LU),
88283parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU),
88284referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88285browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentSessionCount"),
88286typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88287attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88288if (retVal != UA_STATUSCODE_GOOD) return retVal;
88289return retVal;
88290}
88291
88292static UA_StatusCode function_namespace0_generated_693_finish(UA_Server *server, UA_UInt16* ns) {
88293return UA_Server_addNode_finish(server,
88294nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3117LU)
88295);
88296}
88297
88298/* ServerViewCount - ns=0;i=3116 */
88299
88300static UA_StatusCode function_namespace0_generated_694_begin(UA_Server *server, UA_UInt16* ns) {
88301UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88302UA_VariableAttributes attr = UA_VariableAttributes_default;
88303attr.minimumSamplingInterval = 0.000000;
88304attr.userAccessLevel = 1;
88305attr.accessLevel = 1;
88306/* Value rank inherited */
88307attr.valueRank = -2;
88308attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88309attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerViewCount");
88310retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88311requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3116LU),
88312parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU),
88313referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88314browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerViewCount"),
88315typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88316attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88317if (retVal != UA_STATUSCODE_GOOD) return retVal;
88318return retVal;
88319}
88320
88321static UA_StatusCode function_namespace0_generated_694_finish(UA_Server *server, UA_UInt16* ns) {
88322return UA_Server_addNode_finish(server,
88323nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3116LU)
88324);
88325}
88326
88327/* ServerCapabilitiesType - ns=0;i=2013 */
88328
88329static UA_StatusCode function_namespace0_generated_695_begin(UA_Server *server, UA_UInt16* ns) {
88330UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88331UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
88332attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerCapabilitiesType");
88333retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
88334requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2013LU),
88335parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
88336referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
88337browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerCapabilitiesType"),
88338 typeDefinition: UA_NODEID_NULL,
88339attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
88340if (retVal != UA_STATUSCODE_GOOD) return retVal;
88341return retVal;
88342}
88343
88344static UA_StatusCode function_namespace0_generated_695_finish(UA_Server *server, UA_UInt16* ns) {
88345return UA_Server_addNode_finish(server,
88346nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2013LU)
88347);
88348}
88349
88350/* OperationLimits - ns=0;i=11551 */
88351
88352static UA_StatusCode function_namespace0_generated_696_begin(UA_Server *server, UA_UInt16* ns) {
88353UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88354UA_ObjectAttributes attr = UA_ObjectAttributes_default;
88355attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OperationLimits");
88356retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
88357requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11551LU),
88358parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2013LU),
88359referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88360browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OperationLimits"),
88361typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11564LU),
88362attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
88363if (retVal != UA_STATUSCODE_GOOD) return retVal;
88364return retVal;
88365}
88366
88367static UA_StatusCode function_namespace0_generated_696_finish(UA_Server *server, UA_UInt16* ns) {
88368return UA_Server_addNode_finish(server,
88369nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11551LU)
88370);
88371}
88372
88373/* ServerType - ns=0;i=2004 */
88374
88375static UA_StatusCode function_namespace0_generated_697_begin(UA_Server *server, UA_UInt16* ns) {
88376UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88377UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
88378attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerType");
88379retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
88380requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2004LU),
88381parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
88382referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
88383browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerType"),
88384 typeDefinition: UA_NODEID_NULL,
88385attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
88386if (retVal != UA_STATUSCODE_GOOD) return retVal;
88387return retVal;
88388}
88389
88390static UA_StatusCode function_namespace0_generated_697_finish(UA_Server *server, UA_UInt16* ns) {
88391return UA_Server_addNode_finish(server,
88392nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2004LU)
88393);
88394}
88395
88396/* Server - ns=0;i=2253 */
88397
88398static UA_StatusCode function_namespace0_generated_698_begin(UA_Server *server, UA_UInt16* ns) {
88399UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88400UA_ObjectAttributes attr = UA_ObjectAttributes_default;
88401attr.eventNotifier = UA_EVENTNOTIFIER_SUBSCRIBE_TO_EVENT;
88402attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Server");
88403retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
88404requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU),
88405parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 85LU),
88406referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 35LU),
88407browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Server"),
88408typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2004LU),
88409attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
88410if (retVal != UA_STATUSCODE_GOOD) return retVal;
88411return retVal;
88412}
88413
88414static UA_StatusCode function_namespace0_generated_698_finish(UA_Server *server, UA_UInt16* ns) {
88415return UA_Server_addNode_finish(server,
88416nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU)
88417);
88418}
88419
88420/* Auditing - ns=0;i=2994 */
88421
88422static UA_StatusCode function_namespace0_generated_699_begin(UA_Server *server, UA_UInt16* ns) {
88423UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88424UA_VariableAttributes attr = UA_VariableAttributes_default;
88425attr.minimumSamplingInterval = 1000.000000;
88426attr.userAccessLevel = 1;
88427attr.accessLevel = 1;
88428/* Value rank inherited */
88429attr.valueRank = -2;
88430attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
88431attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Auditing");
88432retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88433requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2994LU),
88434parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU),
88435referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
88436browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Auditing"),
88437typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
88438attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88439if (retVal != UA_STATUSCODE_GOOD) return retVal;
88440return retVal;
88441}
88442
88443static UA_StatusCode function_namespace0_generated_699_finish(UA_Server *server, UA_UInt16* ns) {
88444return UA_Server_addNode_finish(server,
88445nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2994LU)
88446);
88447}
88448
88449/* ServerRedundancy - ns=0;i=2296 */
88450
88451static UA_StatusCode function_namespace0_generated_700_begin(UA_Server *server, UA_UInt16* ns) {
88452UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88453UA_ObjectAttributes attr = UA_ObjectAttributes_default;
88454attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerRedundancy");
88455retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
88456requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2296LU),
88457parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU),
88458referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88459browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerRedundancy"),
88460typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2034LU),
88461attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
88462if (retVal != UA_STATUSCODE_GOOD) return retVal;
88463return retVal;
88464}
88465
88466static UA_StatusCode function_namespace0_generated_700_finish(UA_Server *server, UA_UInt16* ns) {
88467return UA_Server_addNode_finish(server,
88468nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2296LU)
88469);
88470}
88471
88472/* RedundancySupport - ns=0;i=3709 */
88473
88474static UA_StatusCode function_namespace0_generated_701_begin(UA_Server *server, UA_UInt16* ns) {
88475UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88476UA_VariableAttributes attr = UA_VariableAttributes_default;
88477attr.minimumSamplingInterval = 0.000000;
88478attr.userAccessLevel = 1;
88479attr.accessLevel = 1;
88480/* Value rank inherited */
88481attr.valueRank = -2;
88482attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 851LU);
88483attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RedundancySupport");
88484retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88485requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3709LU),
88486parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2296LU),
88487referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
88488browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RedundancySupport"),
88489typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
88490attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88491if (retVal != UA_STATUSCODE_GOOD) return retVal;
88492return retVal;
88493}
88494
88495static UA_StatusCode function_namespace0_generated_701_finish(UA_Server *server, UA_UInt16* ns) {
88496return UA_Server_addNode_finish(server,
88497nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3709LU)
88498);
88499}
88500
88501/* VendorServerInfo - ns=0;i=2295 */
88502
88503static UA_StatusCode function_namespace0_generated_702_begin(UA_Server *server, UA_UInt16* ns) {
88504UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88505UA_ObjectAttributes attr = UA_ObjectAttributes_default;
88506attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "VendorServerInfo");
88507retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
88508requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2295LU),
88509parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU),
88510referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88511browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "VendorServerInfo"),
88512typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2033LU),
88513attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
88514if (retVal != UA_STATUSCODE_GOOD) return retVal;
88515return retVal;
88516}
88517
88518static UA_StatusCode function_namespace0_generated_702_finish(UA_Server *server, UA_UInt16* ns) {
88519return UA_Server_addNode_finish(server,
88520nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2295LU)
88521);
88522}
88523
88524/* ServerDiagnostics - ns=0;i=2274 */
88525
88526static UA_StatusCode function_namespace0_generated_703_begin(UA_Server *server, UA_UInt16* ns) {
88527UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88528UA_ObjectAttributes attr = UA_ObjectAttributes_default;
88529attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerDiagnostics");
88530retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
88531requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2274LU),
88532parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU),
88533referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88534browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerDiagnostics"),
88535typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2020LU),
88536attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
88537if (retVal != UA_STATUSCODE_GOOD) return retVal;
88538return retVal;
88539}
88540
88541static UA_StatusCode function_namespace0_generated_703_finish(UA_Server *server, UA_UInt16* ns) {
88542return UA_Server_addNode_finish(server,
88543nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2274LU)
88544);
88545}
88546
88547/* SessionsDiagnosticsSummary - ns=0;i=3706 */
88548
88549static UA_StatusCode function_namespace0_generated_704_begin(UA_Server *server, UA_UInt16* ns) {
88550UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88551UA_ObjectAttributes attr = UA_ObjectAttributes_default;
88552attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionsDiagnosticsSummary");
88553retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
88554requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3706LU),
88555parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2274LU),
88556referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88557browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionsDiagnosticsSummary"),
88558typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2026LU),
88559attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
88560if (retVal != UA_STATUSCODE_GOOD) return retVal;
88561return retVal;
88562}
88563
88564static UA_StatusCode function_namespace0_generated_704_finish(UA_Server *server, UA_UInt16* ns) {
88565return UA_Server_addNode_finish(server,
88566nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3706LU)
88567);
88568}
88569
88570/* SessionSecurityDiagnosticsArray - ns=0;i=3708 */
88571
88572static UA_StatusCode function_namespace0_generated_705_begin(UA_Server *server, UA_UInt16* ns) {
88573UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88574UA_VariableAttributes attr = UA_VariableAttributes_default;
88575attr.minimumSamplingInterval = 0.000000;
88576attr.userAccessLevel = 1;
88577attr.accessLevel = 1;
88578attr.valueRank = 1;
88579attr.arrayDimensionsSize = 1;
88580UA_UInt32 arrayDimensions[1];
88581arrayDimensions[0] = 0;
88582attr.arrayDimensions = &arrayDimensions[0];
88583attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 868LU);
88584attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionSecurityDiagnosticsArray");
88585retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88586requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3708LU),
88587parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3706LU),
88588referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88589browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionSecurityDiagnosticsArray"),
88590typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2243LU),
88591attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88592if (retVal != UA_STATUSCODE_GOOD) return retVal;
88593return retVal;
88594}
88595
88596static UA_StatusCode function_namespace0_generated_705_finish(UA_Server *server, UA_UInt16* ns) {
88597return UA_Server_addNode_finish(server,
88598nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3708LU)
88599);
88600}
88601
88602/* SessionDiagnosticsArray - ns=0;i=3707 */
88603
88604static UA_StatusCode function_namespace0_generated_706_begin(UA_Server *server, UA_UInt16* ns) {
88605UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88606UA_VariableAttributes attr = UA_VariableAttributes_default;
88607attr.minimumSamplingInterval = 0.000000;
88608attr.userAccessLevel = 1;
88609attr.accessLevel = 1;
88610attr.valueRank = 1;
88611attr.arrayDimensionsSize = 1;
88612UA_UInt32 arrayDimensions[1];
88613arrayDimensions[0] = 0;
88614attr.arrayDimensions = &arrayDimensions[0];
88615attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 865LU);
88616attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionDiagnosticsArray");
88617retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88618requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3707LU),
88619parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3706LU),
88620referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88621browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionDiagnosticsArray"),
88622typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2196LU),
88623attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88624if (retVal != UA_STATUSCODE_GOOD) return retVal;
88625return retVal;
88626}
88627
88628static UA_StatusCode function_namespace0_generated_706_finish(UA_Server *server, UA_UInt16* ns) {
88629return UA_Server_addNode_finish(server,
88630nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3707LU)
88631);
88632}
88633
88634/* EnabledFlag - ns=0;i=2294 */
88635
88636static UA_StatusCode function_namespace0_generated_707_begin(UA_Server *server, UA_UInt16* ns) {
88637UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88638UA_VariableAttributes attr = UA_VariableAttributes_default;
88639attr.minimumSamplingInterval = 0.000000;
88640attr.userAccessLevel = 1;
88641attr.accessLevel = 3;
88642/* Value rank inherited */
88643attr.valueRank = -2;
88644attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
88645attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnabledFlag");
88646retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88647requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2294LU),
88648parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2274LU),
88649referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
88650browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnabledFlag"),
88651typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
88652attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88653if (retVal != UA_STATUSCODE_GOOD) return retVal;
88654return retVal;
88655}
88656
88657static UA_StatusCode function_namespace0_generated_707_finish(UA_Server *server, UA_UInt16* ns) {
88658return UA_Server_addNode_finish(server,
88659nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2294LU)
88660);
88661}
88662
88663/* SubscriptionDiagnosticsArray - ns=0;i=2290 */
88664
88665static UA_StatusCode function_namespace0_generated_708_begin(UA_Server *server, UA_UInt16* ns) {
88666UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88667UA_VariableAttributes attr = UA_VariableAttributes_default;
88668attr.minimumSamplingInterval = 0.000000;
88669attr.userAccessLevel = 1;
88670attr.accessLevel = 1;
88671attr.valueRank = 1;
88672attr.arrayDimensionsSize = 1;
88673UA_UInt32 arrayDimensions[1];
88674arrayDimensions[0] = 0;
88675attr.arrayDimensions = &arrayDimensions[0];
88676attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 874LU);
88677attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscriptionDiagnosticsArray");
88678retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88679requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2290LU),
88680parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2274LU),
88681referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88682browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscriptionDiagnosticsArray"),
88683typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2171LU),
88684attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88685if (retVal != UA_STATUSCODE_GOOD) return retVal;
88686return retVal;
88687}
88688
88689static UA_StatusCode function_namespace0_generated_708_finish(UA_Server *server, UA_UInt16* ns) {
88690return UA_Server_addNode_finish(server,
88691nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2290LU)
88692);
88693}
88694
88695/* ServerDiagnosticsSummary - ns=0;i=2275 */
88696
88697static UA_StatusCode function_namespace0_generated_709_begin(UA_Server *server, UA_UInt16* ns) {
88698UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88699UA_VariableAttributes attr = UA_VariableAttributes_default;
88700attr.minimumSamplingInterval = 0.000000;
88701attr.userAccessLevel = 1;
88702attr.accessLevel = 1;
88703/* Value rank inherited */
88704attr.valueRank = -2;
88705attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 859LU);
88706attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerDiagnosticsSummary");
88707retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88708requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU),
88709parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2274LU),
88710referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88711browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerDiagnosticsSummary"),
88712typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2150LU),
88713attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88714if (retVal != UA_STATUSCODE_GOOD) return retVal;
88715return retVal;
88716}
88717
88718static UA_StatusCode function_namespace0_generated_709_finish(UA_Server *server, UA_UInt16* ns) {
88719return UA_Server_addNode_finish(server,
88720nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU)
88721);
88722}
88723
88724/* RejectedSessionCount - ns=0;i=3705 */
88725
88726static UA_StatusCode function_namespace0_generated_710_begin(UA_Server *server, UA_UInt16* ns) {
88727UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88728UA_VariableAttributes attr = UA_VariableAttributes_default;
88729attr.minimumSamplingInterval = 0.000000;
88730attr.userAccessLevel = 1;
88731attr.accessLevel = 1;
88732/* Value rank inherited */
88733attr.valueRank = -2;
88734attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88735attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RejectedSessionCount");
88736retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88737requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3705LU),
88738parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU),
88739referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88740browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RejectedSessionCount"),
88741typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88742attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88743if (retVal != UA_STATUSCODE_GOOD) return retVal;
88744return retVal;
88745}
88746
88747static UA_StatusCode function_namespace0_generated_710_finish(UA_Server *server, UA_UInt16* ns) {
88748return UA_Server_addNode_finish(server,
88749nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3705LU)
88750);
88751}
88752
88753/* RejectedRequestsCount - ns=0;i=2288 */
88754
88755static UA_StatusCode function_namespace0_generated_711_begin(UA_Server *server, UA_UInt16* ns) {
88756UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88757UA_VariableAttributes attr = UA_VariableAttributes_default;
88758attr.minimumSamplingInterval = 0.000000;
88759attr.userAccessLevel = 1;
88760attr.accessLevel = 1;
88761/* Value rank inherited */
88762attr.valueRank = -2;
88763attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88764attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RejectedRequestsCount");
88765retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88766requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2288LU),
88767parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU),
88768referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88769browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RejectedRequestsCount"),
88770typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88771attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88772if (retVal != UA_STATUSCODE_GOOD) return retVal;
88773return retVal;
88774}
88775
88776static UA_StatusCode function_namespace0_generated_711_finish(UA_Server *server, UA_UInt16* ns) {
88777return UA_Server_addNode_finish(server,
88778nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2288LU)
88779);
88780}
88781
88782/* SecurityRejectedRequestsCount - ns=0;i=2287 */
88783
88784static UA_StatusCode function_namespace0_generated_712_begin(UA_Server *server, UA_UInt16* ns) {
88785UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88786UA_VariableAttributes attr = UA_VariableAttributes_default;
88787attr.minimumSamplingInterval = 0.000000;
88788attr.userAccessLevel = 1;
88789attr.accessLevel = 1;
88790/* Value rank inherited */
88791attr.valueRank = -2;
88792attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88793attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityRejectedRequestsCount");
88794retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88795requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2287LU),
88796parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU),
88797referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88798browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityRejectedRequestsCount"),
88799typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88800attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88801if (retVal != UA_STATUSCODE_GOOD) return retVal;
88802return retVal;
88803}
88804
88805static UA_StatusCode function_namespace0_generated_712_finish(UA_Server *server, UA_UInt16* ns) {
88806return UA_Server_addNode_finish(server,
88807nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2287LU)
88808);
88809}
88810
88811/* CumulatedSubscriptionCount - ns=0;i=2286 */
88812
88813static UA_StatusCode function_namespace0_generated_713_begin(UA_Server *server, UA_UInt16* ns) {
88814UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88815UA_VariableAttributes attr = UA_VariableAttributes_default;
88816attr.minimumSamplingInterval = 0.000000;
88817attr.userAccessLevel = 1;
88818attr.accessLevel = 1;
88819/* Value rank inherited */
88820attr.valueRank = -2;
88821attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88822attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CumulatedSubscriptionCount");
88823retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88824requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2286LU),
88825parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU),
88826referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88827browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CumulatedSubscriptionCount"),
88828typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88829attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88830if (retVal != UA_STATUSCODE_GOOD) return retVal;
88831return retVal;
88832}
88833
88834static UA_StatusCode function_namespace0_generated_713_finish(UA_Server *server, UA_UInt16* ns) {
88835return UA_Server_addNode_finish(server,
88836nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2286LU)
88837);
88838}
88839
88840/* CurrentSubscriptionCount - ns=0;i=2285 */
88841
88842static UA_StatusCode function_namespace0_generated_714_begin(UA_Server *server, UA_UInt16* ns) {
88843UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88844UA_VariableAttributes attr = UA_VariableAttributes_default;
88845attr.minimumSamplingInterval = 0.000000;
88846attr.userAccessLevel = 1;
88847attr.accessLevel = 1;
88848/* Value rank inherited */
88849attr.valueRank = -2;
88850attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88851attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentSubscriptionCount");
88852retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88853requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2285LU),
88854parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU),
88855referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88856browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentSubscriptionCount"),
88857typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88858attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88859if (retVal != UA_STATUSCODE_GOOD) return retVal;
88860return retVal;
88861}
88862
88863static UA_StatusCode function_namespace0_generated_714_finish(UA_Server *server, UA_UInt16* ns) {
88864return UA_Server_addNode_finish(server,
88865nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2285LU)
88866);
88867}
88868
88869/* PublishingIntervalCount - ns=0;i=2284 */
88870
88871static UA_StatusCode function_namespace0_generated_715_begin(UA_Server *server, UA_UInt16* ns) {
88872UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88873UA_VariableAttributes attr = UA_VariableAttributes_default;
88874attr.minimumSamplingInterval = 0.000000;
88875attr.userAccessLevel = 1;
88876attr.accessLevel = 1;
88877/* Value rank inherited */
88878attr.valueRank = -2;
88879attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88880attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishingIntervalCount");
88881retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88882requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2284LU),
88883parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU),
88884referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88885browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishingIntervalCount"),
88886typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88887attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88888if (retVal != UA_STATUSCODE_GOOD) return retVal;
88889return retVal;
88890}
88891
88892static UA_StatusCode function_namespace0_generated_715_finish(UA_Server *server, UA_UInt16* ns) {
88893return UA_Server_addNode_finish(server,
88894nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2284LU)
88895);
88896}
88897
88898/* SessionAbortCount - ns=0;i=2282 */
88899
88900static UA_StatusCode function_namespace0_generated_716_begin(UA_Server *server, UA_UInt16* ns) {
88901UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88902UA_VariableAttributes attr = UA_VariableAttributes_default;
88903attr.minimumSamplingInterval = 0.000000;
88904attr.userAccessLevel = 1;
88905attr.accessLevel = 1;
88906/* Value rank inherited */
88907attr.valueRank = -2;
88908attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88909attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionAbortCount");
88910retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88911requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2282LU),
88912parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU),
88913referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88914browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionAbortCount"),
88915typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88916attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88917if (retVal != UA_STATUSCODE_GOOD) return retVal;
88918return retVal;
88919}
88920
88921static UA_StatusCode function_namespace0_generated_716_finish(UA_Server *server, UA_UInt16* ns) {
88922return UA_Server_addNode_finish(server,
88923nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2282LU)
88924);
88925}
88926
88927/* SessionTimeoutCount - ns=0;i=2281 */
88928
88929static UA_StatusCode function_namespace0_generated_717_begin(UA_Server *server, UA_UInt16* ns) {
88930UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88931UA_VariableAttributes attr = UA_VariableAttributes_default;
88932attr.minimumSamplingInterval = 0.000000;
88933attr.userAccessLevel = 1;
88934attr.accessLevel = 1;
88935/* Value rank inherited */
88936attr.valueRank = -2;
88937attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88938attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SessionTimeoutCount");
88939retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88940requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2281LU),
88941parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU),
88942referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88943browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SessionTimeoutCount"),
88944typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88945attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88946if (retVal != UA_STATUSCODE_GOOD) return retVal;
88947return retVal;
88948}
88949
88950static UA_StatusCode function_namespace0_generated_717_finish(UA_Server *server, UA_UInt16* ns) {
88951return UA_Server_addNode_finish(server,
88952nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2281LU)
88953);
88954}
88955
88956/* SecurityRejectedSessionCount - ns=0;i=2279 */
88957
88958static UA_StatusCode function_namespace0_generated_718_begin(UA_Server *server, UA_UInt16* ns) {
88959UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88960UA_VariableAttributes attr = UA_VariableAttributes_default;
88961attr.minimumSamplingInterval = 0.000000;
88962attr.userAccessLevel = 1;
88963attr.accessLevel = 1;
88964/* Value rank inherited */
88965attr.valueRank = -2;
88966attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88967attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecurityRejectedSessionCount");
88968retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88969requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2279LU),
88970parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU),
88971referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
88972browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecurityRejectedSessionCount"),
88973typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
88974attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
88975if (retVal != UA_STATUSCODE_GOOD) return retVal;
88976return retVal;
88977}
88978
88979static UA_StatusCode function_namespace0_generated_718_finish(UA_Server *server, UA_UInt16* ns) {
88980return UA_Server_addNode_finish(server,
88981nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2279LU)
88982);
88983}
88984
88985/* CumulatedSessionCount - ns=0;i=2278 */
88986
88987static UA_StatusCode function_namespace0_generated_719_begin(UA_Server *server, UA_UInt16* ns) {
88988UA_StatusCode retVal = UA_STATUSCODE_GOOD;
88989UA_VariableAttributes attr = UA_VariableAttributes_default;
88990attr.minimumSamplingInterval = 0.000000;
88991attr.userAccessLevel = 1;
88992attr.accessLevel = 1;
88993/* Value rank inherited */
88994attr.valueRank = -2;
88995attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
88996attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CumulatedSessionCount");
88997retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
88998requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2278LU),
88999parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU),
89000referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
89001browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CumulatedSessionCount"),
89002typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
89003attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89004if (retVal != UA_STATUSCODE_GOOD) return retVal;
89005return retVal;
89006}
89007
89008static UA_StatusCode function_namespace0_generated_719_finish(UA_Server *server, UA_UInt16* ns) {
89009return UA_Server_addNode_finish(server,
89010nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2278LU)
89011);
89012}
89013
89014/* CurrentSessionCount - ns=0;i=2277 */
89015
89016static UA_StatusCode function_namespace0_generated_720_begin(UA_Server *server, UA_UInt16* ns) {
89017UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89018UA_VariableAttributes attr = UA_VariableAttributes_default;
89019attr.minimumSamplingInterval = 0.000000;
89020attr.userAccessLevel = 1;
89021attr.accessLevel = 1;
89022/* Value rank inherited */
89023attr.valueRank = -2;
89024attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
89025attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentSessionCount");
89026retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89027requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2277LU),
89028parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU),
89029referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
89030browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentSessionCount"),
89031typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
89032attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89033if (retVal != UA_STATUSCODE_GOOD) return retVal;
89034return retVal;
89035}
89036
89037static UA_StatusCode function_namespace0_generated_720_finish(UA_Server *server, UA_UInt16* ns) {
89038return UA_Server_addNode_finish(server,
89039nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2277LU)
89040);
89041}
89042
89043/* ServerViewCount - ns=0;i=2276 */
89044
89045static UA_StatusCode function_namespace0_generated_721_begin(UA_Server *server, UA_UInt16* ns) {
89046UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89047UA_VariableAttributes attr = UA_VariableAttributes_default;
89048attr.minimumSamplingInterval = 0.000000;
89049attr.userAccessLevel = 1;
89050attr.accessLevel = 1;
89051/* Value rank inherited */
89052attr.valueRank = -2;
89053attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
89054attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerViewCount");
89055retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89056requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2276LU),
89057parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2275LU),
89058referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
89059browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerViewCount"),
89060typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
89061attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89062if (retVal != UA_STATUSCODE_GOOD) return retVal;
89063return retVal;
89064}
89065
89066static UA_StatusCode function_namespace0_generated_721_finish(UA_Server *server, UA_UInt16* ns) {
89067return UA_Server_addNode_finish(server,
89068nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2276LU)
89069);
89070}
89071
89072/* ServerCapabilities - ns=0;i=2268 */
89073
89074static UA_StatusCode function_namespace0_generated_722_begin(UA_Server *server, UA_UInt16* ns) {
89075UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89076UA_ObjectAttributes attr = UA_ObjectAttributes_default;
89077attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerCapabilities");
89078retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
89079requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2268LU),
89080parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU),
89081referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
89082browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerCapabilities"),
89083typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2013LU),
89084attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
89085if (retVal != UA_STATUSCODE_GOOD) return retVal;
89086return retVal;
89087}
89088
89089static UA_StatusCode function_namespace0_generated_722_finish(UA_Server *server, UA_UInt16* ns) {
89090return UA_Server_addNode_finish(server,
89091nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2268LU)
89092);
89093}
89094
89095/* SoftwareCertificates - ns=0;i=3704 */
89096
89097static UA_StatusCode function_namespace0_generated_723_begin(UA_Server *server, UA_UInt16* ns) {
89098UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89099UA_VariableAttributes attr = UA_VariableAttributes_default;
89100attr.minimumSamplingInterval = 0.000000;
89101attr.userAccessLevel = 1;
89102attr.accessLevel = 1;
89103attr.valueRank = 1;
89104attr.arrayDimensionsSize = 1;
89105UA_UInt32 arrayDimensions[1];
89106arrayDimensions[0] = 0;
89107attr.arrayDimensions = &arrayDimensions[0];
89108attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 344LU);
89109attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SoftwareCertificates");
89110retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89111requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3704LU),
89112parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2268LU),
89113referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89114browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SoftwareCertificates"),
89115typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89116attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89117if (retVal != UA_STATUSCODE_GOOD) return retVal;
89118return retVal;
89119}
89120
89121static UA_StatusCode function_namespace0_generated_723_finish(UA_Server *server, UA_UInt16* ns) {
89122return UA_Server_addNode_finish(server,
89123nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3704LU)
89124);
89125}
89126
89127/* AggregateFunctions - ns=0;i=2997 */
89128
89129static UA_StatusCode function_namespace0_generated_724_begin(UA_Server *server, UA_UInt16* ns) {
89130UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89131UA_ObjectAttributes attr = UA_ObjectAttributes_default;
89132attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AggregateFunctions");
89133retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
89134requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2997LU),
89135parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2268LU),
89136referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
89137browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AggregateFunctions"),
89138typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 61LU),
89139attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
89140if (retVal != UA_STATUSCODE_GOOD) return retVal;
89141return retVal;
89142}
89143
89144static UA_StatusCode function_namespace0_generated_724_finish(UA_Server *server, UA_UInt16* ns) {
89145return UA_Server_addNode_finish(server,
89146nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2997LU)
89147);
89148}
89149
89150/* ModellingRules - ns=0;i=2996 */
89151
89152static UA_StatusCode function_namespace0_generated_725_begin(UA_Server *server, UA_UInt16* ns) {
89153UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89154UA_ObjectAttributes attr = UA_ObjectAttributes_default;
89155attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ModellingRules");
89156retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
89157requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2996LU),
89158parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2268LU),
89159referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
89160browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ModellingRules"),
89161typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 61LU),
89162attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
89163if (retVal != UA_STATUSCODE_GOOD) return retVal;
89164return retVal;
89165}
89166
89167static UA_StatusCode function_namespace0_generated_725_finish(UA_Server *server, UA_UInt16* ns) {
89168return UA_Server_addNode_finish(server,
89169nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2996LU)
89170);
89171}
89172
89173/* MaxHistoryContinuationPoints - ns=0;i=2737 */
89174
89175static UA_StatusCode function_namespace0_generated_726_begin(UA_Server *server, UA_UInt16* ns) {
89176UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89177UA_VariableAttributes attr = UA_VariableAttributes_default;
89178attr.minimumSamplingInterval = 0.000000;
89179attr.userAccessLevel = 1;
89180attr.accessLevel = 1;
89181/* Value rank inherited */
89182attr.valueRank = -2;
89183attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
89184attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxHistoryContinuationPoints");
89185retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89186requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2737LU),
89187parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2268LU),
89188referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89189browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxHistoryContinuationPoints"),
89190typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89191attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89192if (retVal != UA_STATUSCODE_GOOD) return retVal;
89193return retVal;
89194}
89195
89196static UA_StatusCode function_namespace0_generated_726_finish(UA_Server *server, UA_UInt16* ns) {
89197return UA_Server_addNode_finish(server,
89198nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2737LU)
89199);
89200}
89201
89202/* MaxQueryContinuationPoints - ns=0;i=2736 */
89203
89204static UA_StatusCode function_namespace0_generated_727_begin(UA_Server *server, UA_UInt16* ns) {
89205UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89206UA_VariableAttributes attr = UA_VariableAttributes_default;
89207attr.minimumSamplingInterval = 0.000000;
89208attr.userAccessLevel = 1;
89209attr.accessLevel = 1;
89210/* Value rank inherited */
89211attr.valueRank = -2;
89212attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
89213attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxQueryContinuationPoints");
89214retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89215requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2736LU),
89216parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2268LU),
89217referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89218browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxQueryContinuationPoints"),
89219typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89220attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89221if (retVal != UA_STATUSCODE_GOOD) return retVal;
89222return retVal;
89223}
89224
89225static UA_StatusCode function_namespace0_generated_727_finish(UA_Server *server, UA_UInt16* ns) {
89226return UA_Server_addNode_finish(server,
89227nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2736LU)
89228);
89229}
89230
89231/* MaxBrowseContinuationPoints - ns=0;i=2735 */
89232
89233static UA_StatusCode function_namespace0_generated_728_begin(UA_Server *server, UA_UInt16* ns) {
89234UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89235UA_VariableAttributes attr = UA_VariableAttributes_default;
89236attr.minimumSamplingInterval = 0.000000;
89237attr.userAccessLevel = 1;
89238attr.accessLevel = 1;
89239/* Value rank inherited */
89240attr.valueRank = -2;
89241attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
89242attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxBrowseContinuationPoints");
89243retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89244requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2735LU),
89245parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2268LU),
89246referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89247browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxBrowseContinuationPoints"),
89248typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89249attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89250if (retVal != UA_STATUSCODE_GOOD) return retVal;
89251return retVal;
89252}
89253
89254static UA_StatusCode function_namespace0_generated_728_finish(UA_Server *server, UA_UInt16* ns) {
89255return UA_Server_addNode_finish(server,
89256nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2735LU)
89257);
89258}
89259
89260/* MinSupportedSampleRate - ns=0;i=2272 */
89261
89262static UA_StatusCode function_namespace0_generated_729_begin(UA_Server *server, UA_UInt16* ns) {
89263UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89264UA_VariableAttributes attr = UA_VariableAttributes_default;
89265attr.minimumSamplingInterval = 0.000000;
89266attr.userAccessLevel = 1;
89267attr.accessLevel = 1;
89268/* Value rank inherited */
89269attr.valueRank = -2;
89270attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 290LU);
89271attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MinSupportedSampleRate");
89272retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89273requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2272LU),
89274parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2268LU),
89275referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89276browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MinSupportedSampleRate"),
89277typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89278attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89279if (retVal != UA_STATUSCODE_GOOD) return retVal;
89280return retVal;
89281}
89282
89283static UA_StatusCode function_namespace0_generated_729_finish(UA_Server *server, UA_UInt16* ns) {
89284return UA_Server_addNode_finish(server,
89285nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2272LU)
89286);
89287}
89288
89289/* LocaleIdArray - ns=0;i=2271 */
89290
89291static UA_StatusCode function_namespace0_generated_730_begin(UA_Server *server, UA_UInt16* ns) {
89292UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89293UA_VariableAttributes attr = UA_VariableAttributes_default;
89294attr.minimumSamplingInterval = 0.000000;
89295attr.userAccessLevel = 1;
89296attr.accessLevel = 1;
89297attr.valueRank = 1;
89298attr.arrayDimensionsSize = 1;
89299UA_UInt32 arrayDimensions[1];
89300arrayDimensions[0] = 0;
89301attr.arrayDimensions = &arrayDimensions[0];
89302attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 295LU);
89303attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "LocaleIdArray");
89304retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89305requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2271LU),
89306parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2268LU),
89307referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89308browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "LocaleIdArray"),
89309typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89310attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89311if (retVal != UA_STATUSCODE_GOOD) return retVal;
89312return retVal;
89313}
89314
89315static UA_StatusCode function_namespace0_generated_730_finish(UA_Server *server, UA_UInt16* ns) {
89316return UA_Server_addNode_finish(server,
89317nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2271LU)
89318);
89319}
89320
89321/* ServerProfileArray - ns=0;i=2269 */
89322
89323static UA_StatusCode function_namespace0_generated_731_begin(UA_Server *server, UA_UInt16* ns) {
89324UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89325UA_VariableAttributes attr = UA_VariableAttributes_default;
89326attr.minimumSamplingInterval = 0.000000;
89327attr.userAccessLevel = 1;
89328attr.accessLevel = 1;
89329attr.valueRank = 1;
89330attr.arrayDimensionsSize = 1;
89331UA_UInt32 arrayDimensions[1];
89332arrayDimensions[0] = 0;
89333attr.arrayDimensions = &arrayDimensions[0];
89334attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
89335attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerProfileArray");
89336retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89337requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2269LU),
89338parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2268LU),
89339referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89340browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerProfileArray"),
89341typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89342attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89343if (retVal != UA_STATUSCODE_GOOD) return retVal;
89344return retVal;
89345}
89346
89347static UA_StatusCode function_namespace0_generated_731_finish(UA_Server *server, UA_UInt16* ns) {
89348return UA_Server_addNode_finish(server,
89349nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2269LU)
89350);
89351}
89352
89353/* OperationLimits - ns=0;i=11704 */
89354
89355static UA_StatusCode function_namespace0_generated_732_begin(UA_Server *server, UA_UInt16* ns) {
89356UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89357UA_ObjectAttributes attr = UA_ObjectAttributes_default;
89358attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OperationLimits");
89359retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
89360requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11704LU),
89361parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2268LU),
89362referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
89363browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OperationLimits"),
89364typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11564LU),
89365attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
89366if (retVal != UA_STATUSCODE_GOOD) return retVal;
89367return retVal;
89368}
89369
89370static UA_StatusCode function_namespace0_generated_732_finish(UA_Server *server, UA_UInt16* ns) {
89371return UA_Server_addNode_finish(server,
89372nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11704LU)
89373);
89374}
89375
89376/* MaxMonitoredItemsPerCall - ns=0;i=11714 */
89377
89378static UA_StatusCode function_namespace0_generated_733_begin(UA_Server *server, UA_UInt16* ns) {
89379UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89380UA_VariableAttributes attr = UA_VariableAttributes_default;
89381attr.minimumSamplingInterval = 0.000000;
89382attr.userAccessLevel = 1;
89383attr.accessLevel = 1;
89384/* Value rank inherited */
89385attr.valueRank = -2;
89386attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
89387attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxMonitoredItemsPerCall");
89388retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89389requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11714LU),
89390parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11704LU),
89391referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89392browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxMonitoredItemsPerCall"),
89393typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89394attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89395if (retVal != UA_STATUSCODE_GOOD) return retVal;
89396return retVal;
89397}
89398
89399static UA_StatusCode function_namespace0_generated_733_finish(UA_Server *server, UA_UInt16* ns) {
89400return UA_Server_addNode_finish(server,
89401nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11714LU)
89402);
89403}
89404
89405/* MaxNodesPerNodeManagement - ns=0;i=11713 */
89406
89407static UA_StatusCode function_namespace0_generated_734_begin(UA_Server *server, UA_UInt16* ns) {
89408UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89409UA_VariableAttributes attr = UA_VariableAttributes_default;
89410attr.minimumSamplingInterval = 0.000000;
89411attr.userAccessLevel = 1;
89412attr.accessLevel = 1;
89413/* Value rank inherited */
89414attr.valueRank = -2;
89415attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
89416attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerNodeManagement");
89417retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89418requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11713LU),
89419parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11704LU),
89420referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89421browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerNodeManagement"),
89422typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89423attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89424if (retVal != UA_STATUSCODE_GOOD) return retVal;
89425return retVal;
89426}
89427
89428static UA_StatusCode function_namespace0_generated_734_finish(UA_Server *server, UA_UInt16* ns) {
89429return UA_Server_addNode_finish(server,
89430nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11713LU)
89431);
89432}
89433
89434/* MaxNodesPerTranslateBrowsePathsToNodeIds - ns=0;i=11712 */
89435
89436static UA_StatusCode function_namespace0_generated_735_begin(UA_Server *server, UA_UInt16* ns) {
89437UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89438UA_VariableAttributes attr = UA_VariableAttributes_default;
89439attr.minimumSamplingInterval = 0.000000;
89440attr.userAccessLevel = 1;
89441attr.accessLevel = 1;
89442/* Value rank inherited */
89443attr.valueRank = -2;
89444attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
89445attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerTranslateBrowsePathsToNodeIds");
89446retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89447requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11712LU),
89448parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11704LU),
89449referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89450browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerTranslateBrowsePathsToNodeIds"),
89451typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89452attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89453if (retVal != UA_STATUSCODE_GOOD) return retVal;
89454return retVal;
89455}
89456
89457static UA_StatusCode function_namespace0_generated_735_finish(UA_Server *server, UA_UInt16* ns) {
89458return UA_Server_addNode_finish(server,
89459nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11712LU)
89460);
89461}
89462
89463/* MaxNodesPerRegisterNodes - ns=0;i=11711 */
89464
89465static UA_StatusCode function_namespace0_generated_736_begin(UA_Server *server, UA_UInt16* ns) {
89466UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89467UA_VariableAttributes attr = UA_VariableAttributes_default;
89468attr.minimumSamplingInterval = 0.000000;
89469attr.userAccessLevel = 1;
89470attr.accessLevel = 1;
89471/* Value rank inherited */
89472attr.valueRank = -2;
89473attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
89474attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerRegisterNodes");
89475retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89476requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11711LU),
89477parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11704LU),
89478referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89479browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerRegisterNodes"),
89480typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89481attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89482if (retVal != UA_STATUSCODE_GOOD) return retVal;
89483return retVal;
89484}
89485
89486static UA_StatusCode function_namespace0_generated_736_finish(UA_Server *server, UA_UInt16* ns) {
89487return UA_Server_addNode_finish(server,
89488nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11711LU)
89489);
89490}
89491
89492/* MaxNodesPerBrowse - ns=0;i=11710 */
89493
89494static UA_StatusCode function_namespace0_generated_737_begin(UA_Server *server, UA_UInt16* ns) {
89495UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89496UA_VariableAttributes attr = UA_VariableAttributes_default;
89497attr.minimumSamplingInterval = 0.000000;
89498attr.userAccessLevel = 1;
89499attr.accessLevel = 1;
89500/* Value rank inherited */
89501attr.valueRank = -2;
89502attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
89503attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerBrowse");
89504retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89505requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11710LU),
89506parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11704LU),
89507referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89508browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerBrowse"),
89509typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89510attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89511if (retVal != UA_STATUSCODE_GOOD) return retVal;
89512return retVal;
89513}
89514
89515static UA_StatusCode function_namespace0_generated_737_finish(UA_Server *server, UA_UInt16* ns) {
89516return UA_Server_addNode_finish(server,
89517nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11710LU)
89518);
89519}
89520
89521/* MaxNodesPerMethodCall - ns=0;i=11709 */
89522
89523static UA_StatusCode function_namespace0_generated_738_begin(UA_Server *server, UA_UInt16* ns) {
89524UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89525UA_VariableAttributes attr = UA_VariableAttributes_default;
89526attr.minimumSamplingInterval = 0.000000;
89527attr.userAccessLevel = 1;
89528attr.accessLevel = 1;
89529/* Value rank inherited */
89530attr.valueRank = -2;
89531attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
89532attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerMethodCall");
89533retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89534requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11709LU),
89535parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11704LU),
89536referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89537browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerMethodCall"),
89538typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89539attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89540if (retVal != UA_STATUSCODE_GOOD) return retVal;
89541return retVal;
89542}
89543
89544static UA_StatusCode function_namespace0_generated_738_finish(UA_Server *server, UA_UInt16* ns) {
89545return UA_Server_addNode_finish(server,
89546nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11709LU)
89547);
89548}
89549
89550/* MaxNodesPerWrite - ns=0;i=11707 */
89551
89552static UA_StatusCode function_namespace0_generated_739_begin(UA_Server *server, UA_UInt16* ns) {
89553UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89554UA_VariableAttributes attr = UA_VariableAttributes_default;
89555attr.minimumSamplingInterval = 0.000000;
89556attr.userAccessLevel = 1;
89557attr.accessLevel = 1;
89558/* Value rank inherited */
89559attr.valueRank = -2;
89560attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
89561attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerWrite");
89562retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89563requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11707LU),
89564parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11704LU),
89565referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89566browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerWrite"),
89567typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89568attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89569if (retVal != UA_STATUSCODE_GOOD) return retVal;
89570return retVal;
89571}
89572
89573static UA_StatusCode function_namespace0_generated_739_finish(UA_Server *server, UA_UInt16* ns) {
89574return UA_Server_addNode_finish(server,
89575nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11707LU)
89576);
89577}
89578
89579/* MaxNodesPerRead - ns=0;i=11705 */
89580
89581static UA_StatusCode function_namespace0_generated_740_begin(UA_Server *server, UA_UInt16* ns) {
89582UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89583UA_VariableAttributes attr = UA_VariableAttributes_default;
89584attr.minimumSamplingInterval = 0.000000;
89585attr.userAccessLevel = 1;
89586attr.accessLevel = 1;
89587/* Value rank inherited */
89588attr.valueRank = -2;
89589attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
89590attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxNodesPerRead");
89591retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89592requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11705LU),
89593parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11704LU),
89594referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89595browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxNodesPerRead"),
89596typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89597attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89598if (retVal != UA_STATUSCODE_GOOD) return retVal;
89599return retVal;
89600}
89601
89602static UA_StatusCode function_namespace0_generated_740_finish(UA_Server *server, UA_UInt16* ns) {
89603return UA_Server_addNode_finish(server,
89604nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11705LU)
89605);
89606}
89607
89608/* HistoryServerCapabilities - ns=0;i=11192 */
89609
89610static UA_StatusCode function_namespace0_generated_741_begin(UA_Server *server, UA_UInt16* ns) {
89611UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89612UA_ObjectAttributes attr = UA_ObjectAttributes_default;
89613attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "HistoryServerCapabilities");
89614retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
89615requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89616parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2268LU),
89617referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
89618browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "HistoryServerCapabilities"),
89619typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2330LU),
89620attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
89621if (retVal != UA_STATUSCODE_GOOD) return retVal;
89622return retVal;
89623}
89624
89625static UA_StatusCode function_namespace0_generated_741_finish(UA_Server *server, UA_UInt16* ns) {
89626return UA_Server_addNode_finish(server,
89627nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU)
89628);
89629}
89630
89631/* DeleteEventCapability - ns=0;i=11502 */
89632
89633static UA_StatusCode function_namespace0_generated_742_begin(UA_Server *server, UA_UInt16* ns) {
89634UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89635UA_VariableAttributes attr = UA_VariableAttributes_default;
89636attr.minimumSamplingInterval = 0.000000;
89637attr.userAccessLevel = 1;
89638attr.accessLevel = 1;
89639/* Value rank inherited */
89640attr.valueRank = -2;
89641attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
89642attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteEventCapability");
89643retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89644requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11502LU),
89645parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89646referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89647browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteEventCapability"),
89648typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89649attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89650if (retVal != UA_STATUSCODE_GOOD) return retVal;
89651return retVal;
89652}
89653
89654static UA_StatusCode function_namespace0_generated_742_finish(UA_Server *server, UA_UInt16* ns) {
89655return UA_Server_addNode_finish(server,
89656nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11502LU)
89657);
89658}
89659
89660/* UpdateEventCapability - ns=0;i=11283 */
89661
89662static UA_StatusCode function_namespace0_generated_743_begin(UA_Server *server, UA_UInt16* ns) {
89663UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89664UA_VariableAttributes attr = UA_VariableAttributes_default;
89665attr.minimumSamplingInterval = 0.000000;
89666attr.userAccessLevel = 1;
89667attr.accessLevel = 1;
89668/* Value rank inherited */
89669attr.valueRank = -2;
89670attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
89671attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UpdateEventCapability");
89672retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89673requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11283LU),
89674parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89675referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89676browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UpdateEventCapability"),
89677typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89678attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89679if (retVal != UA_STATUSCODE_GOOD) return retVal;
89680return retVal;
89681}
89682
89683static UA_StatusCode function_namespace0_generated_743_finish(UA_Server *server, UA_UInt16* ns) {
89684return UA_Server_addNode_finish(server,
89685nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11283LU)
89686);
89687}
89688
89689/* ReplaceEventCapability - ns=0;i=11282 */
89690
89691static UA_StatusCode function_namespace0_generated_744_begin(UA_Server *server, UA_UInt16* ns) {
89692UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89693UA_VariableAttributes attr = UA_VariableAttributes_default;
89694attr.minimumSamplingInterval = 0.000000;
89695attr.userAccessLevel = 1;
89696attr.accessLevel = 1;
89697/* Value rank inherited */
89698attr.valueRank = -2;
89699attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
89700attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ReplaceEventCapability");
89701retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89702requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11282LU),
89703parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89704referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89705browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ReplaceEventCapability"),
89706typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89707attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89708if (retVal != UA_STATUSCODE_GOOD) return retVal;
89709return retVal;
89710}
89711
89712static UA_StatusCode function_namespace0_generated_744_finish(UA_Server *server, UA_UInt16* ns) {
89713return UA_Server_addNode_finish(server,
89714nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11282LU)
89715);
89716}
89717
89718/* InsertEventCapability - ns=0;i=11281 */
89719
89720static UA_StatusCode function_namespace0_generated_745_begin(UA_Server *server, UA_UInt16* ns) {
89721UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89722UA_VariableAttributes attr = UA_VariableAttributes_default;
89723attr.minimumSamplingInterval = 0.000000;
89724attr.userAccessLevel = 1;
89725attr.accessLevel = 1;
89726/* Value rank inherited */
89727attr.valueRank = -2;
89728attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
89729attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InsertEventCapability");
89730retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89731requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11281LU),
89732parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89733referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89734browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InsertEventCapability"),
89735typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89736attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89737if (retVal != UA_STATUSCODE_GOOD) return retVal;
89738return retVal;
89739}
89740
89741static UA_StatusCode function_namespace0_generated_745_finish(UA_Server *server, UA_UInt16* ns) {
89742return UA_Server_addNode_finish(server,
89743nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11281LU)
89744);
89745}
89746
89747/* InsertAnnotationCapability - ns=0;i=11275 */
89748
89749static UA_StatusCode function_namespace0_generated_746_begin(UA_Server *server, UA_UInt16* ns) {
89750UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89751UA_VariableAttributes attr = UA_VariableAttributes_default;
89752attr.minimumSamplingInterval = 0.000000;
89753attr.userAccessLevel = 1;
89754attr.accessLevel = 1;
89755/* Value rank inherited */
89756attr.valueRank = -2;
89757attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
89758attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InsertAnnotationCapability");
89759retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89760requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11275LU),
89761parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89762referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89763browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InsertAnnotationCapability"),
89764typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89765attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89766if (retVal != UA_STATUSCODE_GOOD) return retVal;
89767return retVal;
89768}
89769
89770static UA_StatusCode function_namespace0_generated_746_finish(UA_Server *server, UA_UInt16* ns) {
89771return UA_Server_addNode_finish(server,
89772nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11275LU)
89773);
89774}
89775
89776/* MaxReturnEventValues - ns=0;i=11274 */
89777
89778static UA_StatusCode function_namespace0_generated_747_begin(UA_Server *server, UA_UInt16* ns) {
89779UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89780UA_VariableAttributes attr = UA_VariableAttributes_default;
89781attr.minimumSamplingInterval = 0.000000;
89782attr.userAccessLevel = 1;
89783attr.accessLevel = 1;
89784/* Value rank inherited */
89785attr.valueRank = -2;
89786attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
89787attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxReturnEventValues");
89788retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89789requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11274LU),
89790parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89791referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89792browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxReturnEventValues"),
89793typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89794attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89795if (retVal != UA_STATUSCODE_GOOD) return retVal;
89796return retVal;
89797}
89798
89799static UA_StatusCode function_namespace0_generated_747_finish(UA_Server *server, UA_UInt16* ns) {
89800return UA_Server_addNode_finish(server,
89801nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11274LU)
89802);
89803}
89804
89805/* MaxReturnDataValues - ns=0;i=11273 */
89806
89807static UA_StatusCode function_namespace0_generated_748_begin(UA_Server *server, UA_UInt16* ns) {
89808UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89809UA_VariableAttributes attr = UA_VariableAttributes_default;
89810attr.minimumSamplingInterval = 0.000000;
89811attr.userAccessLevel = 1;
89812attr.accessLevel = 1;
89813/* Value rank inherited */
89814attr.valueRank = -2;
89815attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
89816attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MaxReturnDataValues");
89817retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89818requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11273LU),
89819parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89820referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89821browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MaxReturnDataValues"),
89822typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89823attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89824if (retVal != UA_STATUSCODE_GOOD) return retVal;
89825return retVal;
89826}
89827
89828static UA_StatusCode function_namespace0_generated_748_finish(UA_Server *server, UA_UInt16* ns) {
89829return UA_Server_addNode_finish(server,
89830nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11273LU)
89831);
89832}
89833
89834/* AccessHistoryEventsCapability - ns=0;i=11242 */
89835
89836static UA_StatusCode function_namespace0_generated_749_begin(UA_Server *server, UA_UInt16* ns) {
89837UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89838UA_VariableAttributes attr = UA_VariableAttributes_default;
89839attr.minimumSamplingInterval = 0.000000;
89840attr.userAccessLevel = 1;
89841attr.accessLevel = 1;
89842/* Value rank inherited */
89843attr.valueRank = -2;
89844attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
89845attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AccessHistoryEventsCapability");
89846retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89847requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11242LU),
89848parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89849referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89850browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AccessHistoryEventsCapability"),
89851typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89852attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89853if (retVal != UA_STATUSCODE_GOOD) return retVal;
89854return retVal;
89855}
89856
89857static UA_StatusCode function_namespace0_generated_749_finish(UA_Server *server, UA_UInt16* ns) {
89858return UA_Server_addNode_finish(server,
89859nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11242LU)
89860);
89861}
89862
89863/* AggregateFunctions - ns=0;i=11201 */
89864
89865static UA_StatusCode function_namespace0_generated_750_begin(UA_Server *server, UA_UInt16* ns) {
89866UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89867UA_ObjectAttributes attr = UA_ObjectAttributes_default;
89868attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AggregateFunctions");
89869retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
89870requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11201LU),
89871parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89872referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
89873browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AggregateFunctions"),
89874typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 61LU),
89875attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
89876if (retVal != UA_STATUSCODE_GOOD) return retVal;
89877return retVal;
89878}
89879
89880static UA_StatusCode function_namespace0_generated_750_finish(UA_Server *server, UA_UInt16* ns) {
89881return UA_Server_addNode_finish(server,
89882nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11201LU)
89883);
89884}
89885
89886/* DeleteAtTimeCapability - ns=0;i=11200 */
89887
89888static UA_StatusCode function_namespace0_generated_751_begin(UA_Server *server, UA_UInt16* ns) {
89889UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89890UA_VariableAttributes attr = UA_VariableAttributes_default;
89891attr.minimumSamplingInterval = 0.000000;
89892attr.userAccessLevel = 1;
89893attr.accessLevel = 1;
89894/* Value rank inherited */
89895attr.valueRank = -2;
89896attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
89897attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteAtTimeCapability");
89898retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89899requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11200LU),
89900parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89901referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89902browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteAtTimeCapability"),
89903typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89904attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89905if (retVal != UA_STATUSCODE_GOOD) return retVal;
89906return retVal;
89907}
89908
89909static UA_StatusCode function_namespace0_generated_751_finish(UA_Server *server, UA_UInt16* ns) {
89910return UA_Server_addNode_finish(server,
89911nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11200LU)
89912);
89913}
89914
89915/* DeleteRawCapability - ns=0;i=11199 */
89916
89917static UA_StatusCode function_namespace0_generated_752_begin(UA_Server *server, UA_UInt16* ns) {
89918UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89919UA_VariableAttributes attr = UA_VariableAttributes_default;
89920attr.minimumSamplingInterval = 0.000000;
89921attr.userAccessLevel = 1;
89922attr.accessLevel = 1;
89923/* Value rank inherited */
89924attr.valueRank = -2;
89925attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
89926attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DeleteRawCapability");
89927retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89928requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11199LU),
89929parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89930referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89931browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DeleteRawCapability"),
89932typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89933attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89934if (retVal != UA_STATUSCODE_GOOD) return retVal;
89935return retVal;
89936}
89937
89938static UA_StatusCode function_namespace0_generated_752_finish(UA_Server *server, UA_UInt16* ns) {
89939return UA_Server_addNode_finish(server,
89940nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11199LU)
89941);
89942}
89943
89944/* UpdateDataCapability - ns=0;i=11198 */
89945
89946static UA_StatusCode function_namespace0_generated_753_begin(UA_Server *server, UA_UInt16* ns) {
89947UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89948UA_VariableAttributes attr = UA_VariableAttributes_default;
89949attr.minimumSamplingInterval = 0.000000;
89950attr.userAccessLevel = 1;
89951attr.accessLevel = 1;
89952/* Value rank inherited */
89953attr.valueRank = -2;
89954attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
89955attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "UpdateDataCapability");
89956retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89957requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11198LU),
89958parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89959referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89960browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "UpdateDataCapability"),
89961typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89962attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89963if (retVal != UA_STATUSCODE_GOOD) return retVal;
89964return retVal;
89965}
89966
89967static UA_StatusCode function_namespace0_generated_753_finish(UA_Server *server, UA_UInt16* ns) {
89968return UA_Server_addNode_finish(server,
89969nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11198LU)
89970);
89971}
89972
89973/* ReplaceDataCapability - ns=0;i=11197 */
89974
89975static UA_StatusCode function_namespace0_generated_754_begin(UA_Server *server, UA_UInt16* ns) {
89976UA_StatusCode retVal = UA_STATUSCODE_GOOD;
89977UA_VariableAttributes attr = UA_VariableAttributes_default;
89978attr.minimumSamplingInterval = 0.000000;
89979attr.userAccessLevel = 1;
89980attr.accessLevel = 1;
89981/* Value rank inherited */
89982attr.valueRank = -2;
89983attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
89984attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ReplaceDataCapability");
89985retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
89986requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11197LU),
89987parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
89988referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
89989browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ReplaceDataCapability"),
89990typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
89991attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
89992if (retVal != UA_STATUSCODE_GOOD) return retVal;
89993return retVal;
89994}
89995
89996static UA_StatusCode function_namespace0_generated_754_finish(UA_Server *server, UA_UInt16* ns) {
89997return UA_Server_addNode_finish(server,
89998nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11197LU)
89999);
90000}
90001
90002/* InsertDataCapability - ns=0;i=11196 */
90003
90004static UA_StatusCode function_namespace0_generated_755_begin(UA_Server *server, UA_UInt16* ns) {
90005UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90006UA_VariableAttributes attr = UA_VariableAttributes_default;
90007attr.minimumSamplingInterval = 0.000000;
90008attr.userAccessLevel = 1;
90009attr.accessLevel = 1;
90010/* Value rank inherited */
90011attr.valueRank = -2;
90012attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
90013attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InsertDataCapability");
90014retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90015requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11196LU),
90016parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
90017referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
90018browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InsertDataCapability"),
90019typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
90020attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90021if (retVal != UA_STATUSCODE_GOOD) return retVal;
90022return retVal;
90023}
90024
90025static UA_StatusCode function_namespace0_generated_755_finish(UA_Server *server, UA_UInt16* ns) {
90026return UA_Server_addNode_finish(server,
90027nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11196LU)
90028);
90029}
90030
90031/* AccessHistoryDataCapability - ns=0;i=11193 */
90032
90033static UA_StatusCode function_namespace0_generated_756_begin(UA_Server *server, UA_UInt16* ns) {
90034UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90035UA_VariableAttributes attr = UA_VariableAttributes_default;
90036attr.minimumSamplingInterval = 0.000000;
90037attr.userAccessLevel = 1;
90038attr.accessLevel = 1;
90039/* Value rank inherited */
90040attr.valueRank = -2;
90041attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 1LU);
90042attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AccessHistoryDataCapability");
90043retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90044requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11193LU),
90045parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11192LU),
90046referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
90047browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AccessHistoryDataCapability"),
90048typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
90049attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90050if (retVal != UA_STATUSCODE_GOOD) return retVal;
90051return retVal;
90052}
90053
90054static UA_StatusCode function_namespace0_generated_756_finish(UA_Server *server, UA_UInt16* ns) {
90055return UA_Server_addNode_finish(server,
90056nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11193LU)
90057);
90058}
90059
90060/* ServiceLevel - ns=0;i=2267 */
90061
90062static UA_StatusCode function_namespace0_generated_757_begin(UA_Server *server, UA_UInt16* ns) {
90063UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90064UA_VariableAttributes attr = UA_VariableAttributes_default;
90065attr.minimumSamplingInterval = 1000.000000;
90066attr.userAccessLevel = 1;
90067attr.accessLevel = 1;
90068/* Value rank inherited */
90069attr.valueRank = -2;
90070attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3LU);
90071attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServiceLevel");
90072retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90073requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2267LU),
90074parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU),
90075referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
90076browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServiceLevel"),
90077typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
90078attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90079if (retVal != UA_STATUSCODE_GOOD) return retVal;
90080return retVal;
90081}
90082
90083static UA_StatusCode function_namespace0_generated_757_finish(UA_Server *server, UA_UInt16* ns) {
90084return UA_Server_addNode_finish(server,
90085nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2267LU)
90086);
90087}
90088
90089/* ServerStatus - ns=0;i=2256 */
90090
90091static UA_StatusCode function_namespace0_generated_758_begin(UA_Server *server, UA_UInt16* ns) {
90092UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90093UA_VariableAttributes attr = UA_VariableAttributes_default;
90094attr.minimumSamplingInterval = 1000.000000;
90095attr.userAccessLevel = 1;
90096attr.accessLevel = 1;
90097/* Value rank inherited */
90098attr.valueRank = -2;
90099attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 862LU);
90100attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerStatus");
90101retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90102requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2256LU),
90103parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU),
90104referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90105browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerStatus"),
90106typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2138LU),
90107attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90108if (retVal != UA_STATUSCODE_GOOD) return retVal;
90109return retVal;
90110}
90111
90112static UA_StatusCode function_namespace0_generated_758_finish(UA_Server *server, UA_UInt16* ns) {
90113return UA_Server_addNode_finish(server,
90114nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2256LU)
90115);
90116}
90117
90118/* ShutdownReason - ns=0;i=2993 */
90119
90120static UA_StatusCode function_namespace0_generated_759_begin(UA_Server *server, UA_UInt16* ns) {
90121UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90122UA_VariableAttributes attr = UA_VariableAttributes_default;
90123attr.minimumSamplingInterval = 0.000000;
90124attr.userAccessLevel = 1;
90125attr.accessLevel = 1;
90126/* Value rank inherited */
90127attr.valueRank = -2;
90128attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 21LU);
90129attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ShutdownReason");
90130retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90131requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2993LU),
90132parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2256LU),
90133referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90134browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ShutdownReason"),
90135typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
90136attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90137if (retVal != UA_STATUSCODE_GOOD) return retVal;
90138return retVal;
90139}
90140
90141static UA_StatusCode function_namespace0_generated_759_finish(UA_Server *server, UA_UInt16* ns) {
90142return UA_Server_addNode_finish(server,
90143nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2993LU)
90144);
90145}
90146
90147/* SecondsTillShutdown - ns=0;i=2992 */
90148
90149static UA_StatusCode function_namespace0_generated_760_begin(UA_Server *server, UA_UInt16* ns) {
90150UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90151UA_VariableAttributes attr = UA_VariableAttributes_default;
90152attr.minimumSamplingInterval = 0.000000;
90153attr.userAccessLevel = 1;
90154attr.accessLevel = 1;
90155/* Value rank inherited */
90156attr.valueRank = -2;
90157attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
90158attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SecondsTillShutdown");
90159retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90160requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2992LU),
90161parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2256LU),
90162referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90163browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SecondsTillShutdown"),
90164typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
90165attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90166if (retVal != UA_STATUSCODE_GOOD) return retVal;
90167return retVal;
90168}
90169
90170static UA_StatusCode function_namespace0_generated_760_finish(UA_Server *server, UA_UInt16* ns) {
90171return UA_Server_addNode_finish(server,
90172nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2992LU)
90173);
90174}
90175
90176/* BuildInfo - ns=0;i=2260 */
90177
90178static UA_StatusCode function_namespace0_generated_761_begin(UA_Server *server, UA_UInt16* ns) {
90179UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90180UA_VariableAttributes attr = UA_VariableAttributes_default;
90181attr.minimumSamplingInterval = 0.000000;
90182attr.userAccessLevel = 1;
90183attr.accessLevel = 1;
90184/* Value rank inherited */
90185attr.valueRank = -2;
90186attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 338LU);
90187attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BuildInfo");
90188retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90189requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2260LU),
90190parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2256LU),
90191referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90192browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BuildInfo"),
90193typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3051LU),
90194attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90195if (retVal != UA_STATUSCODE_GOOD) return retVal;
90196return retVal;
90197}
90198
90199static UA_StatusCode function_namespace0_generated_761_finish(UA_Server *server, UA_UInt16* ns) {
90200return UA_Server_addNode_finish(server,
90201nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2260LU)
90202);
90203}
90204
90205/* BuildDate - ns=0;i=2266 */
90206
90207static UA_StatusCode function_namespace0_generated_762_begin(UA_Server *server, UA_UInt16* ns) {
90208UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90209UA_VariableAttributes attr = UA_VariableAttributes_default;
90210attr.minimumSamplingInterval = 1000.000000;
90211attr.userAccessLevel = 1;
90212attr.accessLevel = 1;
90213/* Value rank inherited */
90214attr.valueRank = -2;
90215attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
90216attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BuildDate");
90217retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90218requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2266LU),
90219parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2260LU),
90220referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90221browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BuildDate"),
90222typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
90223attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90224if (retVal != UA_STATUSCODE_GOOD) return retVal;
90225return retVal;
90226}
90227
90228static UA_StatusCode function_namespace0_generated_762_finish(UA_Server *server, UA_UInt16* ns) {
90229return UA_Server_addNode_finish(server,
90230nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2266LU)
90231);
90232}
90233
90234/* BuildNumber - ns=0;i=2265 */
90235
90236static UA_StatusCode function_namespace0_generated_763_begin(UA_Server *server, UA_UInt16* ns) {
90237UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90238UA_VariableAttributes attr = UA_VariableAttributes_default;
90239attr.minimumSamplingInterval = 1000.000000;
90240attr.userAccessLevel = 1;
90241attr.accessLevel = 1;
90242/* Value rank inherited */
90243attr.valueRank = -2;
90244attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
90245attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "BuildNumber");
90246retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90247requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2265LU),
90248parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2260LU),
90249referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90250browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "BuildNumber"),
90251typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
90252attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90253if (retVal != UA_STATUSCODE_GOOD) return retVal;
90254return retVal;
90255}
90256
90257static UA_StatusCode function_namespace0_generated_763_finish(UA_Server *server, UA_UInt16* ns) {
90258return UA_Server_addNode_finish(server,
90259nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2265LU)
90260);
90261}
90262
90263/* SoftwareVersion - ns=0;i=2264 */
90264
90265static UA_StatusCode function_namespace0_generated_764_begin(UA_Server *server, UA_UInt16* ns) {
90266UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90267UA_VariableAttributes attr = UA_VariableAttributes_default;
90268attr.minimumSamplingInterval = 1000.000000;
90269attr.userAccessLevel = 1;
90270attr.accessLevel = 1;
90271/* Value rank inherited */
90272attr.valueRank = -2;
90273attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
90274attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SoftwareVersion");
90275retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90276requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2264LU),
90277parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2260LU),
90278referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90279browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SoftwareVersion"),
90280typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
90281attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90282if (retVal != UA_STATUSCODE_GOOD) return retVal;
90283return retVal;
90284}
90285
90286static UA_StatusCode function_namespace0_generated_764_finish(UA_Server *server, UA_UInt16* ns) {
90287return UA_Server_addNode_finish(server,
90288nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2264LU)
90289);
90290}
90291
90292/* ManufacturerName - ns=0;i=2263 */
90293
90294static UA_StatusCode function_namespace0_generated_765_begin(UA_Server *server, UA_UInt16* ns) {
90295UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90296UA_VariableAttributes attr = UA_VariableAttributes_default;
90297attr.minimumSamplingInterval = 1000.000000;
90298attr.userAccessLevel = 1;
90299attr.accessLevel = 1;
90300/* Value rank inherited */
90301attr.valueRank = -2;
90302attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
90303attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ManufacturerName");
90304retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90305requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2263LU),
90306parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2260LU),
90307referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90308browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ManufacturerName"),
90309typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
90310attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90311if (retVal != UA_STATUSCODE_GOOD) return retVal;
90312return retVal;
90313}
90314
90315static UA_StatusCode function_namespace0_generated_765_finish(UA_Server *server, UA_UInt16* ns) {
90316return UA_Server_addNode_finish(server,
90317nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2263LU)
90318);
90319}
90320
90321/* ProductUri - ns=0;i=2262 */
90322
90323static UA_StatusCode function_namespace0_generated_766_begin(UA_Server *server, UA_UInt16* ns) {
90324UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90325UA_VariableAttributes attr = UA_VariableAttributes_default;
90326attr.minimumSamplingInterval = 1000.000000;
90327attr.userAccessLevel = 1;
90328attr.accessLevel = 1;
90329/* Value rank inherited */
90330attr.valueRank = -2;
90331attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
90332attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ProductUri");
90333retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90334requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2262LU),
90335parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2260LU),
90336referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90337browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ProductUri"),
90338typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
90339attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90340if (retVal != UA_STATUSCODE_GOOD) return retVal;
90341return retVal;
90342}
90343
90344static UA_StatusCode function_namespace0_generated_766_finish(UA_Server *server, UA_UInt16* ns) {
90345return UA_Server_addNode_finish(server,
90346nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2262LU)
90347);
90348}
90349
90350/* ProductName - ns=0;i=2261 */
90351
90352static UA_StatusCode function_namespace0_generated_767_begin(UA_Server *server, UA_UInt16* ns) {
90353UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90354UA_VariableAttributes attr = UA_VariableAttributes_default;
90355attr.minimumSamplingInterval = 1000.000000;
90356attr.userAccessLevel = 1;
90357attr.accessLevel = 1;
90358/* Value rank inherited */
90359attr.valueRank = -2;
90360attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
90361attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ProductName");
90362retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90363requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2261LU),
90364parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2260LU),
90365referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90366browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ProductName"),
90367typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
90368attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90369if (retVal != UA_STATUSCODE_GOOD) return retVal;
90370return retVal;
90371}
90372
90373static UA_StatusCode function_namespace0_generated_767_finish(UA_Server *server, UA_UInt16* ns) {
90374return UA_Server_addNode_finish(server,
90375nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2261LU)
90376);
90377}
90378
90379/* State - ns=0;i=2259 */
90380
90381static UA_StatusCode function_namespace0_generated_768_begin(UA_Server *server, UA_UInt16* ns) {
90382UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90383UA_VariableAttributes attr = UA_VariableAttributes_default;
90384attr.minimumSamplingInterval = 0.000000;
90385attr.userAccessLevel = 1;
90386attr.accessLevel = 1;
90387/* Value rank inherited */
90388attr.valueRank = -2;
90389attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 852LU);
90390attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "State");
90391retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90392requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2259LU),
90393parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2256LU),
90394referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90395browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "State"),
90396typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
90397attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90398if (retVal != UA_STATUSCODE_GOOD) return retVal;
90399return retVal;
90400}
90401
90402static UA_StatusCode function_namespace0_generated_768_finish(UA_Server *server, UA_UInt16* ns) {
90403return UA_Server_addNode_finish(server,
90404nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2259LU)
90405);
90406}
90407
90408/* CurrentTime - ns=0;i=2258 */
90409
90410static UA_StatusCode function_namespace0_generated_769_begin(UA_Server *server, UA_UInt16* ns) {
90411UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90412UA_VariableAttributes attr = UA_VariableAttributes_default;
90413attr.minimumSamplingInterval = 0.000000;
90414attr.userAccessLevel = 1;
90415attr.accessLevel = 1;
90416/* Value rank inherited */
90417attr.valueRank = -2;
90418attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
90419attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "CurrentTime");
90420retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90421requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2258LU),
90422parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2256LU),
90423referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90424browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "CurrentTime"),
90425typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
90426attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90427if (retVal != UA_STATUSCODE_GOOD) return retVal;
90428return retVal;
90429}
90430
90431static UA_StatusCode function_namespace0_generated_769_finish(UA_Server *server, UA_UInt16* ns) {
90432return UA_Server_addNode_finish(server,
90433nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2258LU)
90434);
90435}
90436
90437/* StartTime - ns=0;i=2257 */
90438
90439static UA_StatusCode function_namespace0_generated_770_begin(UA_Server *server, UA_UInt16* ns) {
90440UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90441UA_VariableAttributes attr = UA_VariableAttributes_default;
90442attr.minimumSamplingInterval = 0.000000;
90443attr.userAccessLevel = 1;
90444attr.accessLevel = 1;
90445/* Value rank inherited */
90446attr.valueRank = -2;
90447attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 294LU);
90448attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "StartTime");
90449retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90450requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2257LU),
90451parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2256LU),
90452referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90453browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "StartTime"),
90454typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
90455attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90456if (retVal != UA_STATUSCODE_GOOD) return retVal;
90457return retVal;
90458}
90459
90460static UA_StatusCode function_namespace0_generated_770_finish(UA_Server *server, UA_UInt16* ns) {
90461return UA_Server_addNode_finish(server,
90462nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2257LU)
90463);
90464}
90465
90466/* NamespaceArray - ns=0;i=2255 */
90467
90468static UA_StatusCode function_namespace0_generated_771_begin(UA_Server *server, UA_UInt16* ns) {
90469UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90470UA_VariableAttributes attr = UA_VariableAttributes_default;
90471attr.minimumSamplingInterval = 1000.000000;
90472attr.userAccessLevel = 1;
90473attr.accessLevel = 1;
90474attr.valueRank = 1;
90475attr.arrayDimensionsSize = 1;
90476UA_UInt32 arrayDimensions[1];
90477arrayDimensions[0] = 0;
90478attr.arrayDimensions = &arrayDimensions[0];
90479attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
90480attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NamespaceArray");
90481retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90482requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2255LU),
90483parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU),
90484referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
90485browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NamespaceArray"),
90486typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
90487attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90488if (retVal != UA_STATUSCODE_GOOD) return retVal;
90489return retVal;
90490}
90491
90492static UA_StatusCode function_namespace0_generated_771_finish(UA_Server *server, UA_UInt16* ns) {
90493return UA_Server_addNode_finish(server,
90494nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2255LU)
90495);
90496}
90497
90498/* ServerArray - ns=0;i=2254 */
90499
90500static UA_StatusCode function_namespace0_generated_772_begin(UA_Server *server, UA_UInt16* ns) {
90501UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90502UA_VariableAttributes attr = UA_VariableAttributes_default;
90503attr.minimumSamplingInterval = 1000.000000;
90504attr.userAccessLevel = 1;
90505attr.accessLevel = 1;
90506attr.valueRank = 1;
90507attr.arrayDimensionsSize = 1;
90508UA_UInt32 arrayDimensions[1];
90509arrayDimensions[0] = 0;
90510attr.arrayDimensions = &arrayDimensions[0];
90511attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
90512attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ServerArray");
90513retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90514requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2254LU),
90515parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU),
90516referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
90517browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ServerArray"),
90518typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
90519attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90520if (retVal != UA_STATUSCODE_GOOD) return retVal;
90521return retVal;
90522}
90523
90524static UA_StatusCode function_namespace0_generated_772_finish(UA_Server *server, UA_UInt16* ns) {
90525return UA_Server_addNode_finish(server,
90526nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2254LU)
90527);
90528}
90529
90530/* PublishSubscribe - ns=0;i=14443 */
90531
90532static UA_StatusCode function_namespace0_generated_773_begin(UA_Server *server, UA_UInt16* ns) {
90533UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90534UA_ObjectAttributes attr = UA_ObjectAttributes_default;
90535attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishSubscribe");
90536retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
90537requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14443LU),
90538parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU),
90539referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90540browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishSubscribe"),
90541typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14416LU),
90542attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
90543if (retVal != UA_STATUSCODE_GOOD) return retVal;
90544return retVal;
90545}
90546
90547static UA_StatusCode function_namespace0_generated_773_finish(UA_Server *server, UA_UInt16* ns) {
90548return UA_Server_addNode_finish(server,
90549nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14443LU)
90550);
90551}
90552
90553/* DefaultDatagramPublisherId - ns=0;i=25480 */
90554
90555static UA_StatusCode function_namespace0_generated_774_begin(UA_Server *server, UA_UInt16* ns) {
90556UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90557UA_VariableAttributes attr = UA_VariableAttributes_default;
90558attr.minimumSamplingInterval = 0.000000;
90559attr.userAccessLevel = 1;
90560attr.accessLevel = 1;
90561/* Value rank inherited */
90562attr.valueRank = -2;
90563attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 9LU);
90564attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DefaultDatagramPublisherId");
90565retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90566requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25480LU),
90567parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14443LU),
90568referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
90569browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DefaultDatagramPublisherId"),
90570typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
90571attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90572if (retVal != UA_STATUSCODE_GOOD) return retVal;
90573return retVal;
90574}
90575
90576static UA_StatusCode function_namespace0_generated_774_finish(UA_Server *server, UA_UInt16* ns) {
90577return UA_Server_addNode_finish(server,
90578nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25480LU)
90579);
90580}
90581
90582/* PubSubConfiguration - ns=0;i=25451 */
90583
90584static UA_StatusCode function_namespace0_generated_775_begin(UA_Server *server, UA_UInt16* ns) {
90585UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90586UA_ObjectAttributes attr = UA_ObjectAttributes_default;
90587attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PubSubConfiguration");
90588retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
90589requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25451LU),
90590parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14443LU),
90591referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90592browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PubSubConfiguration"),
90593typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
90594attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
90595if (retVal != UA_STATUSCODE_GOOD) return retVal;
90596return retVal;
90597}
90598
90599static UA_StatusCode function_namespace0_generated_775_finish(UA_Server *server, UA_UInt16* ns) {
90600return UA_Server_addNode_finish(server,
90601nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25451LU)
90602);
90603}
90604
90605/* ReserveIds - ns=0;i=25474 */
90606
90607static UA_StatusCode function_namespace0_generated_776_begin(UA_Server *server, UA_UInt16* ns) {
90608#ifdef UA_ENABLE_METHODCALLS
90609UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90610UA_MethodAttributes attr = UA_MethodAttributes_default;
90611attr.executable = true;
90612attr.userExecutable = true;
90613attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ReserveIds");
90614retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
90615requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25474LU),
90616parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25451LU),
90617referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90618browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ReserveIds"),
90619 typeDefinition: UA_NODEID_NULL,
90620attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
90621if (retVal != UA_STATUSCODE_GOOD) return retVal;
90622return retVal;
90623#else
90624return UA_STATUSCODE_GOOD;
90625#endif /* UA_ENABLE_METHODCALLS */
90626}
90627
90628static UA_StatusCode function_namespace0_generated_776_finish(UA_Server *server, UA_UInt16* ns) {
90629#ifdef UA_ENABLE_METHODCALLS
90630return UA_Server_addMethodNode_finish(server,
90631nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25474LU)
90632, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
90633#else
90634return UA_STATUSCODE_GOOD;
90635#endif /* UA_ENABLE_METHODCALLS */
90636}
90637
90638/* OutputArguments - ns=0;i=25476 */
90639
90640static UA_StatusCode function_namespace0_generated_777_begin(UA_Server *server, UA_UInt16* ns) {
90641#ifdef UA_ENABLE_METHODCALLS
90642UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90643UA_VariableAttributes attr = UA_VariableAttributes_default;
90644attr.minimumSamplingInterval = 0.000000;
90645attr.userAccessLevel = 1;
90646attr.accessLevel = 1;
90647attr.valueRank = 1;
90648attr.arrayDimensionsSize = 1;
90649UA_UInt32 arrayDimensions[1];
90650arrayDimensions[0] = 3;
90651attr.arrayDimensions = &arrayDimensions[0];
90652attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
90653UA_Argument variablenode_ns_0_i_25476_variant_DataContents[3];
90654
90655UA_init(p: &variablenode_ns_0_i_25476_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
90656variablenode_ns_0_i_25476_variant_DataContents[0].name = UA_STRING(chars: "DefaultPublisherId");
90657variablenode_ns_0_i_25476_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 24LU);
90658variablenode_ns_0_i_25476_variant_DataContents[0].valueRank = (UA_Int32) -1;
90659
90660UA_init(p: &variablenode_ns_0_i_25476_variant_DataContents[1], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
90661variablenode_ns_0_i_25476_variant_DataContents[1].name = UA_STRING(chars: "WriterGroupIds");
90662variablenode_ns_0_i_25476_variant_DataContents[1].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
90663variablenode_ns_0_i_25476_variant_DataContents[1].valueRank = (UA_Int32) -1;
90664
90665UA_init(p: &variablenode_ns_0_i_25476_variant_DataContents[2], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
90666variablenode_ns_0_i_25476_variant_DataContents[2].name = UA_STRING(chars: "DataSetWriterIds");
90667variablenode_ns_0_i_25476_variant_DataContents[2].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
90668variablenode_ns_0_i_25476_variant_DataContents[2].valueRank = (UA_Int32) -1;
90669UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_25476_variant_DataContents, arraySize: (UA_Int32) 3, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
90670attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
90671retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90672requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25476LU),
90673parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25474LU),
90674referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
90675browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
90676typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
90677attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90678if (retVal != UA_STATUSCODE_GOOD) return retVal;
90679
90680
90681
90682return retVal;
90683#else
90684return UA_STATUSCODE_GOOD;
90685#endif /* UA_ENABLE_METHODCALLS */
90686}
90687
90688static UA_StatusCode function_namespace0_generated_777_finish(UA_Server *server, UA_UInt16* ns) {
90689#ifdef UA_ENABLE_METHODCALLS
90690return UA_Server_addNode_finish(server,
90691nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25476LU)
90692);
90693#else
90694return UA_STATUSCODE_GOOD;
90695#endif /* UA_ENABLE_METHODCALLS */
90696}
90697
90698/* InputArguments - ns=0;i=25475 */
90699
90700static UA_StatusCode function_namespace0_generated_778_begin(UA_Server *server, UA_UInt16* ns) {
90701#ifdef UA_ENABLE_METHODCALLS
90702UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90703UA_VariableAttributes attr = UA_VariableAttributes_default;
90704attr.minimumSamplingInterval = 0.000000;
90705attr.userAccessLevel = 1;
90706attr.accessLevel = 1;
90707attr.valueRank = 1;
90708attr.arrayDimensionsSize = 1;
90709UA_UInt32 arrayDimensions[1];
90710arrayDimensions[0] = 3;
90711attr.arrayDimensions = &arrayDimensions[0];
90712attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
90713UA_Argument variablenode_ns_0_i_25475_variant_DataContents[3];
90714
90715UA_init(p: &variablenode_ns_0_i_25475_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
90716variablenode_ns_0_i_25475_variant_DataContents[0].name = UA_STRING(chars: "TransportProfileUri");
90717variablenode_ns_0_i_25475_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
90718variablenode_ns_0_i_25475_variant_DataContents[0].valueRank = (UA_Int32) -1;
90719
90720UA_init(p: &variablenode_ns_0_i_25475_variant_DataContents[1], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
90721variablenode_ns_0_i_25475_variant_DataContents[1].name = UA_STRING(chars: "NumReqWriterGroupIds");
90722variablenode_ns_0_i_25475_variant_DataContents[1].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
90723variablenode_ns_0_i_25475_variant_DataContents[1].valueRank = (UA_Int32) -1;
90724
90725UA_init(p: &variablenode_ns_0_i_25475_variant_DataContents[2], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
90726variablenode_ns_0_i_25475_variant_DataContents[2].name = UA_STRING(chars: "NumReqDataSetWriterIds");
90727variablenode_ns_0_i_25475_variant_DataContents[2].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 5LU);
90728variablenode_ns_0_i_25475_variant_DataContents[2].valueRank = (UA_Int32) -1;
90729UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_25475_variant_DataContents, arraySize: (UA_Int32) 3, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
90730attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
90731retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90732requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25475LU),
90733parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25474LU),
90734referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
90735browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
90736typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
90737attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90738if (retVal != UA_STATUSCODE_GOOD) return retVal;
90739
90740
90741
90742return retVal;
90743#else
90744return UA_STATUSCODE_GOOD;
90745#endif /* UA_ENABLE_METHODCALLS */
90746}
90747
90748static UA_StatusCode function_namespace0_generated_778_finish(UA_Server *server, UA_UInt16* ns) {
90749#ifdef UA_ENABLE_METHODCALLS
90750return UA_Server_addNode_finish(server,
90751nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 25475LU)
90752);
90753#else
90754return UA_STATUSCODE_GOOD;
90755#endif /* UA_ENABLE_METHODCALLS */
90756}
90757
90758/* SubscribedDataSets - ns=0;i=23658 */
90759
90760static UA_StatusCode function_namespace0_generated_779_begin(UA_Server *server, UA_UInt16* ns) {
90761UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90762UA_ObjectAttributes attr = UA_ObjectAttributes_default;
90763attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SubscribedDataSets");
90764retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
90765requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23658LU),
90766parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14443LU),
90767referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90768browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SubscribedDataSets"),
90769typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23795LU),
90770attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
90771if (retVal != UA_STATUSCODE_GOOD) return retVal;
90772return retVal;
90773}
90774
90775static UA_StatusCode function_namespace0_generated_779_finish(UA_Server *server, UA_UInt16* ns) {
90776return UA_Server_addNode_finish(server,
90777nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 23658LU)
90778);
90779}
90780
90781/* SupportedTransportProfiles - ns=0;i=17481 */
90782
90783static UA_StatusCode function_namespace0_generated_780_begin(UA_Server *server, UA_UInt16* ns) {
90784UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90785UA_VariableAttributes attr = UA_VariableAttributes_default;
90786attr.minimumSamplingInterval = 0.000000;
90787attr.userAccessLevel = 1;
90788attr.accessLevel = 1;
90789attr.valueRank = 1;
90790attr.arrayDimensionsSize = 1;
90791UA_UInt32 arrayDimensions[1];
90792arrayDimensions[0] = 0;
90793attr.arrayDimensions = &arrayDimensions[0];
90794attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
90795attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "SupportedTransportProfiles");
90796retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90797requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17481LU),
90798parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14443LU),
90799referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
90800browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "SupportedTransportProfiles"),
90801typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
90802attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90803if (retVal != UA_STATUSCODE_GOOD) return retVal;
90804return retVal;
90805}
90806
90807static UA_StatusCode function_namespace0_generated_780_finish(UA_Server *server, UA_UInt16* ns) {
90808return UA_Server_addNode_finish(server,
90809nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17481LU)
90810);
90811}
90812
90813/* PublishedDataSets - ns=0;i=17371 */
90814
90815static UA_StatusCode function_namespace0_generated_781_begin(UA_Server *server, UA_UInt16* ns) {
90816UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90817UA_ObjectAttributes attr = UA_ObjectAttributes_default;
90818attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "PublishedDataSets");
90819retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
90820requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17371LU),
90821parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14443LU),
90822referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90823browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "PublishedDataSets"),
90824typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14477LU),
90825attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
90826if (retVal != UA_STATUSCODE_GOOD) return retVal;
90827return retVal;
90828}
90829
90830static UA_StatusCode function_namespace0_generated_781_finish(UA_Server *server, UA_UInt16* ns) {
90831return UA_Server_addNode_finish(server,
90832nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17371LU)
90833);
90834}
90835
90836/* RemoveConnection - ns=0;i=17369 */
90837
90838static UA_StatusCode function_namespace0_generated_782_begin(UA_Server *server, UA_UInt16* ns) {
90839#ifdef UA_ENABLE_METHODCALLS
90840UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90841UA_MethodAttributes attr = UA_MethodAttributes_default;
90842attr.executable = true;
90843attr.userExecutable = true;
90844attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "RemoveConnection");
90845retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
90846requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17369LU),
90847parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14443LU),
90848referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90849browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "RemoveConnection"),
90850 typeDefinition: UA_NODEID_NULL,
90851attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
90852if (retVal != UA_STATUSCODE_GOOD) return retVal;
90853return retVal;
90854#else
90855return UA_STATUSCODE_GOOD;
90856#endif /* UA_ENABLE_METHODCALLS */
90857}
90858
90859static UA_StatusCode function_namespace0_generated_782_finish(UA_Server *server, UA_UInt16* ns) {
90860#ifdef UA_ENABLE_METHODCALLS
90861return UA_Server_addMethodNode_finish(server,
90862nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17369LU)
90863, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
90864#else
90865return UA_STATUSCODE_GOOD;
90866#endif /* UA_ENABLE_METHODCALLS */
90867}
90868
90869/* InputArguments - ns=0;i=17370 */
90870
90871static UA_StatusCode function_namespace0_generated_783_begin(UA_Server *server, UA_UInt16* ns) {
90872#ifdef UA_ENABLE_METHODCALLS
90873UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90874UA_VariableAttributes attr = UA_VariableAttributes_default;
90875attr.minimumSamplingInterval = 0.000000;
90876attr.userAccessLevel = 1;
90877attr.accessLevel = 1;
90878attr.valueRank = 1;
90879attr.arrayDimensionsSize = 1;
90880UA_UInt32 arrayDimensions[1];
90881arrayDimensions[0] = 0;
90882attr.arrayDimensions = &arrayDimensions[0];
90883attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
90884UA_Argument variablenode_ns_0_i_17370_variant_DataContents[1];
90885
90886UA_init(p: &variablenode_ns_0_i_17370_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
90887variablenode_ns_0_i_17370_variant_DataContents[0].name = UA_STRING(chars: "ConnectionId");
90888variablenode_ns_0_i_17370_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
90889variablenode_ns_0_i_17370_variant_DataContents[0].valueRank = (UA_Int32) -1;
90890UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_17370_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
90891attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
90892retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90893requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17370LU),
90894parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17369LU),
90895referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
90896browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
90897typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
90898attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90899if (retVal != UA_STATUSCODE_GOOD) return retVal;
90900
90901return retVal;
90902#else
90903return UA_STATUSCODE_GOOD;
90904#endif /* UA_ENABLE_METHODCALLS */
90905}
90906
90907static UA_StatusCode function_namespace0_generated_783_finish(UA_Server *server, UA_UInt16* ns) {
90908#ifdef UA_ENABLE_METHODCALLS
90909return UA_Server_addNode_finish(server,
90910nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17370LU)
90911);
90912#else
90913return UA_STATUSCODE_GOOD;
90914#endif /* UA_ENABLE_METHODCALLS */
90915}
90916
90917/* AddConnection - ns=0;i=17366 */
90918
90919static UA_StatusCode function_namespace0_generated_784_begin(UA_Server *server, UA_UInt16* ns) {
90920#ifdef UA_ENABLE_METHODCALLS
90921UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90922UA_MethodAttributes attr = UA_MethodAttributes_default;
90923attr.executable = true;
90924attr.userExecutable = true;
90925attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "AddConnection");
90926retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
90927requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17366LU),
90928parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 14443LU),
90929referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
90930browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "AddConnection"),
90931 typeDefinition: UA_NODEID_NULL,
90932attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
90933if (retVal != UA_STATUSCODE_GOOD) return retVal;
90934return retVal;
90935#else
90936return UA_STATUSCODE_GOOD;
90937#endif /* UA_ENABLE_METHODCALLS */
90938}
90939
90940static UA_StatusCode function_namespace0_generated_784_finish(UA_Server *server, UA_UInt16* ns) {
90941#ifdef UA_ENABLE_METHODCALLS
90942return UA_Server_addMethodNode_finish(server,
90943nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17366LU)
90944, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
90945#else
90946return UA_STATUSCODE_GOOD;
90947#endif /* UA_ENABLE_METHODCALLS */
90948}
90949
90950/* OutputArguments - ns=0;i=17368 */
90951
90952static UA_StatusCode function_namespace0_generated_785_begin(UA_Server *server, UA_UInt16* ns) {
90953#ifdef UA_ENABLE_METHODCALLS
90954UA_StatusCode retVal = UA_STATUSCODE_GOOD;
90955UA_VariableAttributes attr = UA_VariableAttributes_default;
90956attr.minimumSamplingInterval = 0.000000;
90957attr.userAccessLevel = 1;
90958attr.accessLevel = 1;
90959attr.valueRank = 1;
90960attr.arrayDimensionsSize = 1;
90961UA_UInt32 arrayDimensions[1];
90962arrayDimensions[0] = 0;
90963attr.arrayDimensions = &arrayDimensions[0];
90964attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
90965UA_Argument variablenode_ns_0_i_17368_variant_DataContents[1];
90966
90967UA_init(p: &variablenode_ns_0_i_17368_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
90968variablenode_ns_0_i_17368_variant_DataContents[0].name = UA_STRING(chars: "ConnectionId");
90969variablenode_ns_0_i_17368_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17LU);
90970variablenode_ns_0_i_17368_variant_DataContents[0].valueRank = (UA_Int32) -1;
90971UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_17368_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
90972attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
90973retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
90974requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17368LU),
90975parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17366LU),
90976referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
90977browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
90978typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
90979attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
90980if (retVal != UA_STATUSCODE_GOOD) return retVal;
90981
90982return retVal;
90983#else
90984return UA_STATUSCODE_GOOD;
90985#endif /* UA_ENABLE_METHODCALLS */
90986}
90987
90988static UA_StatusCode function_namespace0_generated_785_finish(UA_Server *server, UA_UInt16* ns) {
90989#ifdef UA_ENABLE_METHODCALLS
90990return UA_Server_addNode_finish(server,
90991nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17368LU)
90992);
90993#else
90994return UA_STATUSCODE_GOOD;
90995#endif /* UA_ENABLE_METHODCALLS */
90996}
90997
90998/* InputArguments - ns=0;i=17367 */
90999
91000static UA_StatusCode function_namespace0_generated_786_begin(UA_Server *server, UA_UInt16* ns) {
91001#ifdef UA_ENABLE_METHODCALLS
91002UA_StatusCode retVal = UA_STATUSCODE_GOOD;
91003UA_VariableAttributes attr = UA_VariableAttributes_default;
91004attr.minimumSamplingInterval = 0.000000;
91005attr.userAccessLevel = 1;
91006attr.accessLevel = 1;
91007attr.valueRank = 1;
91008attr.arrayDimensionsSize = 1;
91009UA_UInt32 arrayDimensions[1];
91010arrayDimensions[0] = 0;
91011attr.arrayDimensions = &arrayDimensions[0];
91012attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
91013UA_Argument variablenode_ns_0_i_17367_variant_DataContents[1];
91014
91015UA_init(p: &variablenode_ns_0_i_17367_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
91016variablenode_ns_0_i_17367_variant_DataContents[0].name = UA_STRING(chars: "Configuration");
91017variablenode_ns_0_i_17367_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15617LU);
91018variablenode_ns_0_i_17367_variant_DataContents[0].valueRank = (UA_Int32) -1;
91019UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_17367_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
91020attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
91021retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
91022requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17367LU),
91023parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17366LU),
91024referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
91025browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
91026typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
91027attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
91028if (retVal != UA_STATUSCODE_GOOD) return retVal;
91029
91030return retVal;
91031#else
91032return UA_STATUSCODE_GOOD;
91033#endif /* UA_ENABLE_METHODCALLS */
91034}
91035
91036static UA_StatusCode function_namespace0_generated_786_finish(UA_Server *server, UA_UInt16* ns) {
91037#ifdef UA_ENABLE_METHODCALLS
91038return UA_Server_addNode_finish(server,
91039nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 17367LU)
91040);
91041#else
91042return UA_STATUSCODE_GOOD;
91043#endif /* UA_ENABLE_METHODCALLS */
91044}
91045
91046/* ResendData - ns=0;i=12873 */
91047
91048static UA_StatusCode function_namespace0_generated_787_begin(UA_Server *server, UA_UInt16* ns) {
91049#ifdef UA_ENABLE_METHODCALLS
91050UA_StatusCode retVal = UA_STATUSCODE_GOOD;
91051UA_MethodAttributes attr = UA_MethodAttributes_default;
91052attr.executable = true;
91053attr.userExecutable = true;
91054attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ResendData");
91055retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
91056requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12873LU),
91057parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU),
91058referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
91059browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ResendData"),
91060 typeDefinition: UA_NODEID_NULL,
91061attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
91062if (retVal != UA_STATUSCODE_GOOD) return retVal;
91063return retVal;
91064#else
91065return UA_STATUSCODE_GOOD;
91066#endif /* UA_ENABLE_METHODCALLS */
91067}
91068
91069static UA_StatusCode function_namespace0_generated_787_finish(UA_Server *server, UA_UInt16* ns) {
91070#ifdef UA_ENABLE_METHODCALLS
91071return UA_Server_addMethodNode_finish(server,
91072nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12873LU)
91073, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
91074#else
91075return UA_STATUSCODE_GOOD;
91076#endif /* UA_ENABLE_METHODCALLS */
91077}
91078
91079/* InputArguments - ns=0;i=12874 */
91080
91081static UA_StatusCode function_namespace0_generated_788_begin(UA_Server *server, UA_UInt16* ns) {
91082#ifdef UA_ENABLE_METHODCALLS
91083UA_StatusCode retVal = UA_STATUSCODE_GOOD;
91084UA_VariableAttributes attr = UA_VariableAttributes_default;
91085attr.minimumSamplingInterval = 0.000000;
91086attr.userAccessLevel = 1;
91087attr.accessLevel = 1;
91088attr.valueRank = 1;
91089attr.arrayDimensionsSize = 1;
91090UA_UInt32 arrayDimensions[1];
91091arrayDimensions[0] = 1;
91092attr.arrayDimensions = &arrayDimensions[0];
91093attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
91094UA_Argument variablenode_ns_0_i_12874_variant_DataContents[1];
91095
91096UA_init(p: &variablenode_ns_0_i_12874_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
91097variablenode_ns_0_i_12874_variant_DataContents[0].name = UA_STRING(chars: "SubscriptionId");
91098variablenode_ns_0_i_12874_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
91099variablenode_ns_0_i_12874_variant_DataContents[0].valueRank = (UA_Int32) -1;
91100UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_12874_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
91101attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
91102retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
91103requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12874LU),
91104parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12873LU),
91105referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
91106browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
91107typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
91108attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
91109if (retVal != UA_STATUSCODE_GOOD) return retVal;
91110
91111return retVal;
91112#else
91113return UA_STATUSCODE_GOOD;
91114#endif /* UA_ENABLE_METHODCALLS */
91115}
91116
91117static UA_StatusCode function_namespace0_generated_788_finish(UA_Server *server, UA_UInt16* ns) {
91118#ifdef UA_ENABLE_METHODCALLS
91119return UA_Server_addNode_finish(server,
91120nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12874LU)
91121);
91122#else
91123return UA_STATUSCODE_GOOD;
91124#endif /* UA_ENABLE_METHODCALLS */
91125}
91126
91127/* GetMonitoredItems - ns=0;i=11492 */
91128
91129static UA_StatusCode function_namespace0_generated_789_begin(UA_Server *server, UA_UInt16* ns) {
91130#ifdef UA_ENABLE_METHODCALLS
91131UA_StatusCode retVal = UA_STATUSCODE_GOOD;
91132UA_MethodAttributes attr = UA_MethodAttributes_default;
91133attr.executable = true;
91134attr.userExecutable = true;
91135attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "GetMonitoredItems");
91136retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_METHOD,
91137requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11492LU),
91138parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2253LU),
91139referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
91140browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "GetMonitoredItems"),
91141 typeDefinition: UA_NODEID_NULL,
91142attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL);
91143if (retVal != UA_STATUSCODE_GOOD) return retVal;
91144return retVal;
91145#else
91146return UA_STATUSCODE_GOOD;
91147#endif /* UA_ENABLE_METHODCALLS */
91148}
91149
91150static UA_StatusCode function_namespace0_generated_789_finish(UA_Server *server, UA_UInt16* ns) {
91151#ifdef UA_ENABLE_METHODCALLS
91152return UA_Server_addMethodNode_finish(server,
91153nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11492LU)
91154, NULL, inputArgumentsSize: 0, NULL, outputArgumentsSize: 0, NULL);
91155#else
91156return UA_STATUSCODE_GOOD;
91157#endif /* UA_ENABLE_METHODCALLS */
91158}
91159
91160/* OutputArguments - ns=0;i=11494 */
91161
91162static UA_StatusCode function_namespace0_generated_790_begin(UA_Server *server, UA_UInt16* ns) {
91163#ifdef UA_ENABLE_METHODCALLS
91164UA_StatusCode retVal = UA_STATUSCODE_GOOD;
91165UA_VariableAttributes attr = UA_VariableAttributes_default;
91166attr.minimumSamplingInterval = 0.000000;
91167attr.userAccessLevel = 1;
91168attr.accessLevel = 1;
91169attr.valueRank = 1;
91170attr.arrayDimensionsSize = 1;
91171UA_UInt32 arrayDimensions[1];
91172arrayDimensions[0] = 0;
91173attr.arrayDimensions = &arrayDimensions[0];
91174attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
91175UA_Argument variablenode_ns_0_i_11494_variant_DataContents[2];
91176
91177UA_init(p: &variablenode_ns_0_i_11494_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
91178variablenode_ns_0_i_11494_variant_DataContents[0].name = UA_STRING(chars: "ServerHandles");
91179variablenode_ns_0_i_11494_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
91180variablenode_ns_0_i_11494_variant_DataContents[0].valueRank = (UA_Int32) 1;
91181UA_STACKARRAY(UA_UInt32, variablenode_ns_0_i_11494_variant_DataContents0_arrayDimensions, 1);
91182UA_init(p: variablenode_ns_0_i_11494_variant_DataContents0_arrayDimensions, type: &UA_TYPES[UA_TYPES_UINT32]);
91183variablenode_ns_0_i_11494_variant_DataContents0_arrayDimensions[0] = (UA_UInt32) 0;
91184variablenode_ns_0_i_11494_variant_DataContents[0].arrayDimensionsSize = 1;
91185variablenode_ns_0_i_11494_variant_DataContents[0].arrayDimensions = variablenode_ns_0_i_11494_variant_DataContents0_arrayDimensions;
91186
91187UA_init(p: &variablenode_ns_0_i_11494_variant_DataContents[1], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
91188variablenode_ns_0_i_11494_variant_DataContents[1].name = UA_STRING(chars: "ClientHandles");
91189variablenode_ns_0_i_11494_variant_DataContents[1].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
91190variablenode_ns_0_i_11494_variant_DataContents[1].valueRank = (UA_Int32) 1;
91191UA_STACKARRAY(UA_UInt32, variablenode_ns_0_i_11494_variant_DataContents1_arrayDimensions, 1);
91192UA_init(p: variablenode_ns_0_i_11494_variant_DataContents1_arrayDimensions, type: &UA_TYPES[UA_TYPES_UINT32]);
91193variablenode_ns_0_i_11494_variant_DataContents1_arrayDimensions[0] = (UA_UInt32) 0;
91194variablenode_ns_0_i_11494_variant_DataContents[1].arrayDimensionsSize = 1;
91195variablenode_ns_0_i_11494_variant_DataContents[1].arrayDimensions = variablenode_ns_0_i_11494_variant_DataContents1_arrayDimensions;
91196UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_11494_variant_DataContents, arraySize: (UA_Int32) 2, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
91197attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OutputArguments");
91198retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
91199requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11494LU),
91200parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11492LU),
91201referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
91202browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OutputArguments"),
91203typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
91204attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
91205if (retVal != UA_STATUSCODE_GOOD) return retVal;
91206
91207
91208return retVal;
91209#else
91210return UA_STATUSCODE_GOOD;
91211#endif /* UA_ENABLE_METHODCALLS */
91212}
91213
91214static UA_StatusCode function_namespace0_generated_790_finish(UA_Server *server, UA_UInt16* ns) {
91215#ifdef UA_ENABLE_METHODCALLS
91216return UA_Server_addNode_finish(server,
91217nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11494LU)
91218);
91219#else
91220return UA_STATUSCODE_GOOD;
91221#endif /* UA_ENABLE_METHODCALLS */
91222}
91223
91224/* InputArguments - ns=0;i=11493 */
91225
91226static UA_StatusCode function_namespace0_generated_791_begin(UA_Server *server, UA_UInt16* ns) {
91227#ifdef UA_ENABLE_METHODCALLS
91228UA_StatusCode retVal = UA_STATUSCODE_GOOD;
91229UA_VariableAttributes attr = UA_VariableAttributes_default;
91230attr.minimumSamplingInterval = 0.000000;
91231attr.userAccessLevel = 1;
91232attr.accessLevel = 1;
91233attr.valueRank = 1;
91234attr.arrayDimensionsSize = 1;
91235UA_UInt32 arrayDimensions[1];
91236arrayDimensions[0] = 0;
91237attr.arrayDimensions = &arrayDimensions[0];
91238attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU);
91239UA_Argument variablenode_ns_0_i_11493_variant_DataContents[1];
91240
91241UA_init(p: &variablenode_ns_0_i_11493_variant_DataContents[0], type: &UA_TYPES[UA_TYPES_ARGUMENT]);
91242variablenode_ns_0_i_11493_variant_DataContents[0].name = UA_STRING(chars: "SubscriptionId");
91243variablenode_ns_0_i_11493_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7LU);
91244variablenode_ns_0_i_11493_variant_DataContents[0].valueRank = (UA_Int32) -1;
91245UA_Variant_setArray(v: &attr.value, array: &variablenode_ns_0_i_11493_variant_DataContents, arraySize: (UA_Int32) 1, type: &UA_TYPES[UA_TYPES_ARGUMENT]);
91246attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "InputArguments");
91247retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
91248requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11493LU),
91249parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11492LU),
91250referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
91251browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "InputArguments"),
91252typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
91253attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
91254if (retVal != UA_STATUSCODE_GOOD) return retVal;
91255
91256return retVal;
91257#else
91258return UA_STATUSCODE_GOOD;
91259#endif /* UA_ENABLE_METHODCALLS */
91260}
91261
91262static UA_StatusCode function_namespace0_generated_791_finish(UA_Server *server, UA_UInt16* ns) {
91263#ifdef UA_ENABLE_METHODCALLS
91264return UA_Server_addNode_finish(server,
91265nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11493LU)
91266);
91267#else
91268return UA_STATUSCODE_GOOD;
91269#endif /* UA_ENABLE_METHODCALLS */
91270}
91271
91272/* VendorServerInfo - ns=0;i=2011 */
91273
91274static UA_StatusCode function_namespace0_generated_792_begin(UA_Server *server, UA_UInt16* ns) {
91275UA_StatusCode retVal = UA_STATUSCODE_GOOD;
91276UA_ObjectAttributes attr = UA_ObjectAttributes_default;
91277attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "VendorServerInfo");
91278retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
91279requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2011LU),
91280parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2004LU),
91281referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
91282browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "VendorServerInfo"),
91283typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2033LU),
91284attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
91285if (retVal != UA_STATUSCODE_GOOD) return retVal;
91286return retVal;
91287}
91288
91289static UA_StatusCode function_namespace0_generated_792_finish(UA_Server *server, UA_UInt16* ns) {
91290return UA_Server_addNode_finish(server,
91291nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 2011LU)
91292);
91293}
91294
91295/* ModellingRuleType - ns=0;i=77 */
91296
91297static UA_StatusCode function_namespace0_generated_793_begin(UA_Server *server, UA_UInt16* ns) {
91298UA_StatusCode retVal = UA_STATUSCODE_GOOD;
91299UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
91300attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ModellingRuleType");
91301retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
91302requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 77LU),
91303parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
91304referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
91305browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ModellingRuleType"),
91306 typeDefinition: UA_NODEID_NULL,
91307attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
91308if (retVal != UA_STATUSCODE_GOOD) return retVal;
91309return retVal;
91310}
91311
91312static UA_StatusCode function_namespace0_generated_793_finish(UA_Server *server, UA_UInt16* ns) {
91313return UA_Server_addNode_finish(server,
91314nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 77LU)
91315);
91316}
91317
91318/* ExposesItsArray - ns=0;i=83 */
91319
91320static UA_StatusCode function_namespace0_generated_794_begin(UA_Server *server, UA_UInt16* ns) {
91321UA_StatusCode retVal = UA_STATUSCODE_GOOD;
91322UA_ObjectAttributes attr = UA_ObjectAttributes_default;
91323attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "ExposesItsArray");
91324retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
91325requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 83LU),
91326parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
91327referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
91328browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "ExposesItsArray"),
91329typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 77LU),
91330attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
91331if (retVal != UA_STATUSCODE_GOOD) return retVal;
91332retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 83LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12860LU), false);
91333if (retVal != UA_STATUSCODE_GOOD) return retVal;
91334retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 83LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12816LU), false);
91335if (retVal != UA_STATUSCODE_GOOD) return retVal;
91336retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 83LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12779LU), false);
91337if (retVal != UA_STATUSCODE_GOOD) return retVal;
91338retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 83LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12784LU), false);
91339if (retVal != UA_STATUSCODE_GOOD) return retVal;
91340return retVal;
91341}
91342
91343static UA_StatusCode function_namespace0_generated_794_finish(UA_Server *server, UA_UInt16* ns) {
91344return UA_Server_addNode_finish(server,
91345nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 83LU)
91346);
91347}
91348
91349/* NamingRule - ns=0;i=114 */
91350
91351static UA_StatusCode function_namespace0_generated_795_begin(UA_Server *server, UA_UInt16* ns) {
91352UA_StatusCode retVal = UA_STATUSCODE_GOOD;
91353UA_VariableAttributes attr = UA_VariableAttributes_default;
91354attr.minimumSamplingInterval = 0.000000;
91355attr.userAccessLevel = 1;
91356attr.accessLevel = 1;
91357/* Value rank inherited */
91358attr.valueRank = -2;
91359attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 120LU);
91360UA_Int32 *variablenode_ns_0_i_114_variant_DataContents = UA_Int32_new();
91361if (!variablenode_ns_0_i_114_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY;
91362UA_Int32_init(p: variablenode_ns_0_i_114_variant_DataContents);
91363*variablenode_ns_0_i_114_variant_DataContents = (UA_Int32) 3;
91364UA_Variant_setScalar(v: &attr.value, p: variablenode_ns_0_i_114_variant_DataContents, type: &UA_TYPES[UA_TYPES_INT32]);
91365attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NamingRule");
91366retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
91367requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 114LU),
91368parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 83LU),
91369referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
91370browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NamingRule"),
91371typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
91372attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
91373if (retVal != UA_STATUSCODE_GOOD) return retVal;
91374UA_Int32_delete(p: variablenode_ns_0_i_114_variant_DataContents);
91375return retVal;
91376}
91377
91378static UA_StatusCode function_namespace0_generated_795_finish(UA_Server *server, UA_UInt16* ns) {
91379return UA_Server_addNode_finish(server,
91380nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 114LU)
91381);
91382}
91383
91384/* Optional - ns=0;i=80 */
91385
91386static UA_StatusCode function_namespace0_generated_796_begin(UA_Server *server, UA_UInt16* ns) {
91387UA_StatusCode retVal = UA_STATUSCODE_GOOD;
91388UA_ObjectAttributes attr = UA_ObjectAttributes_default;
91389attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Optional");
91390retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
91391requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU),
91392parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
91393referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
91394browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Optional"),
91395typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 77LU),
91396attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
91397if (retVal != UA_STATUSCODE_GOOD) return retVal;
91398retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11551LU), false);
91399if (retVal != UA_STATUSCODE_GOOD) return retVal;
91400retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11565LU), false);
91401if (retVal != UA_STATUSCODE_GOOD) return retVal;
91402retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11567LU), false);
91403if (retVal != UA_STATUSCODE_GOOD) return retVal;
91404retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11569LU), false);
91405if (retVal != UA_STATUSCODE_GOOD) return retVal;
91406retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11570LU), false);
91407if (retVal != UA_STATUSCODE_GOOD) return retVal;
91408retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11571LU), false);
91409if (retVal != UA_STATUSCODE_GOOD) return retVal;
91410retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11572LU), false);
91411if (retVal != UA_STATUSCODE_GOOD) return retVal;
91412retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11573LU), false);
91413if (retVal != UA_STATUSCODE_GOOD) return retVal;
91414retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11574LU), false);
91415if (retVal != UA_STATUSCODE_GOOD) return retVal;
91416retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2022LU), false);
91417if (retVal != UA_STATUSCODE_GOOD) return retVal;
91418retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3190LU), false);
91419if (retVal != UA_STATUSCODE_GOOD) return retVal;
91420retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2757LU), false);
91421if (retVal != UA_STATUSCODE_GOOD) return retVal;
91422retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2758LU), false);
91423if (retVal != UA_STATUSCODE_GOOD) return retVal;
91424retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2759LU), false);
91425if (retVal != UA_STATUSCODE_GOOD) return retVal;
91426retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9000LU), false);
91427if (retVal != UA_STATUSCODE_GOOD) return retVal;
91428retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9001LU), false);
91429if (retVal != UA_STATUSCODE_GOOD) return retVal;
91430retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11110LU), false);
91431if (retVal != UA_STATUSCODE_GOOD) return retVal;
91432retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11111LU), false);
91433if (retVal != UA_STATUSCODE_GOOD) return retVal;
91434retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9015LU), false);
91435if (retVal != UA_STATUSCODE_GOOD) return retVal;
91436retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9016LU), false);
91437if (retVal != UA_STATUSCODE_GOOD) return retVal;
91438retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9017LU), false);
91439if (retVal != UA_STATUSCODE_GOOD) return retVal;
91440retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 25432LU), false);
91441if (retVal != UA_STATUSCODE_GOOD) return retVal;
91442retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14493LU), false);
91443if (retVal != UA_STATUSCODE_GOOD) return retVal;
91444retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14499LU), false);
91445if (retVal != UA_STATUSCODE_GOOD) return retVal;
91446retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 16994LU), false);
91447if (retVal != UA_STATUSCODE_GOOD) return retVal;
91448retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 16997LU), false);
91449if (retVal != UA_STATUSCODE_GOOD) return retVal;
91450retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23622LU), false);
91451if (retVal != UA_STATUSCODE_GOOD) return retVal;
91452retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 16759LU), false);
91453if (retVal != UA_STATUSCODE_GOOD) return retVal;
91454retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14555LU), false);
91455if (retVal != UA_STATUSCODE_GOOD) return retVal;
91456retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14558LU), false);
91457if (retVal != UA_STATUSCODE_GOOD) return retVal;
91458retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17203LU), false);
91459if (retVal != UA_STATUSCODE_GOOD) return retVal;
91460retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17427LU), false);
91461if (retVal != UA_STATUSCODE_GOOD) return retVal;
91462retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17465LU), false);
91463if (retVal != UA_STATUSCODE_GOOD) return retVal;
91464retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14225LU), false);
91465if (retVal != UA_STATUSCODE_GOOD) return retVal;
91466retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15927LU), false);
91467if (retVal != UA_STATUSCODE_GOOD) return retVal;
91468retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17969LU), false);
91469if (retVal != UA_STATUSCODE_GOOD) return retVal;
91470retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17992LU), false);
91471if (retVal != UA_STATUSCODE_GOOD) return retVal;
91472retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21094LU), false);
91473if (retVal != UA_STATUSCODE_GOOD) return retVal;
91474retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15303LU), false);
91475if (retVal != UA_STATUSCODE_GOOD) return retVal;
91476retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23797LU), false);
91477if (retVal != UA_STATUSCODE_GOOD) return retVal;
91478retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23800LU), false);
91479if (retVal != UA_STATUSCODE_GOOD) return retVal;
91480retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23802LU), false);
91481if (retVal != UA_STATUSCODE_GOOD) return retVal;
91482retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23805LU), false);
91483if (retVal != UA_STATUSCODE_GOOD) return retVal;
91484retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23811LU), false);
91485if (retVal != UA_STATUSCODE_GOOD) return retVal;
91486retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23814LU), false);
91487if (retVal != UA_STATUSCODE_GOOD) return retVal;
91488retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23816LU), false);
91489if (retVal != UA_STATUSCODE_GOOD) return retVal;
91490retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23819LU), false);
91491if (retVal != UA_STATUSCODE_GOOD) return retVal;
91492retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14645LU), false);
91493if (retVal != UA_STATUSCODE_GOOD) return retVal;
91494retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14646LU), false);
91495if (retVal != UA_STATUSCODE_GOOD) return retVal;
91496retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17633LU), false);
91497if (retVal != UA_STATUSCODE_GOOD) return retVal;
91498retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 16312LU), false);
91499if (retVal != UA_STATUSCODE_GOOD) return retVal;
91500retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 16598LU), false);
91501if (retVal != UA_STATUSCODE_GOOD) return retVal;
91502retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14432LU), false);
91503if (retVal != UA_STATUSCODE_GOOD) return retVal;
91504retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15115LU), false);
91505if (retVal != UA_STATUSCODE_GOOD) return retVal;
91506retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15118LU), false);
91507if (retVal != UA_STATUSCODE_GOOD) return retVal;
91508retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2366LU), false);
91509if (retVal != UA_STATUSCODE_GOOD) return retVal;
91510retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2367LU), false);
91511if (retVal != UA_STATUSCODE_GOOD) return retVal;
91512retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2370LU), false);
91513if (retVal != UA_STATUSCODE_GOOD) return retVal;
91514retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2371LU), false);
91515if (retVal != UA_STATUSCODE_GOOD) return retVal;
91516return retVal;
91517}
91518
91519static UA_StatusCode function_namespace0_generated_796_finish(UA_Server *server, UA_UInt16* ns) {
91520return UA_Server_addNode_finish(server,
91521nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU)
91522);
91523}
91524
91525/* NamingRule - ns=0;i=113 */
91526
91527static UA_StatusCode function_namespace0_generated_797_begin(UA_Server *server, UA_UInt16* ns) {
91528UA_StatusCode retVal = UA_STATUSCODE_GOOD;
91529UA_VariableAttributes attr = UA_VariableAttributes_default;
91530attr.minimumSamplingInterval = 0.000000;
91531attr.userAccessLevel = 1;
91532attr.accessLevel = 1;
91533/* Value rank inherited */
91534attr.valueRank = -2;
91535attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 120LU);
91536UA_Int32 *variablenode_ns_0_i_113_variant_DataContents = UA_Int32_new();
91537if (!variablenode_ns_0_i_113_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY;
91538UA_Int32_init(p: variablenode_ns_0_i_113_variant_DataContents);
91539*variablenode_ns_0_i_113_variant_DataContents = (UA_Int32) 2;
91540UA_Variant_setScalar(v: &attr.value, p: variablenode_ns_0_i_113_variant_DataContents, type: &UA_TYPES[UA_TYPES_INT32]);
91541attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NamingRule");
91542retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
91543requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 113LU),
91544parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU),
91545referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
91546browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NamingRule"),
91547typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
91548attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
91549if (retVal != UA_STATUSCODE_GOOD) return retVal;
91550UA_Int32_delete(p: variablenode_ns_0_i_113_variant_DataContents);
91551return retVal;
91552}
91553
91554static UA_StatusCode function_namespace0_generated_797_finish(UA_Server *server, UA_UInt16* ns) {
91555return UA_Server_addNode_finish(server,
91556nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 113LU)
91557);
91558}
91559
91560/* Mandatory - ns=0;i=78 */
91561
91562static UA_StatusCode function_namespace0_generated_798_begin(UA_Server *server, UA_UInt16* ns) {
91563UA_StatusCode retVal = UA_STATUSCODE_GOOD;
91564UA_ObjectAttributes attr = UA_ObjectAttributes_default;
91565attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Mandatory");
91566retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
91567requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU),
91568parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
91569referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
91570browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Mandatory"),
91571typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 77LU),
91572attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
91573if (retVal != UA_STATUSCODE_GOOD) return retVal;
91574retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12169LU), false);
91575if (retVal != UA_STATUSCODE_GOOD) return retVal;
91576retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2011LU), false);
91577if (retVal != UA_STATUSCODE_GOOD) return retVal;
91578retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2035LU), false);
91579if (retVal != UA_STATUSCODE_GOOD) return retVal;
91580retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 7611LU), false);
91581if (retVal != UA_STATUSCODE_GOOD) return retVal;
91582retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2021LU), false);
91583if (retVal != UA_STATUSCODE_GOOD) return retVal;
91584retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3116LU), false);
91585if (retVal != UA_STATUSCODE_GOOD) return retVal;
91586retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3117LU), false);
91587if (retVal != UA_STATUSCODE_GOOD) return retVal;
91588retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3118LU), false);
91589if (retVal != UA_STATUSCODE_GOOD) return retVal;
91590retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3119LU), false);
91591if (retVal != UA_STATUSCODE_GOOD) return retVal;
91592retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3120LU), false);
91593if (retVal != UA_STATUSCODE_GOOD) return retVal;
91594retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3121LU), false);
91595if (retVal != UA_STATUSCODE_GOOD) return retVal;
91596retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3122LU), false);
91597if (retVal != UA_STATUSCODE_GOOD) return retVal;
91598retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3124LU), false);
91599if (retVal != UA_STATUSCODE_GOOD) return retVal;
91600retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3125LU), false);
91601if (retVal != UA_STATUSCODE_GOOD) return retVal;
91602retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3126LU), false);
91603if (retVal != UA_STATUSCODE_GOOD) return retVal;
91604retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3127LU), false);
91605if (retVal != UA_STATUSCODE_GOOD) return retVal;
91606retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3128LU), false);
91607if (retVal != UA_STATUSCODE_GOOD) return retVal;
91608retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2023LU), false);
91609if (retVal != UA_STATUSCODE_GOOD) return retVal;
91610retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12142LU), false);
91611if (retVal != UA_STATUSCODE_GOOD) return retVal;
91612retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12152LU), false);
91613if (retVal != UA_STATUSCODE_GOOD) return retVal;
91614retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12143LU), false);
91615if (retVal != UA_STATUSCODE_GOOD) return retVal;
91616retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12144LU), false);
91617if (retVal != UA_STATUSCODE_GOOD) return retVal;
91618retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12145LU), false);
91619if (retVal != UA_STATUSCODE_GOOD) return retVal;
91620retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12146LU), false);
91621if (retVal != UA_STATUSCODE_GOOD) return retVal;
91622retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12147LU), false);
91623if (retVal != UA_STATUSCODE_GOOD) return retVal;
91624retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12148LU), false);
91625if (retVal != UA_STATUSCODE_GOOD) return retVal;
91626retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12149LU), false);
91627if (retVal != UA_STATUSCODE_GOOD) return retVal;
91628retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12150LU), false);
91629if (retVal != UA_STATUSCODE_GOOD) return retVal;
91630retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12151LU), false);
91631if (retVal != UA_STATUSCODE_GOOD) return retVal;
91632retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2027LU), false);
91633if (retVal != UA_STATUSCODE_GOOD) return retVal;
91634retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2028LU), false);
91635if (retVal != UA_STATUSCODE_GOOD) return retVal;
91636retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12098LU), false);
91637if (retVal != UA_STATUSCODE_GOOD) return retVal;
91638retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12099LU), false);
91639if (retVal != UA_STATUSCODE_GOOD) return retVal;
91640retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12100LU), false);
91641if (retVal != UA_STATUSCODE_GOOD) return retVal;
91642retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12101LU), false);
91643if (retVal != UA_STATUSCODE_GOOD) return retVal;
91644retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12102LU), false);
91645if (retVal != UA_STATUSCODE_GOOD) return retVal;
91646retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12103LU), false);
91647if (retVal != UA_STATUSCODE_GOOD) return retVal;
91648retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12104LU), false);
91649if (retVal != UA_STATUSCODE_GOOD) return retVal;
91650retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12105LU), false);
91651if (retVal != UA_STATUSCODE_GOOD) return retVal;
91652retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12106LU), false);
91653if (retVal != UA_STATUSCODE_GOOD) return retVal;
91654retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12107LU), false);
91655if (retVal != UA_STATUSCODE_GOOD) return retVal;
91656retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12108LU), false);
91657if (retVal != UA_STATUSCODE_GOOD) return retVal;
91658retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12109LU), false);
91659if (retVal != UA_STATUSCODE_GOOD) return retVal;
91660retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12110LU), false);
91661if (retVal != UA_STATUSCODE_GOOD) return retVal;
91662retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12111LU), false);
91663if (retVal != UA_STATUSCODE_GOOD) return retVal;
91664retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12112LU), false);
91665if (retVal != UA_STATUSCODE_GOOD) return retVal;
91666retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12113LU), false);
91667if (retVal != UA_STATUSCODE_GOOD) return retVal;
91668retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12114LU), false);
91669if (retVal != UA_STATUSCODE_GOOD) return retVal;
91670retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12115LU), false);
91671if (retVal != UA_STATUSCODE_GOOD) return retVal;
91672retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12116LU), false);
91673if (retVal != UA_STATUSCODE_GOOD) return retVal;
91674retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12117LU), false);
91675if (retVal != UA_STATUSCODE_GOOD) return retVal;
91676retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12118LU), false);
91677if (retVal != UA_STATUSCODE_GOOD) return retVal;
91678retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12119LU), false);
91679if (retVal != UA_STATUSCODE_GOOD) return retVal;
91680retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12120LU), false);
91681if (retVal != UA_STATUSCODE_GOOD) return retVal;
91682retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12121LU), false);
91683if (retVal != UA_STATUSCODE_GOOD) return retVal;
91684retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12122LU), false);
91685if (retVal != UA_STATUSCODE_GOOD) return retVal;
91686retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12123LU), false);
91687if (retVal != UA_STATUSCODE_GOOD) return retVal;
91688retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12124LU), false);
91689if (retVal != UA_STATUSCODE_GOOD) return retVal;
91690retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12125LU), false);
91691if (retVal != UA_STATUSCODE_GOOD) return retVal;
91692retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12126LU), false);
91693if (retVal != UA_STATUSCODE_GOOD) return retVal;
91694retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12127LU), false);
91695if (retVal != UA_STATUSCODE_GOOD) return retVal;
91696retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12128LU), false);
91697if (retVal != UA_STATUSCODE_GOOD) return retVal;
91698retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12129LU), false);
91699if (retVal != UA_STATUSCODE_GOOD) return retVal;
91700retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12130LU), false);
91701if (retVal != UA_STATUSCODE_GOOD) return retVal;
91702retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12131LU), false);
91703if (retVal != UA_STATUSCODE_GOOD) return retVal;
91704retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12132LU), false);
91705if (retVal != UA_STATUSCODE_GOOD) return retVal;
91706retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12133LU), false);
91707if (retVal != UA_STATUSCODE_GOOD) return retVal;
91708retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12134LU), false);
91709if (retVal != UA_STATUSCODE_GOOD) return retVal;
91710retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12135LU), false);
91711if (retVal != UA_STATUSCODE_GOOD) return retVal;
91712retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12136LU), false);
91713if (retVal != UA_STATUSCODE_GOOD) return retVal;
91714retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12137LU), false);
91715if (retVal != UA_STATUSCODE_GOOD) return retVal;
91716retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12138LU), false);
91717if (retVal != UA_STATUSCODE_GOOD) return retVal;
91718retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12139LU), false);
91719if (retVal != UA_STATUSCODE_GOOD) return retVal;
91720retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12140LU), false);
91721if (retVal != UA_STATUSCODE_GOOD) return retVal;
91722retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12141LU), false);
91723if (retVal != UA_STATUSCODE_GOOD) return retVal;
91724retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12861LU), false);
91725if (retVal != UA_STATUSCODE_GOOD) return retVal;
91726retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12862LU), false);
91727if (retVal != UA_STATUSCODE_GOOD) return retVal;
91728retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12863LU), false);
91729if (retVal != UA_STATUSCODE_GOOD) return retVal;
91730retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12864LU), false);
91731if (retVal != UA_STATUSCODE_GOOD) return retVal;
91732retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12865LU), false);
91733if (retVal != UA_STATUSCODE_GOOD) return retVal;
91734retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12866LU), false);
91735if (retVal != UA_STATUSCODE_GOOD) return retVal;
91736retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12867LU), false);
91737if (retVal != UA_STATUSCODE_GOOD) return retVal;
91738retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12868LU), false);
91739if (retVal != UA_STATUSCODE_GOOD) return retVal;
91740retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12869LU), false);
91741if (retVal != UA_STATUSCODE_GOOD) return retVal;
91742retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2744LU), false);
91743if (retVal != UA_STATUSCODE_GOOD) return retVal;
91744retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3129LU), false);
91745if (retVal != UA_STATUSCODE_GOOD) return retVal;
91746retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3130LU), false);
91747if (retVal != UA_STATUSCODE_GOOD) return retVal;
91748retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2025LU), false);
91749if (retVal != UA_STATUSCODE_GOOD) return retVal;
91750retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12817LU), false);
91751if (retVal != UA_STATUSCODE_GOOD) return retVal;
91752retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12818LU), false);
91753if (retVal != UA_STATUSCODE_GOOD) return retVal;
91754retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12819LU), false);
91755if (retVal != UA_STATUSCODE_GOOD) return retVal;
91756retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12820LU), false);
91757if (retVal != UA_STATUSCODE_GOOD) return retVal;
91758retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12821LU), false);
91759if (retVal != UA_STATUSCODE_GOOD) return retVal;
91760retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12822LU), false);
91761if (retVal != UA_STATUSCODE_GOOD) return retVal;
91762retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12823LU), false);
91763if (retVal != UA_STATUSCODE_GOOD) return retVal;
91764retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12824LU), false);
91765if (retVal != UA_STATUSCODE_GOOD) return retVal;
91766retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12825LU), false);
91767if (retVal != UA_STATUSCODE_GOOD) return retVal;
91768retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12826LU), false);
91769if (retVal != UA_STATUSCODE_GOOD) return retVal;
91770retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12827LU), false);
91771if (retVal != UA_STATUSCODE_GOOD) return retVal;
91772retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12828LU), false);
91773if (retVal != UA_STATUSCODE_GOOD) return retVal;
91774retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12829LU), false);
91775if (retVal != UA_STATUSCODE_GOOD) return retVal;
91776retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12830LU), false);
91777if (retVal != UA_STATUSCODE_GOOD) return retVal;
91778retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12831LU), false);
91779if (retVal != UA_STATUSCODE_GOOD) return retVal;
91780retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12832LU), false);
91781if (retVal != UA_STATUSCODE_GOOD) return retVal;
91782retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12833LU), false);
91783if (retVal != UA_STATUSCODE_GOOD) return retVal;
91784retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12834LU), false);
91785if (retVal != UA_STATUSCODE_GOOD) return retVal;
91786retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12835LU), false);
91787if (retVal != UA_STATUSCODE_GOOD) return retVal;
91788retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12836LU), false);
91789if (retVal != UA_STATUSCODE_GOOD) return retVal;
91790retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12837LU), false);
91791if (retVal != UA_STATUSCODE_GOOD) return retVal;
91792retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12838LU), false);
91793if (retVal != UA_STATUSCODE_GOOD) return retVal;
91794retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12839LU), false);
91795if (retVal != UA_STATUSCODE_GOOD) return retVal;
91796retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12840LU), false);
91797if (retVal != UA_STATUSCODE_GOOD) return retVal;
91798retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12841LU), false);
91799if (retVal != UA_STATUSCODE_GOOD) return retVal;
91800retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12842LU), false);
91801if (retVal != UA_STATUSCODE_GOOD) return retVal;
91802retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12843LU), false);
91803if (retVal != UA_STATUSCODE_GOOD) return retVal;
91804retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12844LU), false);
91805if (retVal != UA_STATUSCODE_GOOD) return retVal;
91806retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12845LU), false);
91807if (retVal != UA_STATUSCODE_GOOD) return retVal;
91808retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12846LU), false);
91809if (retVal != UA_STATUSCODE_GOOD) return retVal;
91810retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12847LU), false);
91811if (retVal != UA_STATUSCODE_GOOD) return retVal;
91812retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12848LU), false);
91813if (retVal != UA_STATUSCODE_GOOD) return retVal;
91814retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12849LU), false);
91815if (retVal != UA_STATUSCODE_GOOD) return retVal;
91816retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12850LU), false);
91817if (retVal != UA_STATUSCODE_GOOD) return retVal;
91818retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12851LU), false);
91819if (retVal != UA_STATUSCODE_GOOD) return retVal;
91820retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12852LU), false);
91821if (retVal != UA_STATUSCODE_GOOD) return retVal;
91822retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12853LU), false);
91823if (retVal != UA_STATUSCODE_GOOD) return retVal;
91824retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12854LU), false);
91825if (retVal != UA_STATUSCODE_GOOD) return retVal;
91826retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12855LU), false);
91827if (retVal != UA_STATUSCODE_GOOD) return retVal;
91828retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12856LU), false);
91829if (retVal != UA_STATUSCODE_GOOD) return retVal;
91830retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12857LU), false);
91831if (retVal != UA_STATUSCODE_GOOD) return retVal;
91832retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12858LU), false);
91833if (retVal != UA_STATUSCODE_GOOD) return retVal;
91834retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12859LU), false);
91835if (retVal != UA_STATUSCODE_GOOD) return retVal;
91836retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12780LU), false);
91837if (retVal != UA_STATUSCODE_GOOD) return retVal;
91838retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12781LU), false);
91839if (retVal != UA_STATUSCODE_GOOD) return retVal;
91840retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12782LU), false);
91841if (retVal != UA_STATUSCODE_GOOD) return retVal;
91842retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12783LU), false);
91843if (retVal != UA_STATUSCODE_GOOD) return retVal;
91844retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2166LU), false);
91845if (retVal != UA_STATUSCODE_GOOD) return retVal;
91846retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11697LU), false);
91847if (retVal != UA_STATUSCODE_GOOD) return retVal;
91848retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11698LU), false);
91849if (retVal != UA_STATUSCODE_GOOD) return retVal;
91850retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11699LU), false);
91851if (retVal != UA_STATUSCODE_GOOD) return retVal;
91852retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2151LU), false);
91853if (retVal != UA_STATUSCODE_GOOD) return retVal;
91854retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2152LU), false);
91855if (retVal != UA_STATUSCODE_GOOD) return retVal;
91856retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2153LU), false);
91857if (retVal != UA_STATUSCODE_GOOD) return retVal;
91858retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2154LU), false);
91859if (retVal != UA_STATUSCODE_GOOD) return retVal;
91860retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2155LU), false);
91861if (retVal != UA_STATUSCODE_GOOD) return retVal;
91862retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2156LU), false);
91863if (retVal != UA_STATUSCODE_GOOD) return retVal;
91864retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2157LU), false);
91865if (retVal != UA_STATUSCODE_GOOD) return retVal;
91866retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2159LU), false);
91867if (retVal != UA_STATUSCODE_GOOD) return retVal;
91868retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2160LU), false);
91869if (retVal != UA_STATUSCODE_GOOD) return retVal;
91870retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2161LU), false);
91871if (retVal != UA_STATUSCODE_GOOD) return retVal;
91872retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2162LU), false);
91873if (retVal != UA_STATUSCODE_GOOD) return retVal;
91874retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2163LU), false);
91875if (retVal != UA_STATUSCODE_GOOD) return retVal;
91876retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 7595LU), false);
91877if (retVal != UA_STATUSCODE_GOOD) return retVal;
91878retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 7597LU), false);
91879if (retVal != UA_STATUSCODE_GOOD) return retVal;
91880retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2030LU), false);
91881if (retVal != UA_STATUSCODE_GOOD) return retVal;
91882retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3131LU), false);
91883if (retVal != UA_STATUSCODE_GOOD) return retVal;
91884retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3132LU), false);
91885if (retVal != UA_STATUSCODE_GOOD) return retVal;
91886retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3133LU), false);
91887if (retVal != UA_STATUSCODE_GOOD) return retVal;
91888retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3134LU), false);
91889if (retVal != UA_STATUSCODE_GOOD) return retVal;
91890retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3135LU), false);
91891if (retVal != UA_STATUSCODE_GOOD) return retVal;
91892retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3136LU), false);
91893if (retVal != UA_STATUSCODE_GOOD) return retVal;
91894retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3137LU), false);
91895if (retVal != UA_STATUSCODE_GOOD) return retVal;
91896retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3138LU), false);
91897if (retVal != UA_STATUSCODE_GOOD) return retVal;
91898retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3139LU), false);
91899if (retVal != UA_STATUSCODE_GOOD) return retVal;
91900retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3140LU), false);
91901if (retVal != UA_STATUSCODE_GOOD) return retVal;
91902retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3141LU), false);
91903if (retVal != UA_STATUSCODE_GOOD) return retVal;
91904retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3142LU), false);
91905if (retVal != UA_STATUSCODE_GOOD) return retVal;
91906retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3143LU), false);
91907if (retVal != UA_STATUSCODE_GOOD) return retVal;
91908retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8898LU), false);
91909if (retVal != UA_STATUSCODE_GOOD) return retVal;
91910retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11891LU), false);
91911if (retVal != UA_STATUSCODE_GOOD) return retVal;
91912retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3151LU), false);
91913if (retVal != UA_STATUSCODE_GOOD) return retVal;
91914retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3152LU), false);
91915if (retVal != UA_STATUSCODE_GOOD) return retVal;
91916retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3153LU), false);
91917if (retVal != UA_STATUSCODE_GOOD) return retVal;
91918retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3154LU), false);
91919if (retVal != UA_STATUSCODE_GOOD) return retVal;
91920retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3155LU), false);
91921if (retVal != UA_STATUSCODE_GOOD) return retVal;
91922retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3156LU), false);
91923if (retVal != UA_STATUSCODE_GOOD) return retVal;
91924retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3157LU), false);
91925if (retVal != UA_STATUSCODE_GOOD) return retVal;
91926retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3158LU), false);
91927if (retVal != UA_STATUSCODE_GOOD) return retVal;
91928retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3159LU), false);
91929if (retVal != UA_STATUSCODE_GOOD) return retVal;
91930retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3160LU), false);
91931if (retVal != UA_STATUSCODE_GOOD) return retVal;
91932retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3161LU), false);
91933if (retVal != UA_STATUSCODE_GOOD) return retVal;
91934retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3162LU), false);
91935if (retVal != UA_STATUSCODE_GOOD) return retVal;
91936retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3163LU), false);
91937if (retVal != UA_STATUSCODE_GOOD) return retVal;
91938retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3164LU), false);
91939if (retVal != UA_STATUSCODE_GOOD) return retVal;
91940retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3165LU), false);
91941if (retVal != UA_STATUSCODE_GOOD) return retVal;
91942retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3166LU), false);
91943if (retVal != UA_STATUSCODE_GOOD) return retVal;
91944retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3167LU), false);
91945if (retVal != UA_STATUSCODE_GOOD) return retVal;
91946retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3168LU), false);
91947if (retVal != UA_STATUSCODE_GOOD) return retVal;
91948retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3169LU), false);
91949if (retVal != UA_STATUSCODE_GOOD) return retVal;
91950retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3170LU), false);
91951if (retVal != UA_STATUSCODE_GOOD) return retVal;
91952retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3171LU), false);
91953if (retVal != UA_STATUSCODE_GOOD) return retVal;
91954retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3172LU), false);
91955if (retVal != UA_STATUSCODE_GOOD) return retVal;
91956retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3173LU), false);
91957if (retVal != UA_STATUSCODE_GOOD) return retVal;
91958retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3174LU), false);
91959if (retVal != UA_STATUSCODE_GOOD) return retVal;
91960retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3175LU), false);
91961if (retVal != UA_STATUSCODE_GOOD) return retVal;
91962retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3176LU), false);
91963if (retVal != UA_STATUSCODE_GOOD) return retVal;
91964retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3177LU), false);
91965if (retVal != UA_STATUSCODE_GOOD) return retVal;
91966retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3178LU), false);
91967if (retVal != UA_STATUSCODE_GOOD) return retVal;
91968retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2031LU), false);
91969if (retVal != UA_STATUSCODE_GOOD) return retVal;
91970retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3179LU), false);
91971if (retVal != UA_STATUSCODE_GOOD) return retVal;
91972retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3180LU), false);
91973if (retVal != UA_STATUSCODE_GOOD) return retVal;
91974retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3181LU), false);
91975if (retVal != UA_STATUSCODE_GOOD) return retVal;
91976retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3182LU), false);
91977if (retVal != UA_STATUSCODE_GOOD) return retVal;
91978retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3183LU), false);
91979if (retVal != UA_STATUSCODE_GOOD) return retVal;
91980retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3184LU), false);
91981if (retVal != UA_STATUSCODE_GOOD) return retVal;
91982retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3185LU), false);
91983if (retVal != UA_STATUSCODE_GOOD) return retVal;
91984retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3186LU), false);
91985if (retVal != UA_STATUSCODE_GOOD) return retVal;
91986retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3187LU), false);
91987if (retVal != UA_STATUSCODE_GOOD) return retVal;
91988retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2245LU), false);
91989if (retVal != UA_STATUSCODE_GOOD) return retVal;
91990retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2246LU), false);
91991if (retVal != UA_STATUSCODE_GOOD) return retVal;
91992retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2247LU), false);
91993if (retVal != UA_STATUSCODE_GOOD) return retVal;
91994retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2248LU), false);
91995if (retVal != UA_STATUSCODE_GOOD) return retVal;
91996retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2249LU), false);
91997if (retVal != UA_STATUSCODE_GOOD) return retVal;
91998retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2250LU), false);
91999if (retVal != UA_STATUSCODE_GOOD) return retVal;
92000retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2251LU), false);
92001if (retVal != UA_STATUSCODE_GOOD) return retVal;
92002retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2252LU), false);
92003if (retVal != UA_STATUSCODE_GOOD) return retVal;
92004retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3058LU), false);
92005if (retVal != UA_STATUSCODE_GOOD) return retVal;
92006retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2032LU), false);
92007if (retVal != UA_STATUSCODE_GOOD) return retVal;
92008retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12785LU), false);
92009if (retVal != UA_STATUSCODE_GOOD) return retVal;
92010retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12786LU), false);
92011if (retVal != UA_STATUSCODE_GOOD) return retVal;
92012retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12787LU), false);
92013if (retVal != UA_STATUSCODE_GOOD) return retVal;
92014retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12788LU), false);
92015if (retVal != UA_STATUSCODE_GOOD) return retVal;
92016retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12789LU), false);
92017if (retVal != UA_STATUSCODE_GOOD) return retVal;
92018retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12790LU), false);
92019if (retVal != UA_STATUSCODE_GOOD) return retVal;
92020retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12791LU), false);
92021if (retVal != UA_STATUSCODE_GOOD) return retVal;
92022retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12792LU), false);
92023if (retVal != UA_STATUSCODE_GOOD) return retVal;
92024retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12793LU), false);
92025if (retVal != UA_STATUSCODE_GOOD) return retVal;
92026retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12794LU), false);
92027if (retVal != UA_STATUSCODE_GOOD) return retVal;
92028retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12795LU), false);
92029if (retVal != UA_STATUSCODE_GOOD) return retVal;
92030retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12796LU), false);
92031if (retVal != UA_STATUSCODE_GOOD) return retVal;
92032retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12797LU), false);
92033if (retVal != UA_STATUSCODE_GOOD) return retVal;
92034retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12798LU), false);
92035if (retVal != UA_STATUSCODE_GOOD) return retVal;
92036retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12799LU), false);
92037if (retVal != UA_STATUSCODE_GOOD) return retVal;
92038retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12800LU), false);
92039if (retVal != UA_STATUSCODE_GOOD) return retVal;
92040retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12801LU), false);
92041if (retVal != UA_STATUSCODE_GOOD) return retVal;
92042retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12802LU), false);
92043if (retVal != UA_STATUSCODE_GOOD) return retVal;
92044retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12803LU), false);
92045if (retVal != UA_STATUSCODE_GOOD) return retVal;
92046retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12804LU), false);
92047if (retVal != UA_STATUSCODE_GOOD) return retVal;
92048retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12805LU), false);
92049if (retVal != UA_STATUSCODE_GOOD) return retVal;
92050retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12806LU), false);
92051if (retVal != UA_STATUSCODE_GOOD) return retVal;
92052retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12807LU), false);
92053if (retVal != UA_STATUSCODE_GOOD) return retVal;
92054retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12808LU), false);
92055if (retVal != UA_STATUSCODE_GOOD) return retVal;
92056retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12809LU), false);
92057if (retVal != UA_STATUSCODE_GOOD) return retVal;
92058retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12810LU), false);
92059if (retVal != UA_STATUSCODE_GOOD) return retVal;
92060retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12811LU), false);
92061if (retVal != UA_STATUSCODE_GOOD) return retVal;
92062retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12812LU), false);
92063if (retVal != UA_STATUSCODE_GOOD) return retVal;
92064retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12813LU), false);
92065if (retVal != UA_STATUSCODE_GOOD) return retVal;
92066retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12814LU), false);
92067if (retVal != UA_STATUSCODE_GOOD) return retVal;
92068retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12815LU), false);
92069if (retVal != UA_STATUSCODE_GOOD) return retVal;
92070retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2173LU), false);
92071if (retVal != UA_STATUSCODE_GOOD) return retVal;
92072retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2174LU), false);
92073if (retVal != UA_STATUSCODE_GOOD) return retVal;
92074retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2175LU), false);
92075if (retVal != UA_STATUSCODE_GOOD) return retVal;
92076retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2176LU), false);
92077if (retVal != UA_STATUSCODE_GOOD) return retVal;
92078retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2177LU), false);
92079if (retVal != UA_STATUSCODE_GOOD) return retVal;
92080retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8888LU), false);
92081if (retVal != UA_STATUSCODE_GOOD) return retVal;
92082retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2179LU), false);
92083if (retVal != UA_STATUSCODE_GOOD) return retVal;
92084retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2180LU), false);
92085if (retVal != UA_STATUSCODE_GOOD) return retVal;
92086retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2181LU), false);
92087if (retVal != UA_STATUSCODE_GOOD) return retVal;
92088retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2182LU), false);
92089if (retVal != UA_STATUSCODE_GOOD) return retVal;
92090retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2183LU), false);
92091if (retVal != UA_STATUSCODE_GOOD) return retVal;
92092retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2184LU), false);
92093if (retVal != UA_STATUSCODE_GOOD) return retVal;
92094retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2185LU), false);
92095if (retVal != UA_STATUSCODE_GOOD) return retVal;
92096retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2186LU), false);
92097if (retVal != UA_STATUSCODE_GOOD) return retVal;
92098retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2187LU), false);
92099if (retVal != UA_STATUSCODE_GOOD) return retVal;
92100retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2188LU), false);
92101if (retVal != UA_STATUSCODE_GOOD) return retVal;
92102retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2189LU), false);
92103if (retVal != UA_STATUSCODE_GOOD) return retVal;
92104retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2190LU), false);
92105if (retVal != UA_STATUSCODE_GOOD) return retVal;
92106retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2191LU), false);
92107if (retVal != UA_STATUSCODE_GOOD) return retVal;
92108retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2998LU), false);
92109if (retVal != UA_STATUSCODE_GOOD) return retVal;
92110retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2193LU), false);
92111if (retVal != UA_STATUSCODE_GOOD) return retVal;
92112retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8889LU), false);
92113if (retVal != UA_STATUSCODE_GOOD) return retVal;
92114retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8890LU), false);
92115if (retVal != UA_STATUSCODE_GOOD) return retVal;
92116retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8891LU), false);
92117if (retVal != UA_STATUSCODE_GOOD) return retVal;
92118retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8892LU), false);
92119if (retVal != UA_STATUSCODE_GOOD) return retVal;
92120retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8893LU), false);
92121if (retVal != UA_STATUSCODE_GOOD) return retVal;
92122retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8894LU), false);
92123if (retVal != UA_STATUSCODE_GOOD) return retVal;
92124retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8895LU), false);
92125if (retVal != UA_STATUSCODE_GOOD) return retVal;
92126retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8896LU), false);
92127if (retVal != UA_STATUSCODE_GOOD) return retVal;
92128retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8897LU), false);
92129if (retVal != UA_STATUSCODE_GOOD) return retVal;
92130retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8902LU), false);
92131if (retVal != UA_STATUSCODE_GOOD) return retVal;
92132retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2198LU), false);
92133if (retVal != UA_STATUSCODE_GOOD) return retVal;
92134retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2199LU), false);
92135if (retVal != UA_STATUSCODE_GOOD) return retVal;
92136retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2200LU), false);
92137if (retVal != UA_STATUSCODE_GOOD) return retVal;
92138retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2201LU), false);
92139if (retVal != UA_STATUSCODE_GOOD) return retVal;
92140retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2202LU), false);
92141if (retVal != UA_STATUSCODE_GOOD) return retVal;
92142retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2203LU), false);
92143if (retVal != UA_STATUSCODE_GOOD) return retVal;
92144retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2204LU), false);
92145if (retVal != UA_STATUSCODE_GOOD) return retVal;
92146retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3050LU), false);
92147if (retVal != UA_STATUSCODE_GOOD) return retVal;
92148retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2205LU), false);
92149if (retVal != UA_STATUSCODE_GOOD) return retVal;
92150retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2206LU), false);
92151if (retVal != UA_STATUSCODE_GOOD) return retVal;
92152retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2207LU), false);
92153if (retVal != UA_STATUSCODE_GOOD) return retVal;
92154retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2208LU), false);
92155if (retVal != UA_STATUSCODE_GOOD) return retVal;
92156retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2209LU), false);
92157if (retVal != UA_STATUSCODE_GOOD) return retVal;
92158retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8900LU), false);
92159if (retVal != UA_STATUSCODE_GOOD) return retVal;
92160retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11892LU), false);
92161if (retVal != UA_STATUSCODE_GOOD) return retVal;
92162retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2217LU), false);
92163if (retVal != UA_STATUSCODE_GOOD) return retVal;
92164retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2218LU), false);
92165if (retVal != UA_STATUSCODE_GOOD) return retVal;
92166retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2219LU), false);
92167if (retVal != UA_STATUSCODE_GOOD) return retVal;
92168retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2220LU), false);
92169if (retVal != UA_STATUSCODE_GOOD) return retVal;
92170retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2221LU), false);
92171if (retVal != UA_STATUSCODE_GOOD) return retVal;
92172retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2222LU), false);
92173if (retVal != UA_STATUSCODE_GOOD) return retVal;
92174retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2223LU), false);
92175if (retVal != UA_STATUSCODE_GOOD) return retVal;
92176retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2224LU), false);
92177if (retVal != UA_STATUSCODE_GOOD) return retVal;
92178retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2225LU), false);
92179if (retVal != UA_STATUSCODE_GOOD) return retVal;
92180retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2226LU), false);
92181if (retVal != UA_STATUSCODE_GOOD) return retVal;
92182retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2227LU), false);
92183if (retVal != UA_STATUSCODE_GOOD) return retVal;
92184retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2228LU), false);
92185if (retVal != UA_STATUSCODE_GOOD) return retVal;
92186retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2229LU), false);
92187if (retVal != UA_STATUSCODE_GOOD) return retVal;
92188retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2230LU), false);
92189if (retVal != UA_STATUSCODE_GOOD) return retVal;
92190retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2231LU), false);
92191if (retVal != UA_STATUSCODE_GOOD) return retVal;
92192retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2232LU), false);
92193if (retVal != UA_STATUSCODE_GOOD) return retVal;
92194retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2233LU), false);
92195if (retVal != UA_STATUSCODE_GOOD) return retVal;
92196retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2234LU), false);
92197if (retVal != UA_STATUSCODE_GOOD) return retVal;
92198retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2235LU), false);
92199if (retVal != UA_STATUSCODE_GOOD) return retVal;
92200retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2236LU), false);
92201if (retVal != UA_STATUSCODE_GOOD) return retVal;
92202retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2237LU), false);
92203if (retVal != UA_STATUSCODE_GOOD) return retVal;
92204retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2238LU), false);
92205if (retVal != UA_STATUSCODE_GOOD) return retVal;
92206retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2239LU), false);
92207if (retVal != UA_STATUSCODE_GOOD) return retVal;
92208retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2240LU), false);
92209if (retVal != UA_STATUSCODE_GOOD) return retVal;
92210retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2241LU), false);
92211if (retVal != UA_STATUSCODE_GOOD) return retVal;
92212retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2242LU), false);
92213if (retVal != UA_STATUSCODE_GOOD) return retVal;
92214retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2730LU), false);
92215if (retVal != UA_STATUSCODE_GOOD) return retVal;
92216retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2731LU), false);
92217if (retVal != UA_STATUSCODE_GOOD) return retVal;
92218retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2042LU), false);
92219if (retVal != UA_STATUSCODE_GOOD) return retVal;
92220retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2043LU), false);
92221if (retVal != UA_STATUSCODE_GOOD) return retVal;
92222retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2044LU), false);
92223if (retVal != UA_STATUSCODE_GOOD) return retVal;
92224retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2045LU), false);
92225if (retVal != UA_STATUSCODE_GOOD) return retVal;
92226retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2046LU), false);
92227if (retVal != UA_STATUSCODE_GOOD) return retVal;
92228retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2047LU), false);
92229if (retVal != UA_STATUSCODE_GOOD) return retVal;
92230retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2050LU), false);
92231if (retVal != UA_STATUSCODE_GOOD) return retVal;
92232retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2051LU), false);
92233if (retVal != UA_STATUSCODE_GOOD) return retVal;
92234retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2134LU), false);
92235if (retVal != UA_STATUSCODE_GOOD) return retVal;
92236retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17222LU), false);
92237if (retVal != UA_STATUSCODE_GOOD) return retVal;
92238retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11851LU), false);
92239if (retVal != UA_STATUSCODE_GOOD) return retVal;
92240retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2053LU), false);
92241if (retVal != UA_STATUSCODE_GOOD) return retVal;
92242retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2054LU), false);
92243if (retVal != UA_STATUSCODE_GOOD) return retVal;
92244retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2055LU), false);
92245if (retVal != UA_STATUSCODE_GOOD) return retVal;
92246retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2056LU), false);
92247if (retVal != UA_STATUSCODE_GOOD) return retVal;
92248retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2057LU), false);
92249if (retVal != UA_STATUSCODE_GOOD) return retVal;
92250retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2128LU), false);
92251if (retVal != UA_STATUSCODE_GOOD) return retVal;
92252retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2129LU), false);
92253if (retVal != UA_STATUSCODE_GOOD) return retVal;
92254retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9003LU), false);
92255if (retVal != UA_STATUSCODE_GOOD) return retVal;
92256retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2756LU), false);
92257if (retVal != UA_STATUSCODE_GOOD) return retVal;
92258retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8996LU), false);
92259if (retVal != UA_STATUSCODE_GOOD) return retVal;
92260retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11112LU), false);
92261if (retVal != UA_STATUSCODE_GOOD) return retVal;
92262retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11113LU), false);
92263if (retVal != UA_STATUSCODE_GOOD) return retVal;
92264retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9009LU), false);
92265if (retVal != UA_STATUSCODE_GOOD) return retVal;
92266retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9010LU), false);
92267if (retVal != UA_STATUSCODE_GOOD) return retVal;
92268retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3874LU), false);
92269if (retVal != UA_STATUSCODE_GOOD) return retVal;
92270retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9011LU), false);
92271if (retVal != UA_STATUSCODE_GOOD) return retVal;
92272retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9012LU), false);
92273if (retVal != UA_STATUSCODE_GOOD) return retVal;
92274retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9020LU), false);
92275if (retVal != UA_STATUSCODE_GOOD) return retVal;
92276retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9021LU), false);
92277if (retVal != UA_STATUSCODE_GOOD) return retVal;
92278retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9022LU), false);
92279if (retVal != UA_STATUSCODE_GOOD) return retVal;
92280retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9023LU), false);
92281if (retVal != UA_STATUSCODE_GOOD) return retVal;
92282retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9024LU), false);
92283if (retVal != UA_STATUSCODE_GOOD) return retVal;
92284retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9025LU), false);
92285if (retVal != UA_STATUSCODE_GOOD) return retVal;
92286retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9026LU), false);
92287if (retVal != UA_STATUSCODE_GOOD) return retVal;
92288retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9028LU), false);
92289if (retVal != UA_STATUSCODE_GOOD) return retVal;
92290retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9027LU), false);
92291if (retVal != UA_STATUSCODE_GOOD) return retVal;
92292retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9029LU), false);
92293if (retVal != UA_STATUSCODE_GOOD) return retVal;
92294retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 9030LU), false);
92295if (retVal != UA_STATUSCODE_GOOD) return retVal;
92296retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 3876LU), false);
92297if (retVal != UA_STATUSCODE_GOOD) return retVal;
92298retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12913LU), false);
92299if (retVal != UA_STATUSCODE_GOOD) return retVal;
92300retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17479LU), false);
92301if (retVal != UA_STATUSCODE_GOOD) return retVal;
92302retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14494LU), false);
92303if (retVal != UA_STATUSCODE_GOOD) return retVal;
92304retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14495LU), false);
92305if (retVal != UA_STATUSCODE_GOOD) return retVal;
92306retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14500LU), false);
92307if (retVal != UA_STATUSCODE_GOOD) return retVal;
92308retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 16995LU), false);
92309if (retVal != UA_STATUSCODE_GOOD) return retVal;
92310retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 16996LU), false);
92311if (retVal != UA_STATUSCODE_GOOD) return retVal;
92312retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17007LU), false);
92313if (retVal != UA_STATUSCODE_GOOD) return retVal;
92314retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14434LU), false);
92315if (retVal != UA_STATUSCODE_GOOD) return retVal;
92316retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15844LU), false);
92317if (retVal != UA_STATUSCODE_GOOD) return retVal;
92318retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15845LU), false);
92319if (retVal != UA_STATUSCODE_GOOD) return retVal;
92320retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14519LU), false);
92321if (retVal != UA_STATUSCODE_GOOD) return retVal;
92322retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15229LU), false);
92323if (retVal != UA_STATUSCODE_GOOD) return retVal;
92324retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14648LU), false);
92325if (retVal != UA_STATUSCODE_GOOD) return retVal;
92326retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15584LU), false);
92327if (retVal != UA_STATUSCODE_GOOD) return retVal;
92328retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14548LU), false);
92329if (retVal != UA_STATUSCODE_GOOD) return retVal;
92330retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14556LU), false);
92331if (retVal != UA_STATUSCODE_GOOD) return retVal;
92332retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14557LU), false);
92333if (retVal != UA_STATUSCODE_GOOD) return retVal;
92334retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14559LU), false);
92335if (retVal != UA_STATUSCODE_GOOD) return retVal;
92336retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14560LU), false);
92337if (retVal != UA_STATUSCODE_GOOD) return retVal;
92338retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17485LU), false);
92339if (retVal != UA_STATUSCODE_GOOD) return retVal;
92340retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14221LU), false);
92341if (retVal != UA_STATUSCODE_GOOD) return retVal;
92342retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17202LU), false);
92343if (retVal != UA_STATUSCODE_GOOD) return retVal;
92344retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21146LU), false);
92345if (retVal != UA_STATUSCODE_GOOD) return retVal;
92346retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21149LU), false);
92347if (retVal != UA_STATUSCODE_GOOD) return retVal;
92348retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14600LU), false);
92349if (retVal != UA_STATUSCODE_GOOD) return retVal;
92350retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14601LU), false);
92351if (retVal != UA_STATUSCODE_GOOD) return retVal;
92352retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17428LU), false);
92353if (retVal != UA_STATUSCODE_GOOD) return retVal;
92354retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17456LU), false);
92355if (retVal != UA_STATUSCODE_GOOD) return retVal;
92356retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17507LU), false);
92357if (retVal != UA_STATUSCODE_GOOD) return retVal;
92358retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17508LU), false);
92359if (retVal != UA_STATUSCODE_GOOD) return retVal;
92360retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14226LU), false);
92361if (retVal != UA_STATUSCODE_GOOD) return retVal;
92362retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17724LU), false);
92363if (retVal != UA_STATUSCODE_GOOD) return retVal;
92364retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17976LU), false);
92365if (retVal != UA_STATUSCODE_GOOD) return retVal;
92366retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17987LU), false);
92367if (retVal != UA_STATUSCODE_GOOD) return retVal;
92368retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17993LU), false);
92369if (retVal != UA_STATUSCODE_GOOD) return retVal;
92370retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17736LU), false);
92371if (retVal != UA_STATUSCODE_GOOD) return retVal;
92372retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17737LU), false);
92373if (retVal != UA_STATUSCODE_GOOD) return retVal;
92374retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17738LU), false);
92375if (retVal != UA_STATUSCODE_GOOD) return retVal;
92376retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17739LU), false);
92377if (retVal != UA_STATUSCODE_GOOD) return retVal;
92378retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17740LU), false);
92379if (retVal != UA_STATUSCODE_GOOD) return retVal;
92380retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17306LU), false);
92381if (retVal != UA_STATUSCODE_GOOD) return retVal;
92382retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17710LU), false);
92383if (retVal != UA_STATUSCODE_GOOD) return retVal;
92384retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21092LU), false);
92385if (retVal != UA_STATUSCODE_GOOD) return retVal;
92386retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21093LU), false);
92387if (retVal != UA_STATUSCODE_GOOD) return retVal;
92388retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17493LU), false);
92389if (retVal != UA_STATUSCODE_GOOD) return retVal;
92390retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23798LU), false);
92391if (retVal != UA_STATUSCODE_GOOD) return retVal;
92392retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23799LU), false);
92393if (retVal != UA_STATUSCODE_GOOD) return retVal;
92394retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23801LU), false);
92395if (retVal != UA_STATUSCODE_GOOD) return retVal;
92396retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23803LU), false);
92397if (retVal != UA_STATUSCODE_GOOD) return retVal;
92398retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23804LU), false);
92399if (retVal != UA_STATUSCODE_GOOD) return retVal;
92400retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23806LU), false);
92401if (retVal != UA_STATUSCODE_GOOD) return retVal;
92402retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23808LU), false);
92403if (retVal != UA_STATUSCODE_GOOD) return retVal;
92404retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23809LU), false);
92405if (retVal != UA_STATUSCODE_GOOD) return retVal;
92406retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23810LU), false);
92407if (retVal != UA_STATUSCODE_GOOD) return retVal;
92408retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23812LU), false);
92409if (retVal != UA_STATUSCODE_GOOD) return retVal;
92410retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23813LU), false);
92411if (retVal != UA_STATUSCODE_GOOD) return retVal;
92412retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23815LU), false);
92413if (retVal != UA_STATUSCODE_GOOD) return retVal;
92414retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23817LU), false);
92415if (retVal != UA_STATUSCODE_GOOD) return retVal;
92416retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23818LU), false);
92417if (retVal != UA_STATUSCODE_GOOD) return retVal;
92418retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23820LU), false);
92419if (retVal != UA_STATUSCODE_GOOD) return retVal;
92420retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23829LU), false);
92421if (retVal != UA_STATUSCODE_GOOD) return retVal;
92422retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23830LU), false);
92423if (retVal != UA_STATUSCODE_GOOD) return retVal;
92424retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23831LU), false);
92425if (retVal != UA_STATUSCODE_GOOD) return retVal;
92426retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17744LU), false);
92427if (retVal != UA_STATUSCODE_GOOD) return retVal;
92428retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17745LU), false);
92429if (retVal != UA_STATUSCODE_GOOD) return retVal;
92430retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17490LU), false);
92431if (retVal != UA_STATUSCODE_GOOD) return retVal;
92432retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17749LU), false);
92433if (retVal != UA_STATUSCODE_GOOD) return retVal;
92434retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17750LU), false);
92435if (retVal != UA_STATUSCODE_GOOD) return retVal;
92436retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14644LU), false);
92437if (retVal != UA_STATUSCODE_GOOD) return retVal;
92438retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17632LU), false);
92439if (retVal != UA_STATUSCODE_GOOD) return retVal;
92440retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14595LU), false);
92441if (retVal != UA_STATUSCODE_GOOD) return retVal;
92442retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14418LU), false);
92443if (retVal != UA_STATUSCODE_GOOD) return retVal;
92444retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17478LU), false);
92445if (retVal != UA_STATUSCODE_GOOD) return retVal;
92446retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14423LU), false);
92447if (retVal != UA_STATUSCODE_GOOD) return retVal;
92448retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15533LU), false);
92449if (retVal != UA_STATUSCODE_GOOD) return retVal;
92450retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 16599LU), false);
92451if (retVal != UA_STATUSCODE_GOOD) return retVal;
92452retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 16600LU), false);
92453if (retVal != UA_STATUSCODE_GOOD) return retVal;
92454retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14433LU), false);
92455if (retVal != UA_STATUSCODE_GOOD) return retVal;
92456retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17292LU), false);
92457if (retVal != UA_STATUSCODE_GOOD) return retVal;
92458retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17706LU), false);
92459if (retVal != UA_STATUSCODE_GOOD) return retVal;
92460retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21083LU), false);
92461if (retVal != UA_STATUSCODE_GOOD) return retVal;
92462retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21084LU), false);
92463if (retVal != UA_STATUSCODE_GOOD) return retVal;
92464retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21086LU), false);
92465if (retVal != UA_STATUSCODE_GOOD) return retVal;
92466retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21097LU), false);
92467if (retVal != UA_STATUSCODE_GOOD) return retVal;
92468retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21098LU), false);
92469if (retVal != UA_STATUSCODE_GOOD) return retVal;
92470retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21099LU), false);
92471if (retVal != UA_STATUSCODE_GOOD) return retVal;
92472retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21100LU), false);
92473if (retVal != UA_STATUSCODE_GOOD) return retVal;
92474retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21101LU), false);
92475if (retVal != UA_STATUSCODE_GOOD) return retVal;
92476retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21102LU), false);
92477if (retVal != UA_STATUSCODE_GOOD) return retVal;
92478retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17494LU), false);
92479if (retVal != UA_STATUSCODE_GOOD) return retVal;
92480retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15311LU), false);
92481if (retVal != UA_STATUSCODE_GOOD) return retVal;
92482retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 21103LU), false);
92483if (retVal != UA_STATUSCODE_GOOD) return retVal;
92484retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15316LU), false);
92485if (retVal != UA_STATUSCODE_GOOD) return retVal;
92486retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15114LU), false);
92487if (retVal != UA_STATUSCODE_GOOD) return retVal;
92488retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15116LU), false);
92489if (retVal != UA_STATUSCODE_GOOD) return retVal;
92490retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15117LU), false);
92491if (retVal != UA_STATUSCODE_GOOD) return retVal;
92492retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15119LU), false);
92493if (retVal != UA_STATUSCODE_GOOD) return retVal;
92494retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 15120LU), false);
92495if (retVal != UA_STATUSCODE_GOOD) return retVal;
92496retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2369LU), false);
92497if (retVal != UA_STATUSCODE_GOOD) return retVal;
92498retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2374LU), false);
92499if (retVal != UA_STATUSCODE_GOOD) return retVal;
92500retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2375LU), false);
92501if (retVal != UA_STATUSCODE_GOOD) return retVal;
92502retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 2377LU), false);
92503if (retVal != UA_STATUSCODE_GOOD) return retVal;
92504retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11241LU), false);
92505if (retVal != UA_STATUSCODE_GOOD) return retVal;
92506retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 11461LU), false);
92507if (retVal != UA_STATUSCODE_GOOD) return retVal;
92508retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12078LU), false);
92509if (retVal != UA_STATUSCODE_GOOD) return retVal;
92510return retVal;
92511}
92512
92513static UA_StatusCode function_namespace0_generated_798_finish(UA_Server *server, UA_UInt16* ns) {
92514return UA_Server_addNode_finish(server,
92515nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU)
92516);
92517}
92518
92519/* NamingRule - ns=0;i=112 */
92520
92521static UA_StatusCode function_namespace0_generated_799_begin(UA_Server *server, UA_UInt16* ns) {
92522UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92523UA_VariableAttributes attr = UA_VariableAttributes_default;
92524attr.minimumSamplingInterval = 0.000000;
92525attr.userAccessLevel = 1;
92526attr.accessLevel = 1;
92527/* Value rank inherited */
92528attr.valueRank = -2;
92529attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 120LU);
92530UA_Int32 *variablenode_ns_0_i_112_variant_DataContents = UA_Int32_new();
92531if (!variablenode_ns_0_i_112_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY;
92532UA_Int32_init(p: variablenode_ns_0_i_112_variant_DataContents);
92533*variablenode_ns_0_i_112_variant_DataContents = (UA_Int32) 1;
92534UA_Variant_setScalar(v: &attr.value, p: variablenode_ns_0_i_112_variant_DataContents, type: &UA_TYPES[UA_TYPES_INT32]);
92535attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NamingRule");
92536retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
92537requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 112LU),
92538parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU),
92539referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
92540browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NamingRule"),
92541typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
92542attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
92543if (retVal != UA_STATUSCODE_GOOD) return retVal;
92544UA_Int32_delete(p: variablenode_ns_0_i_112_variant_DataContents);
92545return retVal;
92546}
92547
92548static UA_StatusCode function_namespace0_generated_799_finish(UA_Server *server, UA_UInt16* ns) {
92549return UA_Server_addNode_finish(server,
92550nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 112LU)
92551);
92552}
92553
92554/* MandatoryPlaceholder - ns=0;i=11510 */
92555
92556static UA_StatusCode function_namespace0_generated_800_begin(UA_Server *server, UA_UInt16* ns) {
92557UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92558UA_ObjectAttributes attr = UA_ObjectAttributes_default;
92559attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "MandatoryPlaceholder");
92560retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
92561requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11510LU),
92562parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
92563referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
92564browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "MandatoryPlaceholder"),
92565typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 77LU),
92566attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
92567if (retVal != UA_STATUSCODE_GOOD) return retVal;
92568return retVal;
92569}
92570
92571static UA_StatusCode function_namespace0_generated_800_finish(UA_Server *server, UA_UInt16* ns) {
92572return UA_Server_addNode_finish(server,
92573nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11510LU)
92574);
92575}
92576
92577/* NamingRule - ns=0;i=11511 */
92578
92579static UA_StatusCode function_namespace0_generated_801_begin(UA_Server *server, UA_UInt16* ns) {
92580UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92581UA_VariableAttributes attr = UA_VariableAttributes_default;
92582attr.minimumSamplingInterval = 0.000000;
92583attr.userAccessLevel = 1;
92584attr.accessLevel = 1;
92585/* Value rank inherited */
92586attr.valueRank = -2;
92587attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 120LU);
92588UA_Int32 *variablenode_ns_0_i_11511_variant_DataContents = UA_Int32_new();
92589if (!variablenode_ns_0_i_11511_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY;
92590UA_Int32_init(p: variablenode_ns_0_i_11511_variant_DataContents);
92591*variablenode_ns_0_i_11511_variant_DataContents = (UA_Int32) 1;
92592UA_Variant_setScalar(v: &attr.value, p: variablenode_ns_0_i_11511_variant_DataContents, type: &UA_TYPES[UA_TYPES_INT32]);
92593attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NamingRule");
92594retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
92595requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11511LU),
92596parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11510LU),
92597referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
92598browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NamingRule"),
92599typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
92600attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
92601if (retVal != UA_STATUSCODE_GOOD) return retVal;
92602UA_Int32_delete(p: variablenode_ns_0_i_11511_variant_DataContents);
92603return retVal;
92604}
92605
92606static UA_StatusCode function_namespace0_generated_801_finish(UA_Server *server, UA_UInt16* ns) {
92607return UA_Server_addNode_finish(server,
92608nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11511LU)
92609);
92610}
92611
92612/* OptionalPlaceholder - ns=0;i=11508 */
92613
92614static UA_StatusCode function_namespace0_generated_802_begin(UA_Server *server, UA_UInt16* ns) {
92615UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92616UA_ObjectAttributes attr = UA_ObjectAttributes_default;
92617attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OptionalPlaceholder");
92618retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
92619requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11508LU),
92620parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
92621referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
92622browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OptionalPlaceholder"),
92623typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 77LU),
92624attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
92625if (retVal != UA_STATUSCODE_GOOD) return retVal;
92626retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11508LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 12097LU), false);
92627if (retVal != UA_STATUSCODE_GOOD) return retVal;
92628retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11508LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14478LU), false);
92629if (retVal != UA_STATUSCODE_GOOD) return retVal;
92630retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11508LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17310LU), false);
92631if (retVal != UA_STATUSCODE_GOOD) return retVal;
92632retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11508LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23796LU), false);
92633if (retVal != UA_STATUSCODE_GOOD) return retVal;
92634retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11508LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 23807LU), false);
92635if (retVal != UA_STATUSCODE_GOOD) return retVal;
92636retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11508LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17743LU), false);
92637if (retVal != UA_STATUSCODE_GOOD) return retVal;
92638retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11508LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 14417LU), false);
92639if (retVal != UA_STATUSCODE_GOOD) return retVal;
92640retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11508LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 17325LU), false);
92641if (retVal != UA_STATUSCODE_GOOD) return retVal;
92642retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11508LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 18076LU), false);
92643if (retVal != UA_STATUSCODE_GOOD) return retVal;
92644return retVal;
92645}
92646
92647static UA_StatusCode function_namespace0_generated_802_finish(UA_Server *server, UA_UInt16* ns) {
92648return UA_Server_addNode_finish(server,
92649nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11508LU)
92650);
92651}
92652
92653/* NamingRule - ns=0;i=11509 */
92654
92655static UA_StatusCode function_namespace0_generated_803_begin(UA_Server *server, UA_UInt16* ns) {
92656UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92657UA_VariableAttributes attr = UA_VariableAttributes_default;
92658attr.minimumSamplingInterval = 0.000000;
92659attr.userAccessLevel = 1;
92660attr.accessLevel = 1;
92661/* Value rank inherited */
92662attr.valueRank = -2;
92663attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 120LU);
92664UA_Int32 *variablenode_ns_0_i_11509_variant_DataContents = UA_Int32_new();
92665if (!variablenode_ns_0_i_11509_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY;
92666UA_Int32_init(p: variablenode_ns_0_i_11509_variant_DataContents);
92667*variablenode_ns_0_i_11509_variant_DataContents = (UA_Int32) 2;
92668UA_Variant_setScalar(v: &attr.value, p: variablenode_ns_0_i_11509_variant_DataContents, type: &UA_TYPES[UA_TYPES_INT32]);
92669attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NamingRule");
92670retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
92671requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11509LU),
92672parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11508LU),
92673referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
92674browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NamingRule"),
92675typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
92676attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
92677if (retVal != UA_STATUSCODE_GOOD) return retVal;
92678UA_Int32_delete(p: variablenode_ns_0_i_11509_variant_DataContents);
92679return retVal;
92680}
92681
92682static UA_StatusCode function_namespace0_generated_803_finish(UA_Server *server, UA_UInt16* ns) {
92683return UA_Server_addNode_finish(server,
92684nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 11509LU)
92685);
92686}
92687
92688/* NamingRule - ns=0;i=111 */
92689
92690static UA_StatusCode function_namespace0_generated_804_begin(UA_Server *server, UA_UInt16* ns) {
92691UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92692UA_VariableAttributes attr = UA_VariableAttributes_default;
92693attr.minimumSamplingInterval = 0.000000;
92694attr.userAccessLevel = 1;
92695attr.accessLevel = 1;
92696/* Value rank inherited */
92697attr.valueRank = -2;
92698attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 120LU);
92699UA_Int32 *variablenode_ns_0_i_111_variant_DataContents = UA_Int32_new();
92700if (!variablenode_ns_0_i_111_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY;
92701UA_Int32_init(p: variablenode_ns_0_i_111_variant_DataContents);
92702*variablenode_ns_0_i_111_variant_DataContents = (UA_Int32) 1;
92703UA_Variant_setScalar(v: &attr.value, p: variablenode_ns_0_i_111_variant_DataContents, type: &UA_TYPES[UA_TYPES_INT32]);
92704attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NamingRule");
92705retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
92706requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 111LU),
92707parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 77LU),
92708referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
92709browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NamingRule"),
92710typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
92711attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
92712if (retVal != UA_STATUSCODE_GOOD) return retVal;
92713UA_Int32_delete(p: variablenode_ns_0_i_111_variant_DataContents);
92714retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 111LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 78LU), true);
92715if (retVal != UA_STATUSCODE_GOOD) return retVal;
92716return retVal;
92717}
92718
92719static UA_StatusCode function_namespace0_generated_804_finish(UA_Server *server, UA_UInt16* ns) {
92720return UA_Server_addNode_finish(server,
92721nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 111LU)
92722);
92723}
92724
92725/* DataTypeEncodingType - ns=0;i=76 */
92726
92727static UA_StatusCode function_namespace0_generated_805_begin(UA_Server *server, UA_UInt16* ns) {
92728UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92729UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
92730attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataTypeEncodingType");
92731retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
92732requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 76LU),
92733parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
92734referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
92735browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataTypeEncodingType"),
92736 typeDefinition: UA_NODEID_NULL,
92737attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
92738if (retVal != UA_STATUSCODE_GOOD) return retVal;
92739return retVal;
92740}
92741
92742static UA_StatusCode function_namespace0_generated_805_finish(UA_Server *server, UA_UInt16* ns) {
92743return UA_Server_addNode_finish(server,
92744nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 76LU)
92745);
92746}
92747
92748/* Default Binary - ns=0;i=8251 */
92749
92750static UA_StatusCode function_namespace0_generated_806_begin(UA_Server *server, UA_UInt16* ns) {
92751UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92752UA_ObjectAttributes attr = UA_ObjectAttributes_default;
92753attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Default Binary");
92754retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
92755requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8251LU),
92756parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
92757referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
92758browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Default Binary"),
92759typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 76LU),
92760attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
92761if (retVal != UA_STATUSCODE_GOOD) return retVal;
92762retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8251LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 38LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 7594LU), false);
92763if (retVal != UA_STATUSCODE_GOOD) return retVal;
92764return retVal;
92765}
92766
92767static UA_StatusCode function_namespace0_generated_806_finish(UA_Server *server, UA_UInt16* ns) {
92768return UA_Server_addNode_finish(server,
92769nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 8251LU)
92770);
92771}
92772
92773/* Default Binary - ns=0;i=298 */
92774
92775static UA_StatusCode function_namespace0_generated_807_begin(UA_Server *server, UA_UInt16* ns) {
92776UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92777UA_ObjectAttributes attr = UA_ObjectAttributes_default;
92778attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Default Binary");
92779retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
92780requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 298LU),
92781parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
92782referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
92783browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Default Binary"),
92784typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 76LU),
92785attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
92786if (retVal != UA_STATUSCODE_GOOD) return retVal;
92787retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 298LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 38LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 296LU), false);
92788if (retVal != UA_STATUSCODE_GOOD) return retVal;
92789return retVal;
92790}
92791
92792static UA_StatusCode function_namespace0_generated_807_finish(UA_Server *server, UA_UInt16* ns) {
92793return UA_Server_addNode_finish(server,
92794nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 298LU)
92795);
92796}
92797
92798/* Default JSON - ns=0;i=15376 */
92799
92800static UA_StatusCode function_namespace0_generated_808_begin(UA_Server *server, UA_UInt16* ns) {
92801UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92802UA_ObjectAttributes attr = UA_ObjectAttributes_default;
92803attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Default JSON");
92804retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
92805requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15376LU),
92806parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
92807referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
92808browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Default JSON"),
92809typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 76LU),
92810attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
92811if (retVal != UA_STATUSCODE_GOOD) return retVal;
92812retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15376LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 38LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 887LU), false);
92813if (retVal != UA_STATUSCODE_GOOD) return retVal;
92814return retVal;
92815}
92816
92817static UA_StatusCode function_namespace0_generated_808_finish(UA_Server *server, UA_UInt16* ns) {
92818return UA_Server_addNode_finish(server,
92819nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15376LU)
92820);
92821}
92822
92823/* Default JSON - ns=0;i=15375 */
92824
92825static UA_StatusCode function_namespace0_generated_809_begin(UA_Server *server, UA_UInt16* ns) {
92826UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92827UA_ObjectAttributes attr = UA_ObjectAttributes_default;
92828attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Default JSON");
92829retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
92830requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15375LU),
92831parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
92832referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
92833browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Default JSON"),
92834typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 76LU),
92835attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
92836if (retVal != UA_STATUSCODE_GOOD) return retVal;
92837retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15375LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 38LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 884LU), false);
92838if (retVal != UA_STATUSCODE_GOOD) return retVal;
92839return retVal;
92840}
92841
92842static UA_StatusCode function_namespace0_generated_809_finish(UA_Server *server, UA_UInt16* ns) {
92843return UA_Server_addNode_finish(server,
92844nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15375LU)
92845);
92846}
92847
92848/* DataTypeSystemType - ns=0;i=75 */
92849
92850static UA_StatusCode function_namespace0_generated_810_begin(UA_Server *server, UA_UInt16* ns) {
92851UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92852UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default;
92853attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataTypeSystemType");
92854retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECTTYPE,
92855requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 75LU),
92856parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
92857referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
92858browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataTypeSystemType"),
92859 typeDefinition: UA_NODEID_NULL,
92860attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL);
92861if (retVal != UA_STATUSCODE_GOOD) return retVal;
92862return retVal;
92863}
92864
92865static UA_StatusCode function_namespace0_generated_810_finish(UA_Server *server, UA_UInt16* ns) {
92866return UA_Server_addNode_finish(server,
92867nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 75LU)
92868);
92869}
92870
92871/* OPC Binary - ns=0;i=93 */
92872
92873static UA_StatusCode function_namespace0_generated_811_begin(UA_Server *server, UA_UInt16* ns) {
92874UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92875UA_ObjectAttributes attr = UA_ObjectAttributes_default;
92876attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "OPC Binary");
92877retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
92878requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 93LU),
92879parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 90LU),
92880referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 35LU),
92881browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "OPC Binary"),
92882typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 75LU),
92883attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
92884if (retVal != UA_STATUSCODE_GOOD) return retVal;
92885return retVal;
92886}
92887
92888static UA_StatusCode function_namespace0_generated_811_finish(UA_Server *server, UA_UInt16* ns) {
92889return UA_Server_addNode_finish(server,
92890nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 93LU)
92891);
92892}
92893
92894/* XML Schema - ns=0;i=92 */
92895
92896static UA_StatusCode function_namespace0_generated_812_begin(UA_Server *server, UA_UInt16* ns) {
92897UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92898UA_ObjectAttributes attr = UA_ObjectAttributes_default;
92899attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "XML Schema");
92900retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
92901requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 92LU),
92902parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 90LU),
92903referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 35LU),
92904browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "XML Schema"),
92905typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 75LU),
92906attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
92907if (retVal != UA_STATUSCODE_GOOD) return retVal;
92908return retVal;
92909}
92910
92911static UA_StatusCode function_namespace0_generated_812_finish(UA_Server *server, UA_UInt16* ns) {
92912return UA_Server_addNode_finish(server,
92913nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 92LU)
92914);
92915}
92916
92917/* DataTypeDictionaryType - ns=0;i=72 */
92918
92919static UA_StatusCode function_namespace0_generated_813_begin(UA_Server *server, UA_UInt16* ns) {
92920UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92921UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
92922/* Value rank inherited */
92923attr.valueRank = -2;
92924attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15LU);
92925attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataTypeDictionaryType");
92926retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
92927requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 72LU),
92928parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
92929referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
92930browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataTypeDictionaryType"),
92931typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
92932attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
92933if (retVal != UA_STATUSCODE_GOOD) return retVal;
92934return retVal;
92935}
92936
92937static UA_StatusCode function_namespace0_generated_813_finish(UA_Server *server, UA_UInt16* ns) {
92938return UA_Server_addNode_finish(server,
92939nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 72LU)
92940);
92941}
92942
92943/* Opc.Ua - ns=0;i=7617 */
92944static const UA_Byte variablenode_ns_0_i_7617_variant_DataContents_byteArray[177218] = {60, 111, 112, 99, 58, 84, 121, 112, 101, 68, 105, 99, 116, 105, 111, 110, 97, 114, 121, 13, 10, 32, 32, 120, 109, 108, 110, 115, 58, 111, 112, 99, 61, 34, 104, 116, 116, 112, 58, 47, 47, 111, 112, 99, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 66, 105, 110, 97, 114, 121, 83, 99, 104, 101, 109, 97, 47, 34, 13, 10, 32, 32, 120, 109, 108, 110, 115, 58, 120, 115, 105, 61, 34, 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 50, 48, 48, 49, 47, 88, 77, 76, 83, 99, 104, 101, 109, 97, 45, 105, 110, 115, 116, 97, 110, 99, 101, 34, 13, 10, 32, 32, 120, 109, 108, 110, 115, 58, 117, 97, 61, 34, 104, 116, 116, 112, 58, 47, 47, 111, 112, 99, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 85, 65, 47, 34, 13, 10, 32, 32, 120, 109, 108, 110, 115, 58, 116, 110, 115, 61, 34, 104, 116, 116, 112, 58, 47, 47, 111, 112, 99, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 85, 65, 47, 34, 13, 10, 32, 32, 68, 101, 102, 97, 117, 108, 116, 66, 121, 116, 101, 79, 114, 100, 101, 114, 61, 34, 76, 105, 116, 116, 108, 101, 69, 110, 100, 105, 97, 110, 34, 13, 10, 32, 32, 84, 97, 114, 103, 101, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101, 61, 34, 104, 116, 116, 112, 58, 47, 47, 111, 112, 99, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 85, 65, 47, 34, 13, 10, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 73, 109, 112, 111, 114, 116, 32, 78, 97, 109, 101, 115, 112, 97, 99, 101, 61, 34, 104, 116, 116, 112, 58, 47, 47, 111, 112, 99, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 66, 105, 110, 97, 114, 121, 83, 99, 104, 101, 109, 97, 47, 34, 32, 47, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 88, 109, 108, 69, 108, 101, 109, 101, 110, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 65, 110, 32, 88, 77, 76, 32, 101, 108, 101, 109, 101, 110, 116, 32, 101, 110, 99, 111, 100, 101, 100, 32, 97, 115, 32, 97, 32, 85, 84, 70, 45, 56, 32, 115, 116, 114, 105, 110, 103, 46, 60, 47, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 101, 110, 103, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 67, 104, 97, 114, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 76, 101, 110, 103, 116, 104, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 54, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 84, 104, 101, 32, 112, 111, 115, 115, 105, 98, 108, 101, 32, 101, 110, 99, 111, 100, 105, 110, 103, 115, 32, 102, 111, 114, 32, 97, 32, 78, 111, 100, 101, 73, 100, 32, 118, 97, 108, 117, 101, 46, 60, 47, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 84, 119, 111, 66, 121, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 70, 111, 117, 114, 66, 121, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 117, 109, 101, 114, 105, 99, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 105, 110, 103, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 71, 117, 105, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 86, 97, 108, 117, 101, 61, 34, 53, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 119, 111, 66, 121, 116, 101, 78, 111, 100, 101, 73, 100, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 70, 111, 117, 114, 66, 121, 116, 101, 78, 111, 100, 101, 73, 100, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 73, 110, 100, 101, 120, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 117, 109, 101, 114, 105, 99, 78, 111, 100, 101, 73, 100, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 73, 110, 100, 101, 120, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 105, 110, 103, 78, 111, 100, 101, 73, 100, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 73, 110, 100, 101, 120, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 67, 104, 97, 114, 65, 114, 114, 97, 121, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 71, 117, 105, 100, 78, 111, 100, 101, 73, 100, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 73, 110, 100, 101, 120, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 71, 117, 105, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 78, 111, 100, 101, 73, 100, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 73, 110, 100, 101, 120, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 100, 101, 110, 116, 105, 102, 105, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 65, 110, 32, 105, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 102, 111, 114, 32, 97, 32, 110, 111, 100, 101, 32, 105, 110, 32, 97, 32, 85, 65, 32, 115, 101, 114, 118, 101, 114, 32, 97, 100, 100, 114, 101, 115, 115, 32, 115, 112, 97, 99, 101, 46, 60, 47, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 101, 114, 118, 101, 100, 49, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 76, 101, 110, 103, 116, 104, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 119, 111, 66, 121, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 84, 119, 111, 66, 121, 116, 101, 78, 111, 100, 101, 73, 100, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 111, 117, 114, 66, 121, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 70, 111, 117, 114, 66, 121, 116, 101, 78, 111, 100, 101, 73, 100, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 117, 109, 101, 114, 105, 99, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 117, 109, 101, 114, 105, 99, 78, 111, 100, 101, 73, 100, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 114, 105, 110, 103, 78, 111, 100, 101, 73, 100, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 71, 117, 105, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 71, 117, 105, 100, 78, 111, 100, 101, 73, 100, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 78, 111, 100, 101, 73, 100, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 53, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 65, 110, 32, 105, 100, 101, 110, 116, 105, 102, 105, 101, 114, 32, 102, 111, 114, 32, 97, 32, 110, 111, 100, 101, 32, 105, 110, 32, 97, 32, 85, 65, 32, 115, 101, 114, 118, 101, 114, 32, 97, 100, 100, 114, 101, 115, 115, 32, 115, 112, 97, 99, 101, 32, 113, 117, 97, 108, 105, 102, 105, 101, 100, 32, 119, 105, 116, 104, 32, 97, 32, 99, 111, 109, 112, 108, 101, 116, 101, 32, 110, 97, 109, 101, 115, 112, 97, 99, 101, 32, 115, 116, 114, 105, 110, 103, 46, 60, 47, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 73, 110, 100, 101, 120, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 85, 82, 73, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 119, 111, 66, 121, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 84, 119, 111, 66, 121, 116, 101, 78, 111, 100, 101, 73, 100, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 111, 117, 114, 66, 121, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 70, 111, 117, 114, 66, 121, 116, 101, 78, 111, 100, 101, 73, 100, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 117, 109, 101, 114, 105, 99, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 117, 109, 101, 114, 105, 99, 78, 111, 100, 101, 73, 100, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 114, 105, 110, 103, 78, 111, 100, 101, 73, 100, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 71, 117, 105, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 71, 117, 105, 100, 78, 111, 100, 101, 73, 100, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 78, 111, 100, 101, 73, 100, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 100, 101, 73, 100, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 53, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 85, 82, 73, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 67, 104, 97, 114, 65, 114, 114, 97, 121, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 85, 82, 73, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 73, 110, 100, 101, 120, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 83, 101, 114, 118, 101, 114, 73, 110, 100, 101, 120, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 32, 66, 121, 116, 101, 79, 114, 100, 101, 114, 83, 105, 103, 110, 105, 102, 105, 99, 97, 110, 116, 61, 34, 116, 114, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 65, 32, 51, 50, 45, 98, 105, 116, 32, 115, 116, 97, 116, 117, 115, 32, 99, 111, 100, 101, 32, 118, 97, 108, 117, 101, 46, 60, 47, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 65, 32, 114, 101, 99, 117, 114, 115, 105, 118, 101, 32, 115, 116, 114, 117, 99, 116, 117, 114, 101, 32, 99, 111, 110, 116, 97, 105, 110, 105, 110, 103, 32, 100, 105, 97, 103, 110, 111, 115, 116, 105, 99, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 97, 115, 115, 111, 99, 105, 97, 116, 101, 100, 32, 119, 105, 116, 104, 32, 97, 32, 115, 116, 97, 116, 117, 115, 32, 99, 111, 100, 101, 46, 60, 47, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 121, 109, 98, 111, 108, 105, 99, 73, 100, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 85, 82, 73, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 101, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 105, 116, 105, 111, 110, 97, 108, 73, 110, 102, 111, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 110, 101, 114, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 110, 101, 114, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 101, 114, 118, 101, 100, 49, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 76, 101, 110, 103, 116, 104, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 121, 109, 98, 111, 108, 105, 99, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 83, 121, 109, 98, 111, 108, 105, 99, 73, 100, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 85, 82, 73, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 85, 82, 73, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 76, 111, 99, 97, 108, 101, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 105, 116, 105, 111, 110, 97, 108, 73, 110, 102, 111, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 67, 104, 97, 114, 65, 114, 114, 97, 121, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 65, 100, 100, 105, 116, 105, 111, 110, 97, 108, 73, 110, 102, 111, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 110, 101, 114, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 73, 110, 110, 101, 114, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 110, 101, 114, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 73, 110, 110, 101, 114, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 65, 32, 115, 116, 114, 105, 110, 103, 32, 113, 117, 97, 108, 105, 102, 105, 101, 100, 32, 119, 105, 116, 104, 32, 97, 32, 110, 97, 109, 101, 115, 112, 97, 99, 101, 32, 105, 110, 100, 101, 120, 46, 60, 47, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 73, 110, 100, 101, 120, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 67, 104, 97, 114, 65, 114, 114, 97, 121, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 65, 32, 115, 116, 114, 105, 110, 103, 32, 113, 117, 97, 108, 105, 102, 105, 101, 100, 32, 119, 105, 116, 104, 32, 97, 32, 110, 97, 109, 101, 115, 112, 97, 99, 101, 32, 105, 110, 100, 101, 120, 46, 60, 47, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 101, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 101, 120, 116, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 101, 114, 118, 101, 100, 49, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 76, 101, 110, 103, 116, 104, 61, 34, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 67, 104, 97, 114, 65, 114, 114, 97, 121, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 76, 111, 99, 97, 108, 101, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 101, 120, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 67, 104, 97, 114, 65, 114, 114, 97, 121, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 84, 101, 120, 116, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 86, 97, 108, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 65, 32, 118, 97, 108, 117, 101, 32, 119, 105, 116, 104, 32, 97, 110, 32, 97, 115, 115, 111, 99, 105, 97, 116, 101, 100, 32, 116, 105, 109, 101, 115, 116, 97, 109, 112, 44, 32, 97, 110, 100, 32, 113, 117, 97, 108, 105, 116, 121, 46, 60, 47, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 111, 117, 114, 99, 101, 84, 105, 109, 101, 115, 116, 97, 109, 112, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 84, 105, 109, 101, 115, 116, 97, 109, 112, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 111, 117, 114, 99, 101, 80, 105, 99, 111, 115, 101, 99, 111, 110, 100, 115, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 80, 105, 99, 111, 115, 101, 99, 111, 110, 100, 115, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 101, 114, 118, 101, 100, 49, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 76, 101, 110, 103, 116, 104, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 108, 117, 101, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 111, 117, 114, 99, 101, 84, 105, 109, 101, 115, 116, 97, 109, 112, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 83, 111, 117, 114, 99, 101, 84, 105, 109, 101, 115, 116, 97, 109, 112, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 111, 117, 114, 99, 101, 80, 105, 99, 111, 115, 101, 99, 111, 110, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 83, 111, 117, 114, 99, 101, 80, 105, 99, 111, 115, 101, 99, 111, 110, 100, 115, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 84, 105, 109, 101, 115, 116, 97, 109, 112, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 83, 101, 114, 118, 101, 114, 84, 105, 109, 101, 115, 116, 97, 109, 112, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 80, 105, 99, 111, 115, 101, 99, 111, 110, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 83, 101, 114, 118, 101, 114, 80, 105, 99, 111, 115, 101, 99, 111, 110, 100, 115, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 65, 32, 115, 101, 114, 105, 97, 108, 105, 122, 101, 100, 32, 111, 98, 106, 101, 99, 116, 32, 112, 114, 101, 102, 105, 120, 101, 100, 32, 119, 105, 116, 104, 32, 105, 116, 115, 32, 100, 97, 116, 97, 32, 116, 121, 112, 101, 32, 105, 100, 101, 110, 116, 105, 102, 105, 101, 114, 46, 60, 47, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 121, 112, 101, 73, 100, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 105, 110, 97, 114, 121, 66, 111, 100, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 88, 109, 108, 66, 111, 100, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 101, 114, 118, 101, 100, 49, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 76, 101, 110, 103, 116, 104, 61, 34, 53, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 121, 112, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 84, 121, 112, 101, 73, 100, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 111, 100, 121, 76, 101, 110, 103, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 111, 100, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 66, 111, 100, 121, 76, 101, 110, 103, 116, 104, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 86, 97, 114, 105, 97, 110, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 65, 32, 117, 110, 105, 111, 110, 32, 111, 102, 32, 115, 101, 118, 101, 114, 97, 108, 32, 116, 121, 112, 101, 115, 46, 60, 47, 111, 112, 99, 58, 68, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 76, 101, 110, 103, 116, 104, 61, 34, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 76, 101, 110, 103, 116, 104, 61, 34, 49, 34, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 105, 116, 34, 32, 76, 101, 110, 103, 116, 104, 61, 34, 49, 34, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 111, 111, 108, 101, 97, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 66, 121, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 66, 121, 116, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 121, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 116, 49, 54, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 49, 54, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 73, 110, 116, 49, 54, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 53, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 116, 51, 50, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 73, 110, 116, 51, 50, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 55, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 116, 54, 52, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 54, 52, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 73, 110, 116, 54, 52, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 54, 52, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 57, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 108, 111, 97, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 70, 108, 111, 97, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 49, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 111, 117, 98, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 49, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 67, 104, 97, 114, 65, 114, 114, 97, 121, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 49, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 49, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 71, 117, 105, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 71, 117, 105, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 49, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 49, 53, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 88, 109, 108, 69, 108, 101, 109, 101, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 88, 109, 108, 69, 108, 101, 109, 101, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 49, 55, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 49, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 49, 57, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 50, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 50, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 50, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 97, 116, 97, 86, 97, 108, 117, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 50, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 114, 105, 97, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 50, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 86, 97, 114, 105, 97, 110, 116, 84, 121, 112, 101, 34, 32, 83, 119, 105, 116, 99, 104, 86, 97, 108, 117, 101, 61, 34, 50, 53, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 83, 119, 105, 116, 99, 104, 70, 105, 101, 108, 100, 61, 34, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 105, 110, 103, 82, 117, 108, 101, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 77, 97, 110, 100, 97, 116, 111, 114, 121, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 79, 112, 116, 105, 111, 110, 97, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 32, 32, 32, 32, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 73, 109, 97, 103, 101, 66, 77, 80, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 73, 109, 97, 103, 101, 71, 73, 70, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 73, 109, 97, 103, 101, 74, 80, 71, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 73, 109, 97, 103, 101, 80, 78, 71, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 117, 100, 105, 111, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 105, 116, 70, 105, 101, 108, 100, 77, 97, 115, 107, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 75, 101, 121, 86, 97, 108, 117, 101, 80, 97, 105, 114, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 75, 101, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 105, 116, 105, 111, 110, 97, 108, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 75, 101, 121, 86, 97, 108, 117, 101, 80, 97, 105, 114, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 112, 104, 101, 109, 101, 114, 97, 108, 75, 101, 121, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 99, 75, 101, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 105, 103, 110, 97, 116, 117, 114, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 112, 111, 105, 110, 116, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 112, 111, 105, 110, 116, 85, 114, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 101, 115, 115, 97, 103, 101, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 80, 111, 108, 105, 99, 121, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 112, 111, 114, 116, 80, 114, 111, 102, 105, 108, 101, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 97, 116, 105, 111, 110, 97, 108, 78, 117, 109, 98, 101, 114, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 117, 109, 101, 114, 97, 116, 111, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 110, 111, 109, 105, 110, 97, 116, 111, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 86, 101, 99, 116, 111, 114, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 104, 114, 101, 101, 68, 86, 101, 99, 116, 111, 114, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 86, 101, 99, 116, 111, 114, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 88, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 89, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 90, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 97, 114, 116, 101, 115, 105, 97, 110, 67, 111, 111, 114, 100, 105, 110, 97, 116, 101, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 104, 114, 101, 101, 68, 67, 97, 114, 116, 101, 115, 105, 97, 110, 67, 111, 111, 114, 100, 105, 110, 97, 116, 101, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 67, 97, 114, 116, 101, 115, 105, 97, 110, 67, 111, 111, 114, 100, 105, 110, 97, 116, 101, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 88, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 89, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 90, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 79, 114, 105, 101, 110, 116, 97, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 104, 114, 101, 101, 68, 79, 114, 105, 101, 110, 116, 97, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 79, 114, 105, 101, 110, 116, 97, 116, 105, 111, 110, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 70, 114, 97, 109, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 104, 114, 101, 101, 68, 70, 114, 97, 109, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 70, 114, 97, 109, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 97, 114, 116, 101, 115, 105, 97, 110, 67, 111, 111, 114, 100, 105, 110, 97, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 84, 104, 114, 101, 101, 68, 67, 97, 114, 116, 101, 115, 105, 97, 110, 67, 111, 111, 114, 100, 105, 110, 97, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 79, 114, 105, 101, 110, 116, 97, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 84, 104, 114, 101, 101, 68, 79, 114, 105, 101, 110, 116, 97, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 79, 112, 101, 110, 70, 105, 108, 101, 77, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 69, 114, 97, 115, 101, 69, 120, 105, 115, 116, 105, 110, 103, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 112, 112, 101, 110, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 73, 100, 101, 110, 116, 105, 116, 121, 67, 114, 105, 116, 101, 114, 105, 97, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 78, 97, 109, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 84, 104, 117, 109, 98, 112, 114, 105, 110, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 71, 114, 111, 117, 112, 73, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 110, 111, 110, 121, 109, 111, 117, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 53, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, 100, 85, 115, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 73, 100, 101, 110, 116, 105, 116, 121, 77, 97, 112, 112, 105, 110, 103, 82, 117, 108, 101, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 114, 105, 116, 101, 114, 105, 97, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 73, 100, 101, 110, 116, 105, 116, 121, 67, 114, 105, 116, 101, 114, 105, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 114, 105, 116, 101, 114, 105, 97, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 99, 121, 85, 110, 105, 116, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 117, 109, 101, 114, 105, 99, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 120, 112, 111, 110, 101, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 108, 112, 104, 97, 98, 101, 116, 105, 99, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 99, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 114, 117, 115, 116, 76, 105, 115, 116, 77, 97, 115, 107, 115, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 84, 114, 117, 115, 116, 101, 100, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 84, 114, 117, 115, 116, 101, 100, 67, 114, 108, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 115, 115, 117, 101, 114, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 115, 115, 117, 101, 114, 67, 114, 108, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 108, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 53, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 114, 117, 115, 116, 76, 105, 115, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 112, 101, 99, 105, 102, 105, 101, 100, 76, 105, 115, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 84, 114, 117, 115, 116, 101, 100, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 117, 115, 116, 101, 100, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 84, 114, 117, 115, 116, 101, 100, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 84, 114, 117, 115, 116, 101, 100, 67, 114, 108, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 117, 115, 116, 101, 100, 67, 114, 108, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 84, 114, 117, 115, 116, 101, 100, 67, 114, 108, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 73, 115, 115, 117, 101, 114, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 115, 117, 101, 114, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 73, 115, 115, 117, 101, 114, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 73, 115, 115, 117, 101, 114, 67, 114, 108, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 115, 117, 101, 114, 67, 114, 108, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 73, 115, 115, 117, 101, 114, 67, 114, 108, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 99, 105, 109, 97, 108, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 99, 97, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 83, 99, 104, 101, 109, 97, 72, 101, 97, 100, 101, 114, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 97, 109, 101, 115, 112, 97, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 97, 109, 101, 115, 112, 97, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 110, 117, 109, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 117, 109, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 110, 117, 109, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 110, 117, 109, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 105, 109, 112, 108, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 105, 109, 112, 108, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 105, 109, 112, 108, 101, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 105, 109, 112, 108, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 110, 117, 109, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 117, 109, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 110, 117, 109, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 117, 105, 108, 116, 73, 110, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 105, 109, 112, 108, 101, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 97, 115, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 117, 105, 108, 116, 73, 110, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 65, 66, 105, 110, 97, 114, 121, 70, 105, 108, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 84, 121, 112, 101, 83, 99, 104, 101, 109, 97, 72, 101, 97, 100, 101, 114, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 97, 109, 101, 115, 112, 97, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 97, 109, 101, 115, 112, 97, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 110, 117, 109, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 117, 109, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 110, 117, 109, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 110, 117, 109, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 105, 109, 112, 108, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 105, 109, 112, 108, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 105, 109, 112, 108, 101, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 105, 109, 112, 108, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 99, 104, 101, 109, 97, 76, 111, 99, 97, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 70, 105, 108, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 108, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 75, 101, 121, 86, 97, 108, 117, 101, 80, 97, 105, 114, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 70, 105, 108, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 111, 100, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 83, 117, 98, 83, 116, 97, 116, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 97, 98, 108, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 80, 97, 117, 115, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 79, 112, 101, 114, 97, 116, 105, 111, 110, 97, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 69, 114, 114, 111, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 77, 101, 116, 97, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 84, 121, 112, 101, 83, 99, 104, 101, 109, 97, 72, 101, 97, 100, 101, 114, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 97, 109, 101, 115, 112, 97, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 97, 109, 101, 115, 112, 97, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 110, 117, 109, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 117, 109, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 110, 117, 109, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 110, 117, 109, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 105, 109, 112, 108, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 105, 109, 112, 108, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 105, 109, 112, 108, 101, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 105, 109, 112, 108, 101, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 70, 105, 101, 108, 100, 77, 101, 116, 97, 68, 97, 116, 97, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 70, 105, 101, 108, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 67, 108, 97, 115, 115, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 71, 117, 105, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 86, 101, 114, 115, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 86, 101, 114, 115, 105, 111, 110, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 70, 105, 101, 108, 100, 77, 101, 116, 97, 68, 97, 116, 97, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 101, 108, 100, 70, 108, 97, 103, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 70, 105, 101, 108, 100, 70, 108, 97, 103, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 117, 105, 108, 116, 73, 110, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 82, 97, 110, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 83, 116, 114, 105, 110, 103, 76, 101, 110, 103, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 70, 105, 101, 108, 100, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 71, 117, 105, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 75, 101, 121, 86, 97, 108, 117, 101, 80, 97, 105, 114, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 70, 105, 101, 108, 100, 70, 108, 97, 103, 115, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 49, 54, 34, 32, 73, 115, 79, 112, 116, 105, 111, 110, 83, 101, 116, 61, 34, 116, 114, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 80, 114, 111, 109, 111, 116, 101, 100, 70, 105, 101, 108, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 86, 101, 114, 115, 105, 111, 110, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 106, 111, 114, 86, 101, 114, 115, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 105, 110, 111, 114, 86, 101, 114, 115, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 101, 100, 68, 97, 116, 97, 83, 101, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 83, 101, 116, 70, 111, 108, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 70, 111, 108, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 83, 101, 116, 70, 111, 108, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 77, 101, 116, 97, 68, 97, 116, 97, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 77, 101, 116, 97, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 120, 116, 101, 110, 115, 105, 111, 110, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 120, 116, 101, 110, 115, 105, 111, 110, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 75, 101, 121, 86, 97, 108, 117, 101, 80, 97, 105, 114, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 120, 116, 101, 110, 115, 105, 111, 110, 70, 105, 101, 108, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 83, 111, 117, 114, 99, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 101, 100, 68, 97, 116, 97, 83, 101, 116, 83, 111, 117, 114, 99, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 101, 100, 86, 97, 114, 105, 97, 98, 108, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 101, 100, 86, 97, 114, 105, 97, 98, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 116, 116, 114, 105, 98, 117, 116, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 97, 109, 112, 108, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 72, 105, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 97, 100, 98, 97, 110, 100, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 97, 100, 98, 97, 110, 100, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 100, 101, 120, 82, 97, 110, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 116, 105, 116, 117, 116, 101, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 77, 101, 116, 97, 68, 97, 116, 97, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 116, 97, 68, 97, 116, 97, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 77, 101, 116, 97, 68, 97, 116, 97, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 101, 100, 68, 97, 116, 97, 73, 116, 101, 109, 115, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 108, 105, 115, 104, 101, 100, 68, 97, 116, 97, 83, 101, 116, 83, 111, 117, 114, 99, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 80, 117, 98, 108, 105, 115, 104, 101, 100, 68, 97, 116, 97, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 101, 100, 68, 97, 116, 97, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 108, 105, 115, 104, 101, 100, 86, 97, 114, 105, 97, 98, 108, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 80, 117, 98, 108, 105, 115, 104, 101, 100, 68, 97, 116, 97, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 101, 100, 69, 118, 101, 110, 116, 115, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 108, 105, 115, 104, 101, 100, 68, 97, 116, 97, 83, 101, 116, 83, 111, 117, 114, 99, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 78, 111, 116, 105, 102, 105, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 108, 101, 99, 116, 101, 100, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 108, 101, 99, 116, 101, 100, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 105, 109, 112, 108, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 79, 112, 101, 114, 97, 110, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 108, 101, 99, 116, 101, 100, 70, 105, 101, 108, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 108, 116, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 67, 111, 110, 116, 101, 110, 116, 70, 105, 108, 116, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 70, 105, 101, 108, 100, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 32, 73, 115, 79, 112, 116, 105, 111, 110, 83, 101, 116, 61, 34, 116, 114, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 111, 117, 114, 99, 101, 84, 105, 109, 101, 115, 116, 97, 109, 112, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 84, 105, 109, 101, 115, 116, 97, 109, 112, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 111, 117, 114, 99, 101, 80, 105, 99, 111, 83, 101, 99, 111, 110, 100, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 80, 105, 99, 111, 83, 101, 99, 111, 110, 100, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 97, 119, 68, 97, 116, 97, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 97, 98, 108, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 70, 105, 101, 108, 100, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 70, 105, 101, 108, 100, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 75, 101, 121, 70, 114, 97, 109, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 75, 101, 121, 86, 97, 108, 117, 101, 80, 97, 105, 114, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 112, 111, 114, 116, 83, 101, 116, 116, 105, 110, 103, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 115, 115, 97, 103, 101, 83, 101, 116, 116, 105, 110, 103, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 83, 117, 98, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 97, 98, 108, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 101, 115, 115, 97, 103, 101, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 71, 114, 111, 117, 112, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 99, 117, 114, 105, 116, 121, 75, 101, 121, 83, 101, 114, 118, 105, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 75, 101, 121, 83, 101, 114, 118, 105, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 110, 100, 112, 111, 105, 110, 116, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 99, 117, 114, 105, 116, 121, 75, 101, 121, 83, 101, 114, 118, 105, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 83, 105, 122, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 71, 114, 111, 117, 112, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 71, 114, 111, 117, 112, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 75, 101, 121, 86, 97, 108, 117, 101, 80, 97, 105, 114, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 71, 114, 111, 117, 112, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 83, 117, 98, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 83, 117, 98, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 97, 98, 108, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 83, 117, 98, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 101, 115, 115, 97, 103, 101, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 83, 117, 98, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 71, 114, 111, 117, 112, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 83, 117, 98, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 99, 117, 114, 105, 116, 121, 75, 101, 121, 83, 101, 114, 118, 105, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 75, 101, 121, 83, 101, 114, 118, 105, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 110, 100, 112, 111, 105, 110, 116, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 99, 117, 114, 105, 116, 121, 75, 101, 121, 83, 101, 114, 118, 105, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 83, 105, 122, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 83, 117, 98, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 71, 114, 111, 117, 112, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 71, 114, 111, 117, 112, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 75, 101, 121, 86, 97, 108, 117, 101, 80, 97, 105, 114, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 71, 114, 111, 117, 112, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 75, 101, 101, 112, 65, 108, 105, 118, 101, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 114, 105, 111, 114, 105, 116, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 72, 101, 97, 100, 101, 114, 76, 97, 121, 111, 117, 116, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 112, 111, 114, 116, 83, 101, 116, 116, 105, 110, 103, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 115, 115, 97, 103, 101, 83, 101, 116, 116, 105, 110, 103, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 83, 117, 98, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 97, 98, 108, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 101, 114, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 112, 111, 114, 116, 80, 114, 111, 102, 105, 108, 101, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 114, 101, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 75, 101, 121, 86, 97, 108, 117, 101, 80, 97, 105, 114, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 112, 111, 114, 116, 83, 101, 116, 116, 105, 110, 103, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 97, 100, 101, 114, 71, 114, 111, 117, 112, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 101, 114, 71, 114, 111, 117, 112, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 97, 100, 101, 114, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 97, 100, 101, 114, 71, 114, 111, 117, 112, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 65, 100, 100, 114, 101, 115, 115, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 73, 110, 116, 101, 114, 102, 97, 99, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 65, 100, 100, 114, 101, 115, 115, 85, 114, 108, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 101, 116, 119, 111, 114, 107, 65, 100, 100, 114, 101, 115, 115, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 73, 110, 116, 101, 114, 102, 97, 99, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 101, 116, 119, 111, 114, 107, 65, 100, 100, 114, 101, 115, 115, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 114, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 101, 114, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 83, 117, 98, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 83, 117, 98, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 97, 98, 108, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 83, 117, 98, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 101, 115, 115, 97, 103, 101, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 83, 117, 98, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 71, 114, 111, 117, 112, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 83, 117, 98, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 99, 117, 114, 105, 116, 121, 75, 101, 121, 83, 101, 114, 118, 105, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 75, 101, 121, 83, 101, 114, 118, 105, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 110, 100, 112, 111, 105, 110, 116, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 99, 117, 114, 105, 116, 121, 75, 101, 121, 83, 101, 114, 118, 105, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 83, 105, 122, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 83, 117, 98, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 71, 114, 111, 117, 112, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 71, 114, 111, 117, 112, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 75, 101, 121, 86, 97, 108, 117, 101, 80, 97, 105, 114, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 71, 114, 111, 117, 112, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 112, 111, 114, 116, 83, 101, 116, 116, 105, 110, 103, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 115, 115, 97, 103, 101, 83, 101, 116, 116, 105, 110, 103, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 101, 114, 71, 114, 111, 117, 112, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 101, 114, 71, 114, 111, 117, 112, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 97, 98, 108, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 101, 114, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 77, 101, 116, 97, 68, 97, 116, 97, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 77, 101, 116, 97, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 70, 105, 101, 108, 100, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 70, 105, 101, 108, 100, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 115, 115, 97, 103, 101, 82, 101, 99, 101, 105, 118, 101, 84, 105, 109, 101, 111, 117, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 75, 101, 121, 70, 114, 97, 109, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 72, 101, 97, 100, 101, 114, 76, 97, 121, 111, 117, 116, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 101, 115, 115, 97, 103, 101, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 71, 114, 111, 117, 112, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 99, 117, 114, 105, 116, 121, 75, 101, 121, 83, 101, 114, 118, 105, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 75, 101, 121, 83, 101, 114, 118, 105, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 110, 100, 112, 111, 105, 110, 116, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 99, 117, 114, 105, 116, 121, 75, 101, 121, 83, 101, 114, 118, 105, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 75, 101, 121, 86, 97, 108, 117, 101, 80, 97, 105, 114, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 112, 111, 114, 116, 83, 101, 116, 116, 105, 110, 103, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 115, 115, 97, 103, 101, 83, 101, 116, 116, 105, 110, 103, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 98, 101, 100, 68, 97, 116, 97, 83, 101, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 98, 101, 100, 68, 97, 116, 97, 83, 101, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 97, 114, 103, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 115, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 83, 117, 98, 115, 99, 114, 105, 98, 101, 100, 68, 97, 116, 97, 83, 101, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 84, 97, 114, 103, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 97, 114, 103, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 70, 105, 101, 108, 100, 84, 97, 114, 103, 101, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 84, 97, 114, 103, 101, 116, 86, 97, 114, 105, 97, 98, 108, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 70, 105, 101, 108, 100, 84, 97, 114, 103, 101, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 70, 105, 101, 108, 100, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 71, 117, 105, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 99, 101, 105, 118, 101, 114, 73, 110, 100, 101, 120, 82, 97, 110, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 97, 114, 103, 101, 116, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 116, 116, 114, 105, 98, 117, 116, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 73, 110, 100, 101, 120, 82, 97, 110, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 79, 118, 101, 114, 114, 105, 100, 101, 86, 97, 108, 117, 101, 72, 97, 110, 100, 108, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 79, 118, 101, 114, 114, 105, 100, 101, 86, 97, 108, 117, 101, 72, 97, 110, 100, 108, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 79, 118, 101, 114, 114, 105, 100, 101, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 79, 118, 101, 114, 114, 105, 100, 101, 86, 97, 108, 117, 101, 72, 97, 110, 100, 108, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 97, 98, 108, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 85, 115, 97, 98, 108, 101, 86, 97, 108, 117, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 79, 118, 101, 114, 114, 105, 100, 101, 86, 97, 108, 117, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 98, 101, 100, 68, 97, 116, 97, 83, 101, 116, 77, 105, 114, 114, 111, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 83, 117, 98, 115, 99, 114, 105, 98, 101, 100, 68, 97, 116, 97, 83, 101, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 97, 114, 101, 110, 116, 78, 111, 100, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 83, 117, 98, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 80, 117, 98, 108, 105, 115, 104, 101, 100, 68, 97, 116, 97, 83, 101, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 101, 100, 68, 97, 116, 97, 83, 101, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 108, 105, 115, 104, 101, 100, 68, 97, 116, 97, 83, 101, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 80, 117, 98, 108, 105, 115, 104, 101, 100, 68, 97, 116, 97, 83, 101, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 80, 117, 98, 83, 117, 98, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 97, 98, 108, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 79, 114, 100, 101, 114, 105, 110, 103, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 110, 100, 101, 102, 105, 110, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 115, 99, 101, 110, 100, 105, 110, 103, 87, 114, 105, 116, 101, 114, 73, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 115, 99, 101, 110, 100, 105, 110, 103, 87, 114, 105, 116, 101, 114, 73, 100, 83, 105, 110, 103, 108, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 97, 100, 112, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 32, 73, 115, 79, 112, 116, 105, 111, 110, 83, 101, 116, 61, 34, 116, 114, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 101, 114, 73, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 71, 114, 111, 117, 112, 72, 101, 97, 100, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 73, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 71, 114, 111, 117, 112, 86, 101, 114, 115, 105, 111, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 78, 117, 109, 98, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 113, 117, 101, 110, 99, 101, 78, 117, 109, 98, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 80, 97, 121, 108, 111, 97, 100, 72, 101, 97, 100, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 115, 116, 97, 109, 112, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 50, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 80, 105, 99, 111, 83, 101, 99, 111, 110, 100, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 53, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 67, 108, 97, 115, 115, 73, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 53, 49, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 80, 114, 111, 109, 111, 116, 101, 100, 70, 105, 101, 108, 100, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 48, 50, 52, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 97, 100, 112, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 71, 114, 111, 117, 112, 86, 101, 114, 115, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 79, 114, 100, 101, 114, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 79, 114, 100, 101, 114, 105, 110, 103, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 85, 97, 100, 112, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 97, 109, 112, 108, 105, 110, 103, 79, 102, 102, 115, 101, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 79, 102, 102, 115, 101, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 79, 102, 102, 115, 101, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 79, 102, 102, 115, 101, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 97, 100, 112, 68, 97, 116, 97, 83, 101, 116, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 32, 73, 115, 79, 112, 116, 105, 111, 110, 83, 101, 116, 61, 34, 116, 114, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 115, 116, 97, 109, 112, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 80, 105, 99, 111, 83, 101, 99, 111, 110, 100, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 77, 97, 106, 111, 114, 86, 101, 114, 115, 105, 111, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 77, 105, 110, 111, 114, 86, 101, 114, 115, 105, 111, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 113, 117, 101, 110, 99, 101, 78, 117, 109, 98, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 97, 100, 112, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 85, 97, 100, 112, 68, 97, 116, 97, 83, 101, 116, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 102, 105, 103, 117, 114, 101, 100, 83, 105, 122, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 78, 117, 109, 98, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 79, 102, 102, 115, 101, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 97, 100, 112, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 71, 114, 111, 117, 112, 86, 101, 114, 115, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 78, 117, 109, 98, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 79, 102, 102, 115, 101, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 67, 108, 97, 115, 115, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 71, 117, 105, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 85, 97, 100, 112, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 85, 97, 100, 112, 68, 97, 116, 97, 83, 101, 116, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 99, 101, 105, 118, 101, 79, 102, 102, 115, 101, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 114, 111, 99, 101, 115, 115, 105, 110, 103, 79, 102, 102, 115, 101, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 74, 115, 111, 110, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 32, 73, 115, 79, 112, 116, 105, 111, 110, 83, 101, 116, 61, 34, 116, 114, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 72, 101, 97, 100, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 77, 101, 115, 115, 97, 103, 101, 72, 101, 97, 100, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 105, 110, 103, 108, 101, 68, 97, 116, 97, 83, 101, 116, 77, 101, 115, 115, 97, 103, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 101, 114, 73, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 67, 108, 97, 115, 115, 73, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 112, 108, 121, 84, 111, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 74, 115, 111, 110, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 74, 115, 111, 110, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 74, 115, 111, 110, 68, 97, 116, 97, 83, 101, 116, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 32, 73, 115, 79, 112, 116, 105, 111, 110, 83, 101, 116, 61, 34, 116, 114, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 73, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 77, 101, 116, 97, 68, 97, 116, 97, 86, 101, 114, 115, 105, 111, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 113, 117, 101, 110, 99, 101, 78, 117, 109, 98, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 115, 116, 97, 109, 112, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 74, 115, 111, 110, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 74, 115, 111, 110, 68, 97, 116, 97, 83, 101, 116, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 74, 115, 111, 110, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 74, 115, 111, 110, 78, 101, 116, 119, 111, 114, 107, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 101, 116, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 74, 115, 111, 110, 68, 97, 116, 97, 83, 101, 116, 77, 101, 115, 115, 97, 103, 101, 67, 111, 110, 116, 101, 110, 116, 77, 97, 115, 107, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 103, 114, 97, 109, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 99, 111, 118, 101, 114, 121, 65, 100, 100, 114, 101, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 103, 114, 97, 109, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 115, 115, 97, 103, 101, 82, 101, 112, 101, 97, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 115, 115, 97, 103, 101, 82, 101, 112, 101, 97, 116, 68, 101, 108, 97, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 107, 101, 114, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 111, 117, 114, 99, 101, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 80, 114, 111, 102, 105, 108, 101, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 107, 101, 114, 84, 114, 97, 110, 115, 112, 111, 114, 116, 81, 117, 97, 108, 105, 116, 121, 79, 102, 83, 101, 114, 118, 105, 99, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 116, 83, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 66, 101, 115, 116, 69, 102, 102, 111, 114, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 116, 76, 101, 97, 115, 116, 79, 110, 99, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 116, 77, 111, 115, 116, 79, 110, 99, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 69, 120, 97, 99, 116, 108, 121, 79, 110, 99, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 107, 101, 114, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 87, 114, 105, 116, 101, 114, 71, 114, 111, 117, 112, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 117, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 111, 117, 114, 99, 101, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 80, 114, 111, 102, 105, 108, 101, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 68, 101, 108, 105, 118, 101, 114, 121, 71, 117, 97, 114, 97, 110, 116, 101, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 66, 114, 111, 107, 101, 114, 84, 114, 97, 110, 115, 112, 111, 114, 116, 81, 117, 97, 108, 105, 116, 121, 79, 102, 83, 101, 114, 118, 105, 99, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 107, 101, 114, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 87, 114, 105, 116, 101, 114, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 117, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 111, 117, 114, 99, 101, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 80, 114, 111, 102, 105, 108, 101, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 68, 101, 108, 105, 118, 101, 114, 121, 71, 117, 97, 114, 97, 110, 116, 101, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 66, 114, 111, 107, 101, 114, 84, 114, 97, 110, 115, 112, 111, 114, 116, 81, 117, 97, 108, 105, 116, 121, 79, 102, 83, 101, 114, 118, 105, 99, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 116, 97, 68, 97, 116, 97, 81, 117, 101, 117, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 116, 97, 68, 97, 116, 97, 85, 112, 100, 97, 116, 101, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 107, 101, 114, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 83, 101, 116, 82, 101, 97, 100, 101, 114, 84, 114, 97, 110, 115, 112, 111, 114, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 117, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 111, 117, 114, 99, 101, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 80, 114, 111, 102, 105, 108, 101, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 68, 101, 108, 105, 118, 101, 114, 121, 71, 117, 97, 114, 97, 110, 116, 101, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 66, 114, 111, 107, 101, 114, 84, 114, 97, 110, 115, 112, 111, 114, 116, 81, 117, 97, 108, 105, 116, 121, 79, 102, 83, 101, 114, 118, 105, 99, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 116, 97, 68, 97, 116, 97, 81, 117, 101, 117, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 76, 101, 118, 101, 108, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 66, 97, 115, 105, 99, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 100, 118, 97, 110, 99, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 102, 111, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 76, 111, 103, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 98, 117, 103, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 83, 117, 98, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 67, 111, 117, 110, 116, 101, 114, 67, 108, 97, 115, 115, 105, 102, 105, 99, 97, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 69, 114, 114, 111, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 108, 105, 97, 115, 78, 97, 109, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 108, 105, 97, 115, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 100, 78, 111, 100, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 100, 78, 111, 100, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 100, 78, 111, 100, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 73, 100, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 117, 109, 101, 114, 105, 99, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 105, 110, 103, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 71, 117, 105, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 79, 112, 97, 113, 117, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 110, 115, 112, 101, 99, 105, 102, 105, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 79, 98, 106, 101, 99, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 86, 97, 114, 105, 97, 98, 108, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 77, 101, 116, 104, 111, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 79, 98, 106, 101, 99, 116, 84, 121, 112, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 86, 97, 114, 105, 97, 98, 108, 101, 84, 121, 112, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 86, 105, 101, 119, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 50, 56, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 32, 73, 115, 79, 112, 116, 105, 111, 110, 83, 101, 116, 61, 34, 116, 114, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 72, 105, 115, 116, 111, 114, 105, 122, 105, 110, 103, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 72, 105, 115, 116, 111, 114, 121, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 50, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 115, 101, 114, 116, 72, 105, 115, 116, 111, 114, 121, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 53, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 100, 105, 102, 121, 72, 105, 115, 116, 111, 114, 121, 34, 32, 86, 97, 108, 117, 101, 61, 34, 53, 49, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 72, 105, 115, 116, 111, 114, 121, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 48, 50, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 99, 101, 105, 118, 101, 69, 118, 101, 110, 116, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 48, 52, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 97, 108, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 48, 57, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 82, 101, 102, 101, 114, 101, 110, 99, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 49, 57, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 109, 111, 118, 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 51, 56, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 78, 111, 100, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 55, 54, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 78, 111, 100, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 53, 53, 51, 54, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 76, 101, 118, 101, 108, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 56, 34, 32, 73, 115, 79, 112, 116, 105, 111, 110, 83, 101, 116, 61, 34, 116, 114, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 116, 82, 101, 97, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 116, 87, 114, 105, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 87, 114, 105, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 109, 97, 110, 116, 105, 99, 67, 104, 97, 110, 103, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 87, 114, 105, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 115, 116, 97, 109, 112, 87, 114, 105, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 52, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 76, 101, 118, 101, 108, 69, 120, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 32, 73, 115, 79, 112, 116, 105, 111, 110, 83, 101, 116, 61, 34, 116, 114, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 116, 82, 101, 97, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 116, 87, 114, 105, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 87, 114, 105, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 109, 97, 110, 116, 105, 99, 67, 104, 97, 110, 103, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 87, 114, 105, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 115, 116, 97, 109, 112, 87, 114, 105, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 97, 116, 111, 109, 105, 99, 82, 101, 97, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 53, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 97, 116, 111, 109, 105, 99, 87, 114, 105, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 53, 49, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 70, 117, 108, 108, 65, 114, 114, 97, 121, 79, 110, 108, 121, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 48, 50, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 83, 117, 98, 68, 97, 116, 97, 84, 121, 112, 101, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 48, 52, 56, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 78, 111, 116, 105, 102, 105, 101, 114, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 56, 34, 32, 73, 115, 79, 112, 116, 105, 111, 110, 83, 101, 116, 61, 34, 116, 114, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 98, 101, 84, 111, 69, 118, 101, 110, 116, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 87, 114, 105, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 49, 54, 34, 32, 73, 115, 79, 112, 116, 105, 111, 110, 83, 101, 116, 61, 34, 116, 114, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 105, 103, 110, 105, 110, 103, 82, 101, 113, 117, 105, 114, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 69, 110, 99, 114, 121, 112, 116, 105, 111, 110, 82, 101, 113, 117, 105, 114, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 82, 101, 113, 117, 105, 114, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 112, 112, 108, 121, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 84, 111, 66, 114, 111, 119, 115, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 117, 99, 116, 117, 114, 101, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 117, 99, 116, 117, 114, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 117, 99, 116, 117, 114, 101, 87, 105, 116, 104, 79, 112, 116, 105, 111, 110, 97, 108, 70, 105, 101, 108, 100, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 110, 105, 111, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 117, 99, 116, 117, 114, 101, 70, 105, 101, 108, 100, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 82, 97, 110, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 83, 116, 114, 105, 110, 103, 76, 101, 110, 103, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 79, 112, 116, 105, 111, 110, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 102, 97, 117, 108, 116, 69, 110, 99, 111, 100, 105, 110, 103, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 97, 115, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 117, 99, 116, 117, 114, 101, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 70, 105, 101, 108, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 70, 105, 101, 108, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 110, 117, 109, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 110, 117, 109, 70, 105, 101, 108, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 70, 105, 101, 108, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 102, 101, 114, 101, 110, 99, 101, 78, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 115, 116, 97, 110, 99, 101, 78, 111, 100, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 102, 101, 114, 101, 110, 99, 101, 78, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 121, 112, 101, 78, 111, 100, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 102, 101, 114, 101, 110, 99, 101, 78, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 79, 98, 106, 101, 99, 116, 78, 111, 100, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 73, 110, 115, 116, 97, 110, 99, 101, 78, 111, 100, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 102, 101, 114, 101, 110, 99, 101, 78, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 78, 111, 116, 105, 102, 105, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 79, 98, 106, 101, 99, 116, 84, 121, 112, 101, 78, 111, 100, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 84, 121, 112, 101, 78, 111, 100, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 102, 101, 114, 101, 110, 99, 101, 78, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 65, 98, 115, 116, 114, 97, 99, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 86, 97, 114, 105, 97, 98, 108, 101, 78, 111, 100, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 73, 110, 115, 116, 97, 110, 99, 101, 78, 111, 100, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 102, 101, 114, 101, 110, 99, 101, 78, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 82, 97, 110, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 76, 101, 118, 101, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 65, 99, 99, 101, 115, 115, 76, 101, 118, 101, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 105, 110, 105, 109, 117, 109, 83, 97, 109, 112, 108, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 105, 122, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 76, 101, 118, 101, 108, 69, 120, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 86, 97, 114, 105, 97, 98, 108, 101, 84, 121, 112, 101, 78, 111, 100, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 84, 121, 112, 101, 78, 111, 100, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 102, 101, 114, 101, 110, 99, 101, 78, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 82, 97, 110, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 65, 98, 115, 116, 114, 97, 99, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 78, 111, 100, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 84, 121, 112, 101, 78, 111, 100, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 102, 101, 114, 101, 110, 99, 101, 78, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 65, 98, 115, 116, 114, 97, 99, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 121, 109, 109, 101, 116, 114, 105, 99, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 118, 101, 114, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 101, 116, 104, 111, 100, 78, 111, 100, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 73, 110, 115, 116, 97, 110, 99, 101, 78, 111, 100, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 102, 101, 114, 101, 110, 99, 101, 78, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 120, 101, 99, 117, 116, 97, 98, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 69, 120, 101, 99, 117, 116, 97, 98, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 86, 105, 101, 119, 78, 111, 100, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 73, 110, 115, 116, 97, 110, 99, 101, 78, 111, 100, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 102, 101, 114, 101, 110, 99, 101, 78, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 97, 105, 110, 115, 78, 111, 76, 111, 111, 112, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 78, 111, 116, 105, 102, 105, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 78, 111, 100, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 84, 121, 112, 101, 78, 111, 100, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 49, 54, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 102, 101, 114, 101, 110, 99, 101, 78, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 65, 98, 115, 116, 114, 97, 99, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 78, 111, 100, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 73, 110, 118, 101, 114, 115, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 97, 114, 103, 101, 116, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 114, 103, 117, 109, 101, 110, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 82, 97, 110, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 110, 117, 109, 86, 97, 108, 117, 101, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 54, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 110, 117, 109, 70, 105, 101, 108, 100, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 69, 110, 117, 109, 86, 97, 108, 117, 101, 84, 121, 112, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 54, 52, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 69, 110, 117, 109, 86, 97, 108, 117, 101, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 69, 110, 117, 109, 86, 97, 108, 117, 101, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 69, 110, 117, 109, 86, 97, 108, 117, 101, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 79, 112, 116, 105, 111, 110, 83, 101, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 105, 100, 66, 105, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 110, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 114, 109, 97, 108, 105, 122, 101, 100, 83, 116, 114, 105, 110, 103, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 99, 105, 109, 97, 108, 83, 116, 114, 105, 110, 103, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 117, 114, 97, 116, 105, 111, 110, 83, 116, 114, 105, 110, 103, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 83, 116, 114, 105, 110, 103, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 101, 83, 116, 114, 105, 110, 103, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 117, 114, 97, 116, 105, 111, 110, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 116, 99, 84, 105, 109, 101, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 101, 73, 100, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 90, 111, 110, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 79, 102, 102, 115, 101, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 121, 108, 105, 103, 104, 116, 83, 97, 118, 105, 110, 103, 73, 110, 79, 102, 102, 115, 101, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 100, 101, 120, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 116, 101, 103, 101, 114, 73, 100, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 65, 110, 100, 83, 101, 114, 118, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 99, 111, 118, 101, 114, 121, 83, 101, 114, 118, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 114, 111, 100, 117, 99, 116, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 71, 97, 116, 101, 119, 97, 121, 83, 101, 114, 118, 101, 114, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 99, 111, 118, 101, 114, 121, 80, 114, 111, 102, 105, 108, 101, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 115, 99, 111, 118, 101, 114, 121, 85, 114, 108, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 99, 111, 118, 101, 114, 121, 85, 114, 108, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 115, 99, 111, 118, 101, 114, 121, 85, 114, 108, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 84, 111, 107, 101, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 115, 116, 97, 109, 112, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 97, 110, 100, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 116, 117, 114, 110, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 117, 100, 105, 116, 69, 110, 116, 114, 121, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 111, 117, 116, 72, 105, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 105, 116, 105, 111, 110, 97, 108, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 115, 116, 97, 109, 112, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 97, 110, 100, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 105, 99, 101, 82, 101, 115, 117, 108, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 105, 99, 101, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 116, 114, 105, 110, 103, 84, 97, 98, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 114, 105, 110, 103, 84, 97, 98, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 116, 114, 105, 110, 103, 84, 97, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 105, 116, 105, 111, 110, 97, 108, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 86, 101, 114, 115, 105, 111, 110, 84, 105, 109, 101, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 105, 99, 101, 70, 97, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 108, 101, 115, 115, 73, 110, 118, 111, 107, 101, 82, 101, 113, 117, 101, 115, 116, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 114, 105, 115, 86, 101, 114, 115, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 97, 109, 101, 115, 112, 97, 99, 101, 85, 114, 105, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 85, 114, 105, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 97, 109, 101, 115, 112, 97, 99, 101, 85, 114, 105, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 85, 114, 105, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 85, 114, 105, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 85, 114, 105, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 105, 99, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 108, 101, 115, 115, 73, 110, 118, 111, 107, 101, 82, 101, 115, 112, 111, 110, 115, 101, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 97, 109, 101, 115, 112, 97, 99, 101, 85, 114, 105, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 85, 114, 105, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 97, 109, 101, 115, 112, 97, 99, 101, 85, 114, 105, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 85, 114, 105, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 85, 114, 105, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 85, 114, 105, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 105, 99, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 70, 105, 110, 100, 83, 101, 114, 118, 101, 114, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 112, 111, 105, 110, 116, 85, 114, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 85, 114, 105, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 85, 114, 105, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 85, 114, 105, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 70, 105, 110, 100, 83, 101, 114, 118, 101, 114, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 79, 110, 78, 101, 116, 119, 111, 114, 107, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 99, 111, 114, 100, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 99, 111, 118, 101, 114, 121, 85, 114, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 67, 97, 112, 97, 98, 105, 108, 105, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 67, 97, 112, 97, 98, 105, 108, 105, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 67, 97, 112, 97, 98, 105, 108, 105, 116, 105, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 70, 105, 110, 100, 83, 101, 114, 118, 101, 114, 115, 79, 110, 78, 101, 116, 119, 111, 114, 107, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 114, 116, 105, 110, 103, 82, 101, 99, 111, 114, 100, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 82, 101, 99, 111, 114, 100, 115, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 67, 97, 112, 97, 98, 105, 108, 105, 116, 121, 70, 105, 108, 116, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 67, 97, 112, 97, 98, 105, 108, 105, 116, 121, 70, 105, 108, 116, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 67, 97, 112, 97, 98, 105, 108, 105, 116, 121, 70, 105, 108, 116, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 70, 105, 110, 100, 83, 101, 114, 118, 101, 114, 115, 79, 110, 78, 101, 116, 119, 111, 114, 107, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 67, 111, 117, 110, 116, 101, 114, 82, 101, 115, 101, 116, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 101, 114, 79, 110, 78, 101, 116, 119, 111, 114, 107, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 73, 110, 115, 116, 97, 110, 99, 101, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 101, 115, 115, 97, 103, 101, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 118, 97, 108, 105, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 105, 103, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 105, 103, 110, 65, 110, 100, 69, 110, 99, 114, 121, 112, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 84, 111, 107, 101, 110, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 110, 111, 110, 121, 109, 111, 117, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 78, 97, 109, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 115, 115, 117, 101, 100, 84, 111, 107, 101, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 84, 111, 107, 101, 110, 80, 111, 108, 105, 99, 121, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 111, 108, 105, 99, 121, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 111, 107, 101, 110, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 85, 115, 101, 114, 84, 111, 107, 101, 110, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 115, 117, 101, 100, 84, 111, 107, 101, 110, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 115, 117, 101, 114, 69, 110, 100, 112, 111, 105, 110, 116, 85, 114, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 80, 111, 108, 105, 99, 121, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 112, 111, 105, 110, 116, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 112, 111, 105, 110, 116, 85, 114, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 101, 115, 115, 97, 103, 101, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 80, 111, 108, 105, 99, 121, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 85, 115, 101, 114, 84, 111, 107, 101, 110, 80, 111, 108, 105, 99, 121, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 115, 101, 114, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 112, 111, 114, 116, 80, 114, 111, 102, 105, 108, 101, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 76, 101, 118, 101, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 71, 101, 116, 69, 110, 100, 112, 111, 105, 110, 116, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 112, 111, 105, 110, 116, 85, 114, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 80, 114, 111, 102, 105, 108, 101, 85, 114, 105, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 114, 111, 102, 105, 108, 101, 85, 114, 105, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 80, 114, 111, 102, 105, 108, 101, 85, 114, 105, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 71, 101, 116, 69, 110, 100, 112, 111, 105, 110, 116, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 110, 100, 112, 111, 105, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 112, 111, 105, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 110, 100, 112, 111, 105, 110, 116, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 110, 100, 112, 111, 105, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 103, 105, 115, 116, 101, 114, 101, 100, 83, 101, 114, 118, 101, 114, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 114, 111, 100, 117, 99, 116, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 78, 97, 109, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 78, 97, 109, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 78, 97, 109, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 71, 97, 116, 101, 119, 97, 121, 83, 101, 114, 118, 101, 114, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 115, 99, 111, 118, 101, 114, 121, 85, 114, 108, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 99, 111, 118, 101, 114, 121, 85, 114, 108, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 115, 99, 111, 118, 101, 114, 121, 85, 114, 108, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 109, 97, 112, 104, 111, 114, 101, 70, 105, 108, 101, 80, 97, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 79, 110, 108, 105, 110, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 103, 105, 115, 116, 101, 114, 83, 101, 114, 118, 101, 114, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 103, 105, 115, 116, 101, 114, 101, 100, 83, 101, 114, 118, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 103, 105, 115, 116, 101, 114, 83, 101, 114, 118, 101, 114, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 99, 111, 118, 101, 114, 121, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 100, 110, 115, 68, 105, 115, 99, 111, 118, 101, 114, 121, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 68, 105, 115, 99, 111, 118, 101, 114, 121, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 100, 110, 115, 83, 101, 114, 118, 101, 114, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 67, 97, 112, 97, 98, 105, 108, 105, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 67, 97, 112, 97, 98, 105, 108, 105, 116, 105, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 67, 97, 112, 97, 98, 105, 108, 105, 116, 105, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 103, 105, 115, 116, 101, 114, 83, 101, 114, 118, 101, 114, 50, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 103, 105, 115, 116, 101, 114, 101, 100, 83, 101, 114, 118, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 115, 99, 111, 118, 101, 114, 121, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 99, 111, 118, 101, 114, 121, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 115, 99, 111, 118, 101, 114, 121, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 103, 105, 115, 116, 101, 114, 83, 101, 114, 118, 101, 114, 50, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 84, 111, 107, 101, 110, 82, 101, 113, 117, 101, 115, 116, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 115, 115, 117, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 110, 101, 119, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 104, 97, 110, 110, 101, 108, 83, 101, 99, 117, 114, 105, 116, 121, 84, 111, 107, 101, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 104, 97, 110, 110, 101, 108, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 111, 107, 101, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 114, 101, 97, 116, 101, 100, 65, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 76, 105, 102, 101, 116, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 79, 112, 101, 110, 83, 101, 99, 117, 114, 101, 67, 104, 97, 110, 110, 101, 108, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 80, 114, 111, 116, 111, 99, 111, 108, 86, 101, 114, 115, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 99, 117, 114, 105, 116, 121, 84, 111, 107, 101, 110, 82, 101, 113, 117, 101, 115, 116, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 101, 115, 115, 97, 103, 101, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 78, 111, 110, 99, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 76, 105, 102, 101, 116, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 79, 112, 101, 110, 83, 101, 99, 117, 114, 101, 67, 104, 97, 110, 110, 101, 108, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 80, 114, 111, 116, 111, 99, 111, 108, 86, 101, 114, 115, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 84, 111, 107, 101, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 67, 104, 97, 110, 110, 101, 108, 83, 101, 99, 117, 114, 105, 116, 121, 84, 111, 107, 101, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 78, 111, 110, 99, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 108, 111, 115, 101, 83, 101, 99, 117, 114, 101, 67, 104, 97, 110, 110, 101, 108, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 108, 111, 115, 101, 83, 101, 99, 117, 114, 101, 67, 104, 97, 110, 110, 101, 108, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 105, 103, 110, 101, 100, 83, 111, 102, 116, 119, 97, 114, 101, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 68, 97, 116, 97, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 105, 103, 110, 97, 116, 117, 114, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 84, 111, 107, 101, 110, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 105, 103, 110, 97, 116, 117, 114, 101, 68, 97, 116, 97, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 108, 103, 111, 114, 105, 116, 104, 109, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 105, 103, 110, 97, 116, 117, 114, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 114, 101, 97, 116, 101, 83, 101, 115, 115, 105, 111, 110, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 112, 111, 105, 110, 116, 85, 114, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 78, 111, 110, 99, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 83, 101, 115, 115, 105, 111, 110, 84, 105, 109, 101, 111, 117, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 82, 101, 115, 112, 111, 110, 115, 101, 77, 101, 115, 115, 97, 103, 101, 83, 105, 122, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 114, 101, 97, 116, 101, 83, 101, 115, 115, 105, 111, 110, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 84, 111, 107, 101, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 83, 101, 115, 115, 105, 111, 110, 84, 105, 109, 101, 111, 117, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 78, 111, 110, 99, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 69, 110, 100, 112, 111, 105, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 69, 110, 100, 112, 111, 105, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 110, 100, 112, 111, 105, 110, 116, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 69, 110, 100, 112, 111, 105, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 83, 111, 102, 116, 119, 97, 114, 101, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 83, 111, 102, 116, 119, 97, 114, 101, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 105, 103, 110, 101, 100, 83, 111, 102, 116, 119, 97, 114, 101, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 114, 118, 101, 114, 83, 111, 102, 116, 119, 97, 114, 101, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 83, 105, 103, 110, 97, 116, 117, 114, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 105, 103, 110, 97, 116, 117, 114, 101, 68, 97, 116, 97, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 82, 101, 113, 117, 101, 115, 116, 77, 101, 115, 115, 97, 103, 101, 83, 105, 122, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 111, 108, 105, 99, 121, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 110, 111, 110, 121, 109, 111, 117, 115, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 85, 115, 101, 114, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 111, 108, 105, 99, 121, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 85, 115, 101, 114, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 78, 97, 109, 101, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 85, 115, 101, 114, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 111, 108, 105, 99, 121, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 85, 115, 101, 114, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 97, 115, 115, 119, 111, 114, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 99, 114, 121, 112, 116, 105, 111, 110, 65, 108, 103, 111, 114, 105, 116, 104, 109, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 88, 53, 48, 57, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 85, 115, 101, 114, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 111, 108, 105, 99, 121, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 85, 115, 101, 114, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 68, 97, 116, 97, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 73, 115, 115, 117, 101, 100, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 85, 115, 101, 114, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 111, 108, 105, 99, 121, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 85, 115, 101, 114, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 111, 107, 101, 110, 68, 97, 116, 97, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 99, 114, 121, 112, 116, 105, 111, 110, 65, 108, 103, 111, 114, 105, 116, 104, 109, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 115, 97, 69, 110, 99, 114, 121, 112, 116, 101, 100, 83, 101, 99, 114, 101, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 99, 99, 69, 110, 99, 114, 121, 112, 116, 101, 100, 83, 101, 99, 114, 101, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 99, 116, 105, 118, 97, 116, 101, 83, 101, 115, 115, 105, 111, 110, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 83, 105, 103, 110, 97, 116, 117, 114, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 105, 103, 110, 97, 116, 117, 114, 101, 68, 97, 116, 97, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 67, 108, 105, 101, 110, 116, 83, 111, 102, 116, 119, 97, 114, 101, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 83, 111, 102, 116, 119, 97, 114, 101, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 105, 103, 110, 101, 100, 83, 111, 102, 116, 119, 97, 114, 101, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 67, 108, 105, 101, 110, 116, 83, 111, 102, 116, 119, 97, 114, 101, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 73, 100, 101, 110, 116, 105, 116, 121, 84, 111, 107, 101, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 84, 111, 107, 101, 110, 83, 105, 103, 110, 97, 116, 117, 114, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 105, 103, 110, 97, 116, 117, 114, 101, 68, 97, 116, 97, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 99, 116, 105, 118, 97, 116, 101, 83, 101, 115, 115, 105, 111, 110, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 78, 111, 110, 99, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 108, 111, 115, 101, 83, 101, 115, 115, 105, 111, 110, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 108, 111, 115, 101, 83, 101, 115, 115, 105, 111, 110, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 97, 110, 99, 101, 108, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 97, 110, 100, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 97, 110, 99, 101, 108, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 97, 110, 99, 101, 108, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 77, 97, 115, 107, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 76, 101, 118, 101, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 97, 105, 110, 115, 78, 111, 76, 111, 111, 112, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 78, 111, 116, 105, 102, 105, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 50, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 69, 120, 101, 99, 117, 116, 97, 98, 108, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 53, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 105, 122, 105, 110, 103, 34, 32, 86, 97, 108, 117, 101, 61, 34, 53, 49, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 118, 101, 114, 115, 101, 78, 97, 109, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 48, 50, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 115, 65, 98, 115, 116, 114, 97, 99, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 48, 52, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 77, 105, 110, 105, 109, 117, 109, 83, 97, 109, 112, 108, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 48, 57, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 49, 57, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 51, 56, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 121, 109, 109, 101, 116, 114, 105, 99, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 55, 54, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 65, 99, 99, 101, 115, 115, 76, 101, 118, 101, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 53, 53, 51, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 69, 120, 101, 99, 117, 116, 97, 98, 108, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 51, 49, 48, 55, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 54, 50, 49, 52, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 82, 97, 110, 107, 34, 32, 86, 97, 108, 117, 101, 61, 34, 53, 50, 52, 50, 56, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 48, 52, 56, 53, 55, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 48, 57, 55, 49, 53, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 49, 57, 52, 51, 48, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 51, 56, 56, 54, 48, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 55, 55, 55, 50, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 108, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 51, 53, 53, 52, 52, 51, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 66, 97, 115, 101, 78, 111, 100, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 54, 53, 48, 49, 50, 50, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 79, 98, 106, 101, 99, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 54, 53, 48, 49, 51, 52, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 79, 98, 106, 101, 99, 116, 84, 121, 112, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 54, 53, 48, 51, 50, 54, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 86, 97, 114, 105, 97, 98, 108, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 54, 53, 55, 49, 51, 56, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 86, 97, 114, 105, 97, 98, 108, 101, 84, 121, 112, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 56, 54, 48, 48, 52, 51, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 77, 101, 116, 104, 111, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 54, 54, 51, 50, 53, 52, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 54, 53, 51, 55, 48, 54, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 86, 105, 101, 119, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 54, 53, 48, 49, 51, 53, 54, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 112, 101, 99, 105, 102, 105, 101, 100, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 79, 98, 106, 101, 99, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 112, 101, 99, 105, 102, 105, 101, 100, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 78, 111, 116, 105, 102, 105, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 86, 97, 114, 105, 97, 98, 108, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 112, 101, 99, 105, 102, 105, 101, 100, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 82, 97, 110, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 76, 101, 118, 101, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 65, 99, 99, 101, 115, 115, 76, 101, 118, 101, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 105, 110, 105, 109, 117, 109, 83, 97, 109, 112, 108, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 105, 122, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 101, 116, 104, 111, 100, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 112, 101, 99, 105, 102, 105, 101, 100, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 120, 101, 99, 117, 116, 97, 98, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 69, 120, 101, 99, 117, 116, 97, 98, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 79, 98, 106, 101, 99, 116, 84, 121, 112, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 112, 101, 99, 105, 102, 105, 101, 100, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 65, 98, 115, 116, 114, 97, 99, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 86, 97, 114, 105, 97, 98, 108, 101, 84, 121, 112, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 112, 101, 99, 105, 102, 105, 101, 100, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 82, 97, 110, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 65, 98, 115, 116, 114, 97, 99, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 112, 101, 99, 105, 102, 105, 101, 100, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 65, 98, 115, 116, 114, 97, 99, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 121, 109, 109, 101, 116, 114, 105, 99, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 118, 101, 114, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 112, 101, 99, 105, 102, 105, 101, 100, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 65, 98, 115, 116, 114, 97, 99, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 86, 105, 101, 119, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 112, 101, 99, 105, 102, 105, 101, 100, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 97, 105, 110, 115, 78, 111, 76, 111, 111, 112, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 78, 111, 116, 105, 102, 105, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 71, 101, 110, 101, 114, 105, 99, 65, 116, 116, 114, 105, 98, 117, 116, 101, 86, 97, 108, 117, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 116, 116, 114, 105, 98, 117, 116, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 71, 101, 110, 101, 114, 105, 99, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 112, 101, 99, 105, 102, 105, 101, 100, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 116, 116, 114, 105, 98, 117, 116, 101, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 116, 116, 114, 105, 98, 117, 116, 101, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 71, 101, 110, 101, 114, 105, 99, 65, 116, 116, 114, 105, 98, 117, 116, 101, 86, 97, 108, 117, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 116, 116, 114, 105, 98, 117, 116, 101, 86, 97, 108, 117, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 78, 111, 100, 101, 115, 73, 116, 101, 109, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 97, 114, 101, 110, 116, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 78, 101, 119, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 121, 112, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 78, 111, 100, 101, 115, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 78, 111, 100, 101, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 65, 100, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 115, 84, 111, 65, 100, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 100, 100, 78, 111, 100, 101, 115, 73, 116, 101, 109, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 65, 100, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 78, 111, 100, 101, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 100, 100, 78, 111, 100, 101, 115, 82, 101, 115, 117, 108, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 73, 116, 101, 109, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 111, 117, 114, 99, 101, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 70, 111, 114, 119, 97, 114, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 97, 114, 103, 101, 116, 83, 101, 114, 118, 101, 114, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 97, 114, 103, 101, 116, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 97, 114, 103, 101, 116, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 84, 111, 65, 100, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 84, 111, 65, 100, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 100, 100, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 73, 116, 101, 109, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 84, 111, 65, 100, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 78, 111, 100, 101, 115, 73, 116, 101, 109, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 84, 97, 114, 103, 101, 116, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 78, 111, 100, 101, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 68, 101, 108, 101, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 115, 84, 111, 68, 101, 108, 101, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 68, 101, 108, 101, 116, 101, 78, 111, 100, 101, 115, 73, 116, 101, 109, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 68, 101, 108, 101, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 78, 111, 100, 101, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 73, 116, 101, 109, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 111, 117, 114, 99, 101, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 70, 111, 114, 119, 97, 114, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 97, 114, 103, 101, 116, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 66, 105, 100, 105, 114, 101, 99, 116, 105, 111, 110, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 84, 111, 68, 101, 108, 101, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 84, 111, 68, 101, 108, 101, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 68, 101, 108, 101, 116, 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 73, 116, 101, 109, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 84, 111, 68, 101, 108, 101, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 116, 116, 114, 105, 98, 117, 116, 101, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 32, 73, 115, 79, 112, 116, 105, 111, 110, 83, 101, 116, 61, 34, 116, 114, 117, 101, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 76, 101, 118, 101, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 114, 114, 97, 121, 68, 105, 109, 101, 110, 115, 105, 111, 110, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 97, 105, 110, 115, 78, 111, 76, 111, 111, 112, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 78, 111, 116, 105, 102, 105, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 50, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 69, 120, 101, 99, 117, 116, 97, 98, 108, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 53, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 105, 122, 105, 110, 103, 34, 32, 86, 97, 108, 117, 101, 61, 34, 53, 49, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 118, 101, 114, 115, 101, 78, 97, 109, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 48, 50, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 115, 65, 98, 115, 116, 114, 97, 99, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 48, 52, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 77, 105, 110, 105, 109, 117, 109, 83, 97, 109, 112, 108, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 48, 57, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 49, 57, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 51, 56, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 121, 109, 109, 101, 116, 114, 105, 99, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 55, 54, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 65, 99, 99, 101, 115, 115, 76, 101, 118, 101, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 53, 53, 51, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 69, 120, 101, 99, 117, 116, 97, 98, 108, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 51, 49, 48, 55, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 54, 50, 49, 52, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 82, 97, 110, 107, 34, 32, 86, 97, 108, 117, 101, 61, 34, 53, 50, 52, 50, 56, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 77, 97, 115, 107, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 48, 52, 56, 53, 55, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 70, 111, 114, 86, 97, 114, 105, 97, 98, 108, 101, 84, 121, 112, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 48, 57, 55, 49, 53, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 49, 57, 52, 51, 48, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 111, 108, 101, 80, 101, 114, 109, 105, 115, 115, 105, 111, 110, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 51, 56, 56, 54, 48, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 82, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 55, 55, 55, 50, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 99, 99, 101, 115, 115, 76, 101, 118, 101, 108, 69, 120, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 51, 53, 53, 52, 52, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 68, 105, 114, 101, 99, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 70, 111, 114, 119, 97, 114, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 118, 101, 114, 115, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 66, 111, 116, 104, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 118, 97, 108, 105, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 86, 105, 101, 119, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 105, 101, 119, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 115, 116, 97, 109, 112, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 105, 101, 119, 86, 101, 114, 115, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 68, 105, 114, 101, 99, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 66, 114, 111, 119, 115, 101, 68, 105, 114, 101, 99, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 99, 108, 117, 100, 101, 83, 117, 98, 116, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 77, 97, 115, 107, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 82, 101, 115, 117, 108, 116, 77, 97, 115, 107, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 73, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 115, 70, 111, 114, 119, 97, 114, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 84, 121, 112, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 108, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 73, 110, 102, 111, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 84, 97, 114, 103, 101, 116, 73, 110, 102, 111, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 48, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 70, 111, 114, 119, 97, 114, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 67, 108, 97, 115, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 121, 112, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 105, 110, 117, 97, 116, 105, 111, 110, 80, 111, 105, 110, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 105, 110, 117, 97, 116, 105, 111, 110, 80, 111, 105, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 102, 101, 114, 101, 110, 99, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 105, 101, 119, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 86, 105, 101, 119, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 77, 97, 120, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 80, 101, 114, 78, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 66, 114, 111, 119, 115, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 115, 84, 111, 66, 114, 111, 119, 115, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 66, 114, 111, 119, 115, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 66, 114, 111, 119, 115, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 66, 114, 111, 119, 115, 101, 82, 101, 115, 117, 108, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 101, 120, 116, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 108, 101, 97, 115, 101, 67, 111, 110, 116, 105, 110, 117, 97, 116, 105, 111, 110, 80, 111, 105, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 67, 111, 110, 116, 105, 110, 117, 97, 116, 105, 111, 110, 80, 111, 105, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 105, 110, 117, 97, 116, 105, 111, 110, 80, 111, 105, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 67, 111, 110, 116, 105, 110, 117, 97, 116, 105, 111, 110, 80, 111, 105, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 101, 120, 116, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 66, 114, 111, 119, 115, 101, 82, 101, 115, 117, 108, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 108, 97, 116, 105, 118, 101, 80, 97, 116, 104, 69, 108, 101, 109, 101, 110, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 73, 110, 118, 101, 114, 115, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 99, 108, 117, 100, 101, 83, 117, 98, 116, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 97, 114, 103, 101, 116, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 108, 97, 116, 105, 118, 101, 80, 97, 116, 104, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 108, 101, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 108, 101, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 108, 97, 116, 105, 118, 101, 80, 97, 116, 104, 69, 108, 101, 109, 101, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 108, 101, 109, 101, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 114, 116, 105, 110, 103, 78, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 108, 97, 116, 105, 118, 101, 80, 97, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 108, 97, 116, 105, 118, 101, 80, 97, 116, 104, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 84, 97, 114, 103, 101, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 97, 114, 103, 101, 116, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 109, 97, 105, 110, 105, 110, 103, 80, 97, 116, 104, 73, 110, 100, 101, 120, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 84, 97, 114, 103, 101, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 97, 114, 103, 101, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 84, 97, 114, 103, 101, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 84, 97, 114, 103, 101, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 108, 97, 116, 101, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 115, 84, 111, 78, 111, 100, 101, 73, 100, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 108, 97, 116, 101, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 115, 84, 111, 78, 111, 100, 101, 73, 100, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 82, 101, 115, 117, 108, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 103, 105, 115, 116, 101, 114, 78, 111, 100, 101, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 82, 101, 103, 105, 115, 116, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 115, 84, 111, 82, 101, 103, 105, 115, 116, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 82, 101, 103, 105, 115, 116, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 103, 105, 115, 116, 101, 114, 78, 111, 100, 101, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 103, 105, 115, 116, 101, 114, 101, 100, 78, 111, 100, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 103, 105, 115, 116, 101, 114, 101, 100, 78, 111, 100, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 103, 105, 115, 116, 101, 114, 101, 100, 78, 111, 100, 101, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 110, 114, 101, 103, 105, 115, 116, 101, 114, 78, 111, 100, 101, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 85, 110, 114, 101, 103, 105, 115, 116, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 115, 84, 111, 85, 110, 114, 101, 103, 105, 115, 116, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 85, 110, 114, 101, 103, 105, 115, 116, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 110, 114, 101, 103, 105, 115, 116, 101, 114, 78, 111, 100, 101, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 117, 110, 116, 101, 114, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 117, 109, 101, 114, 105, 99, 82, 97, 110, 103, 101, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 79, 112, 97, 113, 117, 101, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 112, 111, 105, 110, 116, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 79, 112, 101, 114, 97, 116, 105, 111, 110, 84, 105, 109, 101, 111, 117, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 66, 105, 110, 97, 114, 121, 69, 110, 99, 111, 100, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 83, 116, 114, 105, 110, 103, 76, 101, 110, 103, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 76, 101, 110, 103, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 65, 114, 114, 97, 121, 76, 101, 110, 103, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 77, 101, 115, 115, 97, 103, 101, 83, 105, 122, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 66, 117, 102, 102, 101, 114, 83, 105, 122, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 104, 97, 110, 110, 101, 108, 76, 105, 102, 101, 116, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 84, 111, 107, 101, 110, 76, 105, 102, 101, 116, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 114, 121, 68, 97, 116, 97, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 108, 97, 116, 105, 118, 101, 80, 97, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 108, 97, 116, 105, 118, 101, 80, 97, 116, 104, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 116, 116, 114, 105, 98, 117, 116, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 100, 101, 120, 82, 97, 110, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 121, 112, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 78, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 99, 108, 117, 100, 101, 83, 117, 98, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 81, 117, 101, 114, 121, 68, 97, 116, 97, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 70, 105, 108, 116, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 69, 113, 117, 97, 108, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 115, 78, 117, 108, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 71, 114, 101, 97, 116, 101, 114, 84, 104, 97, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 76, 101, 115, 115, 84, 104, 97, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 71, 114, 101, 97, 116, 101, 114, 84, 104, 97, 110, 79, 114, 69, 113, 117, 97, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 76, 101, 115, 115, 84, 104, 97, 110, 79, 114, 69, 113, 117, 97, 108, 34, 32, 86, 97, 108, 117, 101, 61, 34, 53, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 76, 105, 107, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 55, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 66, 101, 116, 119, 101, 101, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 76, 105, 115, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 57, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 110, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 79, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 97, 115, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 86, 105, 101, 119, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 79, 102, 84, 121, 112, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 108, 97, 116, 101, 100, 84, 111, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 53, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 66, 105, 116, 119, 105, 115, 101, 65, 110, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 66, 105, 116, 119, 105, 115, 101, 79, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 55, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 114, 121, 68, 97, 116, 97, 83, 101, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 121, 112, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 78, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 112, 97, 110, 100, 101, 100, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 86, 97, 108, 117, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 84, 121, 112, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 70, 111, 114, 119, 97, 114, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 100, 78, 111, 100, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 100, 78, 111, 100, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 102, 101, 114, 101, 110, 99, 101, 100, 78, 111, 100, 101, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 101, 110, 116, 70, 105, 108, 116, 101, 114, 69, 108, 101, 109, 101, 110, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 108, 116, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 70, 105, 108, 116, 101, 114, 79, 112, 101, 114, 97, 116, 111, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 70, 105, 108, 116, 101, 114, 79, 112, 101, 114, 97, 110, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 108, 116, 101, 114, 79, 112, 101, 114, 97, 110, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 70, 105, 108, 116, 101, 114, 79, 112, 101, 114, 97, 110, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 101, 110, 116, 70, 105, 108, 116, 101, 114, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 108, 101, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 108, 101, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 67, 111, 110, 116, 101, 110, 116, 70, 105, 108, 116, 101, 114, 69, 108, 101, 109, 101, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 108, 101, 109, 101, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 70, 105, 108, 116, 101, 114, 79, 112, 101, 114, 97, 110, 100, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 108, 101, 109, 101, 110, 116, 79, 112, 101, 114, 97, 110, 100, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 70, 105, 108, 116, 101, 114, 79, 112, 101, 114, 97, 110, 100, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 100, 101, 120, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 76, 105, 116, 101, 114, 97, 108, 79, 112, 101, 114, 97, 110, 100, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 70, 105, 108, 116, 101, 114, 79, 112, 101, 114, 97, 110, 100, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 116, 116, 114, 105, 98, 117, 116, 101, 79, 112, 101, 114, 97, 110, 100, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 70, 105, 108, 116, 101, 114, 79, 112, 101, 114, 97, 110, 100, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 108, 105, 97, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 108, 97, 116, 105, 118, 101, 80, 97, 116, 104, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 116, 116, 114, 105, 98, 117, 116, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 100, 101, 120, 82, 97, 110, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 105, 109, 112, 108, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 79, 112, 101, 114, 97, 110, 100, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 70, 105, 108, 116, 101, 114, 79, 112, 101, 114, 97, 110, 100, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 121, 112, 101, 68, 101, 102, 105, 110, 105, 116, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 116, 116, 114, 105, 98, 117, 116, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 100, 101, 120, 82, 97, 110, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 101, 110, 116, 70, 105, 108, 116, 101, 114, 69, 108, 101, 109, 101, 110, 116, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 79, 112, 101, 114, 97, 110, 100, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 79, 112, 101, 114, 97, 110, 100, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 79, 112, 101, 114, 97, 110, 100, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 79, 112, 101, 114, 97, 110, 100, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 79, 112, 101, 114, 97, 110, 100, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 79, 112, 101, 114, 97, 110, 100, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 101, 110, 116, 70, 105, 108, 116, 101, 114, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 108, 101, 109, 101, 110, 116, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 108, 101, 109, 101, 110, 116, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 67, 111, 110, 116, 101, 110, 116, 70, 105, 108, 116, 101, 114, 69, 108, 101, 109, 101, 110, 116, 82, 101, 115, 117, 108, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 108, 101, 109, 101, 110, 116, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 108, 101, 109, 101, 110, 116, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 108, 101, 109, 101, 110, 116, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 108, 101, 109, 101, 110, 116, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 97, 114, 115, 105, 110, 103, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 114, 121, 70, 105, 114, 115, 116, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 105, 101, 119, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 86, 105, 101, 119, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 84, 121, 112, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 100, 101, 84, 121, 112, 101, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 84, 121, 112, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 108, 116, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 67, 111, 110, 116, 101, 110, 116, 70, 105, 108, 116, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 68, 97, 116, 97, 83, 101, 116, 115, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 114, 121, 70, 105, 114, 115, 116, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 81, 117, 101, 114, 121, 68, 97, 116, 97, 83, 101, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 114, 121, 68, 97, 116, 97, 83, 101, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 81, 117, 101, 114, 121, 68, 97, 116, 97, 83, 101, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 81, 117, 101, 114, 121, 68, 97, 116, 97, 83, 101, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 105, 110, 117, 97, 116, 105, 111, 110, 80, 111, 105, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 80, 97, 114, 115, 105, 110, 103, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 97, 114, 115, 105, 110, 103, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 80, 97, 114, 115, 105, 110, 103, 82, 101, 115, 117, 108, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 80, 97, 114, 115, 105, 110, 103, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 108, 116, 101, 114, 82, 101, 115, 117, 108, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 67, 111, 110, 116, 101, 110, 116, 70, 105, 108, 116, 101, 114, 82, 101, 115, 117, 108, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 114, 121, 78, 101, 120, 116, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 108, 101, 97, 115, 101, 67, 111, 110, 116, 105, 110, 117, 97, 116, 105, 111, 110, 80, 111, 105, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 105, 110, 117, 97, 116, 105, 111, 110, 80, 111, 105, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 114, 121, 78, 101, 120, 116, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 81, 117, 101, 114, 121, 68, 97, 116, 97, 83, 101, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 114, 121, 68, 97, 116, 97, 83, 101, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 81, 117, 101, 114, 121, 68, 97, 116, 97, 83, 101, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 81, 117, 101, 114, 121, 68, 97, 116, 97, 83, 101, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 67, 111, 110, 116, 105, 110, 117, 97, 116, 105, 111, 110, 80, 111, 105, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 115, 116, 97, 109, 112, 115, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 111, 117, 114, 99, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 66, 111, 116, 104, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 101, 105, 116, 104, 101, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 118, 97, 108, 105, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 86, 97, 108, 117, 101, 73, 100, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 116, 116, 114, 105, 98, 117, 116, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 100, 101, 120, 82, 97, 110, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 69, 110, 99, 111, 100, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 65, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 115, 116, 97, 109, 112, 115, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 84, 105, 109, 101, 115, 116, 97, 109, 112, 115, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 82, 101, 97, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 115, 84, 111, 82, 101, 97, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 97, 100, 86, 97, 108, 117, 101, 73, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 82, 101, 97, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 97, 116, 97, 86, 97, 108, 117, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 86, 97, 108, 117, 101, 73, 100, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 100, 101, 120, 82, 97, 110, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 69, 110, 99, 111, 100, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 81, 117, 97, 108, 105, 102, 105, 101, 100, 78, 97, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 105, 110, 117, 97, 116, 105, 111, 110, 80, 111, 105, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 111, 110, 116, 105, 110, 117, 97, 116, 105, 111, 110, 80, 111, 105, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 68, 97, 116, 97, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 68, 101, 116, 97, 105, 108, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 69, 118, 101, 110, 116, 68, 101, 116, 97, 105, 108, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 68, 101, 116, 97, 105, 108, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 117, 109, 86, 97, 108, 117, 101, 115, 80, 101, 114, 78, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 114, 116, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 108, 116, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 118, 101, 110, 116, 70, 105, 108, 116, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 82, 97, 119, 77, 111, 100, 105, 102, 105, 101, 100, 68, 101, 116, 97, 105, 108, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 68, 101, 116, 97, 105, 108, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 82, 101, 97, 100, 77, 111, 100, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 114, 116, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 117, 109, 86, 97, 108, 117, 101, 115, 80, 101, 114, 78, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 116, 117, 114, 110, 66, 111, 117, 110, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 80, 114, 111, 99, 101, 115, 115, 101, 100, 68, 101, 116, 97, 105, 108, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 68, 101, 116, 97, 105, 108, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 114, 116, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 114, 111, 99, 101, 115, 115, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 103, 103, 114, 101, 103, 97, 116, 101, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 103, 103, 114, 101, 103, 97, 116, 101, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 103, 103, 114, 101, 103, 97, 116, 101, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 103, 103, 114, 101, 103, 97, 116, 101, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 103, 103, 114, 101, 103, 97, 116, 101, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 65, 116, 84, 105, 109, 101, 68, 101, 116, 97, 105, 108, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 68, 101, 116, 97, 105, 108, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 113, 84, 105, 109, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 84, 105, 109, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 113, 84, 105, 109, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 83, 105, 109, 112, 108, 101, 66, 111, 117, 110, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 68, 97, 116, 97, 68, 101, 116, 97, 105, 108, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 68, 101, 116, 97, 105, 108, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 113, 84, 105, 109, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 84, 105, 109, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 113, 84, 105, 109, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 68, 97, 116, 97, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 97, 116, 97, 86, 97, 108, 117, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 86, 97, 108, 117, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 100, 105, 102, 105, 99, 97, 116, 105, 111, 110, 73, 110, 102, 111, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 100, 105, 102, 105, 99, 97, 116, 105, 111, 110, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 112, 100, 97, 116, 101, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 77, 111, 100, 105, 102, 105, 101, 100, 68, 97, 116, 97, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 68, 97, 116, 97, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 97, 116, 97, 86, 97, 108, 117, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 97, 116, 97, 86, 97, 108, 117, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 77, 111, 100, 105, 102, 105, 99, 97, 116, 105, 111, 110, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 100, 105, 102, 105, 99, 97, 116, 105, 111, 110, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 111, 100, 105, 102, 105, 99, 97, 116, 105, 111, 110, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 77, 111, 100, 105, 102, 105, 99, 97, 116, 105, 111, 110, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 69, 118, 101, 110, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 118, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 69, 118, 101, 110, 116, 70, 105, 101, 108, 100, 76, 105, 115, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 118, 101, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 68, 101, 116, 97, 105, 108, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 115, 116, 97, 109, 112, 115, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 84, 105, 109, 101, 115, 116, 97, 109, 112, 115, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 108, 101, 97, 115, 101, 67, 111, 110, 116, 105, 110, 117, 97, 116, 105, 111, 110, 80, 111, 105, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 82, 101, 97, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 115, 84, 111, 82, 101, 97, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 86, 97, 108, 117, 101, 73, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 82, 101, 97, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 82, 101, 115, 117, 108, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 86, 97, 108, 117, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 116, 116, 114, 105, 98, 117, 116, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 100, 101, 120, 82, 97, 110, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 97, 116, 97, 86, 97, 108, 117, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 87, 114, 105, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 115, 84, 111, 87, 114, 105, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 87, 114, 105, 116, 101, 86, 97, 108, 117, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 111, 100, 101, 115, 84, 111, 87, 114, 105, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 115, 101, 114, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 112, 108, 97, 99, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 112, 100, 97, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 101, 114, 102, 111, 114, 109, 85, 112, 100, 97, 116, 101, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 73, 110, 115, 101, 114, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 112, 108, 97, 99, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 112, 100, 97, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 109, 111, 118, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 112, 100, 97, 116, 101, 68, 97, 116, 97, 68, 101, 116, 97, 105, 108, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 101, 114, 102, 111, 114, 109, 73, 110, 115, 101, 114, 116, 82, 101, 112, 108, 97, 99, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 80, 101, 114, 102, 111, 114, 109, 85, 112, 100, 97, 116, 101, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 112, 100, 97, 116, 101, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 112, 100, 97, 116, 101, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 97, 116, 97, 86, 97, 108, 117, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 112, 100, 97, 116, 101, 86, 97, 108, 117, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 112, 100, 97, 116, 101, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 97, 116, 97, 68, 101, 116, 97, 105, 108, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 101, 114, 102, 111, 114, 109, 73, 110, 115, 101, 114, 116, 82, 101, 112, 108, 97, 99, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 80, 101, 114, 102, 111, 114, 109, 85, 112, 100, 97, 116, 101, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 85, 112, 100, 97, 116, 101, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 112, 100, 97, 116, 101, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 97, 116, 97, 86, 97, 108, 117, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 85, 112, 100, 97, 116, 101, 86, 97, 108, 117, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 85, 112, 100, 97, 116, 101, 69, 118, 101, 110, 116, 68, 101, 116, 97, 105, 108, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 101, 114, 102, 111, 114, 109, 73, 110, 115, 101, 114, 116, 82, 101, 112, 108, 97, 99, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 80, 101, 114, 102, 111, 114, 109, 85, 112, 100, 97, 116, 101, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 108, 116, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 118, 101, 110, 116, 70, 105, 108, 116, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 118, 101, 110, 116, 68, 97, 116, 97, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 68, 97, 116, 97, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 69, 118, 101, 110, 116, 70, 105, 101, 108, 100, 76, 105, 115, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 118, 101, 110, 116, 68, 97, 116, 97, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 82, 97, 119, 77, 111, 100, 105, 102, 105, 101, 100, 68, 101, 116, 97, 105, 108, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 115, 68, 101, 108, 101, 116, 101, 77, 111, 100, 105, 102, 105, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 114, 116, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 65, 116, 84, 105, 109, 101, 68, 101, 116, 97, 105, 108, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 113, 84, 105, 109, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 84, 105, 109, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 113, 84, 105, 109, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 69, 118, 101, 110, 116, 68, 101, 116, 97, 105, 108, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 83, 111, 117, 114, 99, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 118, 101, 110, 116, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 118, 101, 110, 116, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 79, 112, 101, 114, 97, 116, 105, 111, 110, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 79, 112, 101, 114, 97, 116, 105, 111, 110, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 79, 112, 101, 114, 97, 116, 105, 111, 110, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 68, 101, 116, 97, 105, 108, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 82, 101, 115, 117, 108, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 97, 108, 108, 77, 101, 116, 104, 111, 100, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 79, 98, 106, 101, 99, 116, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 116, 104, 111, 100, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 97, 108, 108, 77, 101, 116, 104, 111, 100, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 79, 117, 116, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 79, 117, 116, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 79, 117, 116, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 97, 108, 108, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 77, 101, 116, 104, 111, 100, 115, 84, 111, 67, 97, 108, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 116, 104, 111, 100, 115, 84, 111, 67, 97, 108, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 67, 97, 108, 108, 77, 101, 116, 104, 111, 100, 82, 101, 113, 117, 101, 115, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 77, 101, 116, 104, 111, 100, 115, 84, 111, 67, 97, 108, 108, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 97, 108, 108, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 67, 97, 108, 108, 77, 101, 116, 104, 111, 100, 82, 101, 115, 117, 108, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 77, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 97, 98, 108, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 97, 109, 112, 108, 105, 110, 103, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 112, 111, 114, 116, 105, 110, 103, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 67, 104, 97, 110, 103, 101, 84, 114, 105, 103, 103, 101, 114, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 86, 97, 108, 117, 101, 84, 105, 109, 101, 115, 116, 97, 109, 112, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 97, 100, 98, 97, 110, 100, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 98, 115, 111, 108, 117, 116, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 80, 101, 114, 99, 101, 110, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 70, 105, 108, 116, 101, 114, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 67, 104, 97, 110, 103, 101, 70, 105, 108, 116, 101, 114, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 70, 105, 108, 116, 101, 114, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 105, 103, 103, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 68, 97, 116, 97, 67, 104, 97, 110, 103, 101, 84, 114, 105, 103, 103, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 97, 100, 98, 97, 110, 100, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 97, 100, 98, 97, 110, 100, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 70, 105, 108, 116, 101, 114, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 70, 105, 108, 116, 101, 114, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 105, 109, 112, 108, 101, 65, 116, 116, 114, 105, 98, 117, 116, 101, 79, 112, 101, 114, 97, 110, 100, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 67, 111, 110, 116, 101, 110, 116, 70, 105, 108, 116, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 103, 103, 114, 101, 103, 97, 116, 101, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 83, 101, 114, 118, 101, 114, 67, 97, 112, 97, 98, 105, 108, 105, 116, 105, 101, 115, 68, 101, 102, 97, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 101, 97, 116, 85, 110, 99, 101, 114, 116, 97, 105, 110, 65, 115, 66, 97, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 101, 114, 99, 101, 110, 116, 68, 97, 116, 97, 66, 97, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 101, 114, 99, 101, 110, 116, 68, 97, 116, 97, 71, 111, 111, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 83, 108, 111, 112, 101, 100, 69, 120, 116, 114, 97, 112, 111, 108, 97, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 103, 103, 114, 101, 103, 97, 116, 101, 70, 105, 108, 116, 101, 114, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 70, 105, 108, 116, 101, 114, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 114, 116, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 103, 103, 114, 101, 103, 97, 116, 101, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 114, 111, 99, 101, 115, 115, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 103, 103, 114, 101, 103, 97, 116, 101, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 103, 103, 114, 101, 103, 97, 116, 101, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 70, 105, 108, 116, 101, 114, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 70, 105, 108, 116, 101, 114, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 70, 105, 108, 116, 101, 114, 82, 101, 115, 117, 108, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 101, 108, 101, 99, 116, 67, 108, 97, 117, 115, 101, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 104, 101, 114, 101, 67, 108, 97, 117, 115, 101, 82, 101, 115, 117, 108, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 67, 111, 110, 116, 101, 110, 116, 70, 105, 108, 116, 101, 114, 82, 101, 115, 117, 108, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 103, 103, 114, 101, 103, 97, 116, 101, 70, 105, 108, 116, 101, 114, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 70, 105, 108, 116, 101, 114, 82, 101, 115, 117, 108, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 83, 116, 97, 114, 116, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 80, 114, 111, 99, 101, 115, 115, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 65, 103, 103, 114, 101, 103, 97, 116, 101, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 103, 103, 114, 101, 103, 97, 116, 101, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 72, 97, 110, 100, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 97, 109, 112, 108, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 108, 116, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 117, 101, 83, 105, 122, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 99, 97, 114, 100, 79, 108, 100, 101, 115, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 67, 114, 101, 97, 116, 101, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 116, 101, 109, 84, 111, 77, 111, 110, 105, 116, 111, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 97, 100, 86, 97, 108, 117, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 77, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 77, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 67, 114, 101, 97, 116, 101, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 83, 97, 109, 112, 108, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 81, 117, 101, 117, 101, 83, 105, 122, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 108, 116, 101, 114, 82, 101, 115, 117, 108, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 114, 101, 97, 116, 101, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 115, 116, 97, 109, 112, 115, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 84, 105, 109, 101, 115, 116, 97, 109, 112, 115, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 73, 116, 101, 109, 115, 84, 111, 67, 114, 101, 97, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 116, 101, 109, 115, 84, 111, 67, 114, 101, 97, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 67, 114, 101, 97, 116, 101, 82, 101, 113, 117, 101, 115, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 73, 116, 101, 109, 115, 84, 111, 67, 114, 101, 97, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 114, 101, 97, 116, 101, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 67, 114, 101, 97, 116, 101, 82, 101, 115, 117, 108, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 77, 111, 100, 105, 102, 121, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 77, 111, 100, 105, 102, 121, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 83, 97, 109, 112, 108, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 81, 117, 101, 117, 101, 83, 105, 122, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 70, 105, 108, 116, 101, 114, 82, 101, 115, 117, 108, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 100, 105, 102, 121, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 105, 109, 101, 115, 116, 97, 109, 112, 115, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 84, 105, 109, 101, 115, 116, 97, 109, 112, 115, 84, 111, 82, 101, 116, 117, 114, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 73, 116, 101, 109, 115, 84, 111, 77, 111, 100, 105, 102, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 116, 101, 109, 115, 84, 111, 77, 111, 100, 105, 102, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 77, 111, 100, 105, 102, 121, 82, 101, 113, 117, 101, 115, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 73, 116, 101, 109, 115, 84, 111, 77, 111, 100, 105, 102, 121, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 100, 105, 102, 121, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 77, 111, 100, 105, 102, 121, 82, 101, 115, 117, 108, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 116, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 77, 111, 100, 101, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 77, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 77, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 116, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 77, 111, 100, 101, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 116, 84, 114, 105, 103, 103, 101, 114, 105, 110, 103, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 105, 103, 103, 101, 114, 105, 110, 103, 73, 116, 101, 109, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 105, 110, 107, 115, 84, 111, 65, 100, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 105, 110, 107, 115, 84, 111, 65, 100, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 105, 110, 107, 115, 84, 111, 65, 100, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 105, 110, 107, 115, 84, 111, 82, 101, 109, 111, 118, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 105, 110, 107, 115, 84, 111, 82, 101, 109, 111, 118, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 105, 110, 107, 115, 84, 111, 82, 101, 109, 111, 118, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 116, 84, 114, 105, 103, 103, 101, 114, 105, 110, 103, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 100, 100, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 100, 100, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 100, 100, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 100, 100, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 109, 111, 118, 101, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 109, 111, 118, 101, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 109, 111, 118, 101, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 109, 111, 118, 101, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 109, 111, 118, 101, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 109, 111, 118, 101, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 114, 101, 97, 116, 101, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 76, 105, 102, 101, 116, 105, 109, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 77, 97, 120, 75, 101, 101, 112, 65, 108, 105, 118, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 115, 80, 101, 114, 80, 117, 98, 108, 105, 115, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 69, 110, 97, 98, 108, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 114, 105, 111, 114, 105, 116, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 114, 101, 97, 116, 101, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 76, 105, 102, 101, 116, 105, 109, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 77, 97, 120, 75, 101, 101, 112, 65, 108, 105, 118, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 100, 105, 102, 121, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 76, 105, 102, 101, 116, 105, 109, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 101, 100, 77, 97, 120, 75, 101, 101, 112, 65, 108, 105, 118, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 115, 80, 101, 114, 80, 117, 98, 108, 105, 115, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 114, 105, 111, 114, 105, 116, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 100, 105, 102, 121, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 76, 105, 102, 101, 116, 105, 109, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 118, 105, 115, 101, 100, 77, 97, 120, 75, 101, 101, 112, 65, 108, 105, 118, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 116, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 77, 111, 100, 101, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 69, 110, 97, 98, 108, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 116, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 77, 111, 100, 101, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 77, 101, 115, 115, 97, 103, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 113, 117, 101, 110, 99, 101, 78, 117, 109, 98, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 68, 97, 116, 97, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 68, 97, 116, 97, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 68, 97, 116, 97, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 68, 97, 116, 97, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 67, 104, 97, 110, 103, 101, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 68, 97, 116, 97, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 72, 97, 110, 100, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 97, 116, 97, 86, 97, 108, 117, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 76, 105, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 68, 97, 116, 97, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 118, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 118, 101, 110, 116, 70, 105, 101, 108, 100, 76, 105, 115, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 118, 101, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 70, 105, 101, 108, 100, 76, 105, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 72, 97, 110, 100, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 118, 101, 110, 116, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 118, 101, 110, 116, 70, 105, 101, 108, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 69, 118, 101, 110, 116, 70, 105, 101, 108, 100, 76, 105, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 118, 101, 110, 116, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 70, 105, 101, 108, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 118, 101, 110, 116, 70, 105, 101, 108, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 104, 97, 110, 103, 101, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 116, 110, 115, 58, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 68, 97, 116, 97, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 65, 99, 107, 110, 111, 119, 108, 101, 100, 103, 101, 109, 101, 110, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 113, 117, 101, 110, 99, 101, 78, 117, 109, 98, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 65, 99, 107, 110, 111, 119, 108, 101, 100, 103, 101, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 65, 99, 107, 110, 111, 119, 108, 101, 100, 103, 101, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 65, 99, 107, 110, 111, 119, 108, 101, 100, 103, 101, 109, 101, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 65, 99, 107, 110, 111, 119, 108, 101, 100, 103, 101, 109, 101, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 118, 97, 105, 108, 97, 98, 108, 101, 83, 101, 113, 117, 101, 110, 99, 101, 78, 117, 109, 98, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 118, 97, 105, 108, 97, 98, 108, 101, 83, 101, 113, 117, 101, 110, 99, 101, 78, 117, 109, 98, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 118, 97, 105, 108, 97, 98, 108, 101, 83, 101, 113, 117, 101, 110, 99, 101, 78, 117, 109, 98, 101, 114, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 114, 101, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 77, 101, 115, 115, 97, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 77, 101, 115, 115, 97, 103, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 112, 117, 98, 108, 105, 115, 104, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 116, 114, 97, 110, 115, 109, 105, 116, 83, 101, 113, 117, 101, 110, 99, 101, 78, 117, 109, 98, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 112, 117, 98, 108, 105, 115, 104, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 77, 101, 115, 115, 97, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 77, 101, 115, 115, 97, 103, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 102, 101, 114, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 118, 97, 105, 108, 97, 98, 108, 101, 83, 101, 113, 117, 101, 110, 99, 101, 78, 117, 109, 98, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 118, 97, 105, 108, 97, 98, 108, 101, 83, 101, 113, 117, 101, 110, 99, 101, 78, 117, 109, 98, 101, 114, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 118, 97, 105, 108, 97, 98, 108, 101, 83, 101, 113, 117, 101, 110, 99, 101, 78, 117, 109, 98, 101, 114, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 102, 101, 114, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 110, 100, 73, 110, 105, 116, 105, 97, 108, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 102, 101, 114, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 84, 114, 97, 110, 115, 102, 101, 114, 82, 101, 115, 117, 108, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 82, 101, 113, 117, 101, 115, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 113, 117, 101, 115, 116, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 82, 101, 115, 112, 111, 110, 115, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 101, 115, 112, 111, 110, 115, 101, 72, 101, 97, 100, 101, 114, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 115, 117, 108, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 82, 101, 115, 117, 108, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 66, 117, 105, 108, 100, 73, 110, 102, 111, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 114, 111, 100, 117, 99, 116, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 110, 117, 102, 97, 99, 116, 117, 114, 101, 114, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 114, 111, 100, 117, 99, 116, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 111, 102, 116, 119, 97, 114, 101, 86, 101, 114, 115, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 117, 105, 108, 100, 78, 117, 109, 98, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 117, 105, 108, 100, 68, 97, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 100, 117, 110, 100, 97, 110, 99, 121, 83, 117, 112, 112, 111, 114, 116, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 110, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 108, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 87, 97, 114, 109, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 72, 111, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 112, 97, 114, 101, 110, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 72, 111, 116, 65, 110, 100, 77, 105, 114, 114, 111, 114, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 53, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 83, 116, 97, 116, 101, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 117, 110, 110, 105, 110, 103, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 70, 97, 105, 108, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 117, 115, 112, 101, 110, 100, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 83, 104, 117, 116, 100, 111, 119, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 84, 101, 115, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 53, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 109, 109, 117, 110, 105, 99, 97, 116, 105, 111, 110, 70, 97, 117, 108, 116, 34, 32, 86, 97, 108, 117, 101, 61, 34, 54, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 110, 107, 110, 111, 119, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 55, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 100, 117, 110, 100, 97, 110, 116, 83, 101, 114, 118, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 105, 99, 101, 76, 101, 118, 101, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 83, 116, 97, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 101, 114, 83, 116, 97, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 112, 111, 105, 110, 116, 85, 114, 108, 76, 105, 115, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 69, 110, 100, 112, 111, 105, 110, 116, 85, 114, 108, 76, 105, 115, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 112, 111, 105, 110, 116, 85, 114, 108, 76, 105, 115, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 69, 110, 100, 112, 111, 105, 110, 116, 85, 114, 108, 76, 105, 115, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 71, 114, 111, 117, 112, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 78, 101, 116, 119, 111, 114, 107, 80, 97, 116, 104, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 101, 116, 119, 111, 114, 107, 80, 97, 116, 104, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 110, 100, 112, 111, 105, 110, 116, 85, 114, 108, 76, 105, 115, 116, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 78, 101, 116, 119, 111, 114, 107, 80, 97, 116, 104, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 97, 109, 112, 108, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 97, 109, 112, 108, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 97, 98, 108, 101, 100, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 83, 117, 109, 109, 97, 114, 121, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 86, 105, 101, 119, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 116, 83, 101, 115, 115, 105, 111, 110, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 117, 109, 117, 108, 97, 116, 101, 100, 83, 101, 115, 115, 105, 111, 110, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 82, 101, 106, 101, 99, 116, 101, 100, 83, 101, 115, 115, 105, 111, 110, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 106, 101, 99, 116, 101, 100, 83, 101, 115, 115, 105, 111, 110, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 84, 105, 109, 101, 111, 117, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 65, 98, 111, 114, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 116, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 117, 109, 117, 108, 97, 116, 101, 100, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 82, 101, 106, 101, 99, 116, 101, 100, 82, 101, 113, 117, 101, 115, 116, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 106, 101, 99, 116, 101, 100, 82, 101, 113, 117, 101, 115, 116, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 83, 116, 97, 116, 117, 115, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 114, 116, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 116, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 101, 114, 83, 116, 97, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 117, 105, 108, 100, 73, 110, 102, 111, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 66, 117, 105, 108, 100, 73, 110, 102, 111, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 111, 110, 100, 115, 84, 105, 108, 108, 83, 104, 117, 116, 100, 111, 119, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 104, 117, 116, 100, 111, 119, 110, 82, 101, 97, 115, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 101, 114, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 100, 112, 111, 105, 110, 116, 85, 114, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 111, 99, 97, 108, 101, 73, 100, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 99, 116, 117, 97, 108, 83, 101, 115, 115, 105, 111, 110, 84, 105, 109, 101, 111, 117, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 82, 101, 115, 112, 111, 110, 115, 101, 77, 101, 115, 115, 97, 103, 101, 83, 105, 122, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 76, 97, 115, 116, 67, 111, 110, 116, 97, 99, 116, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 116, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 116, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 116, 80, 117, 98, 108, 105, 115, 104, 82, 101, 113, 117, 101, 115, 116, 115, 73, 110, 81, 117, 101, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 111, 116, 97, 108, 82, 101, 113, 117, 101, 115, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 110, 97, 117, 116, 104, 111, 114, 105, 122, 101, 100, 82, 101, 113, 117, 101, 115, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 100, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 82, 101, 97, 100, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 87, 114, 105, 116, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 72, 105, 115, 116, 111, 114, 121, 85, 112, 100, 97, 116, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 97, 108, 108, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 114, 101, 97, 116, 101, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 100, 105, 102, 121, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 116, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 77, 111, 100, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 116, 84, 114, 105, 103, 103, 101, 114, 105, 110, 103, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 114, 101, 97, 116, 101, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 100, 105, 102, 121, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 116, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 77, 111, 100, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 112, 117, 98, 108, 105, 115, 104, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 102, 101, 114, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 78, 111, 100, 101, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 100, 100, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 78, 111, 100, 101, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 108, 101, 116, 101, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 66, 114, 111, 119, 115, 101, 78, 101, 120, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 108, 97, 116, 101, 66, 114, 111, 119, 115, 101, 80, 97, 116, 104, 115, 84, 111, 78, 111, 100, 101, 73, 100, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 114, 121, 70, 105, 114, 115, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 81, 117, 101, 114, 121, 78, 101, 120, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 103, 105, 115, 116, 101, 114, 78, 111, 100, 101, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 110, 114, 101, 103, 105, 115, 116, 101, 114, 78, 111, 100, 101, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 83, 101, 99, 117, 114, 105, 116, 121, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 85, 115, 101, 114, 73, 100, 79, 102, 83, 101, 115, 115, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 67, 108, 105, 101, 110, 116, 85, 115, 101, 114, 73, 100, 72, 105, 115, 116, 111, 114, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 85, 115, 101, 114, 73, 100, 72, 105, 115, 116, 111, 114, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 67, 108, 105, 101, 110, 116, 85, 115, 101, 114, 73, 100, 72, 105, 115, 116, 111, 114, 121, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 77, 101, 99, 104, 97, 110, 105, 115, 109, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 99, 111, 100, 105, 110, 103, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 112, 111, 114, 116, 80, 114, 111, 116, 111, 99, 111, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 77, 101, 115, 115, 97, 103, 101, 83, 101, 99, 117, 114, 105, 116, 121, 77, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 99, 117, 114, 105, 116, 121, 80, 111, 108, 105, 99, 121, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 108, 105, 101, 110, 116, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 114, 118, 105, 99, 101, 67, 111, 117, 110, 116, 101, 114, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 111, 116, 97, 108, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 114, 114, 111, 114, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 82, 101, 115, 117, 108, 116, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 83, 116, 97, 116, 117, 115, 67, 111, 100, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 73, 110, 102, 111, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 101, 115, 115, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 83, 117, 98, 115, 99, 114, 105, 112, 116, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 114, 105, 111, 114, 105, 116, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 73, 110, 116, 101, 114, 118, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 75, 101, 101, 112, 65, 108, 105, 118, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 76, 105, 102, 101, 116, 105, 109, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 97, 120, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 115, 80, 101, 114, 80, 117, 98, 108, 105, 115, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 105, 110, 103, 69, 110, 97, 98, 108, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 111, 111, 108, 101, 97, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 100, 105, 102, 121, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 97, 98, 108, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 97, 98, 108, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 112, 117, 98, 108, 105, 115, 104, 82, 101, 113, 117, 101, 115, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 112, 117, 98, 108, 105, 115, 104, 77, 101, 115, 115, 97, 103, 101, 82, 101, 113, 117, 101, 115, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 112, 117, 98, 108, 105, 115, 104, 77, 101, 115, 115, 97, 103, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 102, 101, 114, 82, 101, 113, 117, 101, 115, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 102, 101, 114, 114, 101, 100, 84, 111, 65, 108, 116, 67, 108, 105, 101, 110, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 114, 97, 110, 115, 102, 101, 114, 114, 101, 100, 84, 111, 83, 97, 109, 101, 67, 108, 105, 101, 110, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 80, 117, 98, 108, 105, 115, 104, 82, 101, 113, 117, 101, 115, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 67, 104, 97, 110, 103, 101, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 116, 105, 102, 105, 99, 97, 116, 105, 111, 110, 115, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 116, 101, 80, 117, 98, 108, 105, 115, 104, 82, 101, 113, 117, 101, 115, 116, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 116, 75, 101, 101, 112, 65, 108, 105, 118, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 117, 114, 114, 101, 110, 116, 76, 105, 102, 101, 116, 105, 109, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 110, 97, 99, 107, 110, 111, 119, 108, 101, 100, 103, 101, 100, 77, 101, 115, 115, 97, 103, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 99, 97, 114, 100, 101, 100, 77, 101, 115, 115, 97, 103, 101, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 97, 98, 108, 101, 100, 77, 111, 110, 105, 116, 111, 114, 101, 100, 73, 116, 101, 109, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 111, 110, 105, 116, 111, 114, 105, 110, 103, 81, 117, 101, 117, 101, 79, 118, 101, 114, 102, 108, 111, 119, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 101, 120, 116, 83, 101, 113, 117, 101, 110, 99, 101, 78, 117, 109, 98, 101, 114, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 118, 101, 110, 116, 81, 117, 101, 117, 101, 79, 118, 101, 114, 70, 108, 111, 119, 67, 111, 117, 110, 116, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 85, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 100, 101, 108, 67, 104, 97, 110, 103, 101, 83, 116, 114, 117, 99, 116, 117, 114, 101, 86, 101, 114, 98, 77, 97, 115, 107, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 65, 100, 100, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 78, 111, 100, 101, 68, 101, 108, 101, 116, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 65, 100, 100, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 82, 101, 102, 101, 114, 101, 110, 99, 101, 68, 101, 108, 101, 116, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 56, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 68, 97, 116, 97, 84, 121, 112, 101, 67, 104, 97, 110, 103, 101, 100, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 54, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 77, 111, 100, 101, 108, 67, 104, 97, 110, 103, 101, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 102, 102, 101, 99, 116, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 102, 102, 101, 99, 116, 101, 100, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 101, 114, 98, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 66, 121, 116, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 83, 101, 109, 97, 110, 116, 105, 99, 67, 104, 97, 110, 103, 101, 83, 116, 114, 117, 99, 116, 117, 114, 101, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 102, 102, 101, 99, 116, 101, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 102, 102, 101, 99, 116, 101, 100, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 82, 97, 110, 103, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 111, 119, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 72, 105, 103, 104, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 85, 73, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 97, 109, 101, 115, 112, 97, 99, 101, 85, 114, 105, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 110, 105, 116, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 105, 115, 112, 108, 97, 121, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 68, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 120, 105, 115, 83, 99, 97, 108, 101, 69, 110, 117, 109, 101, 114, 97, 116, 105, 111, 110, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 76, 105, 110, 101, 97, 114, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 76, 111, 103, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 76, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 67, 111, 109, 112, 108, 101, 120, 78, 117, 109, 98, 101, 114, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 70, 108, 111, 97, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 109, 97, 103, 105, 110, 97, 114, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 70, 108, 111, 97, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 68, 111, 117, 98, 108, 101, 67, 111, 109, 112, 108, 101, 120, 78, 117, 109, 98, 101, 114, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 82, 101, 97, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 109, 97, 103, 105, 110, 97, 114, 121, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 120, 105, 115, 73, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 110, 103, 105, 110, 101, 101, 114, 105, 110, 103, 85, 110, 105, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 69, 85, 73, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 69, 85, 82, 97, 110, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 82, 97, 110, 103, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 84, 105, 116, 108, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 76, 111, 99, 97, 108, 105, 122, 101, 100, 84, 101, 120, 116, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 120, 105, 115, 83, 99, 97, 108, 101, 84, 121, 112, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 120, 105, 115, 83, 99, 97, 108, 101, 69, 110, 117, 109, 101, 114, 97, 116, 105, 111, 110, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 65, 120, 105, 115, 83, 116, 101, 112, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 120, 105, 115, 83, 116, 101, 112, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 65, 120, 105, 115, 83, 116, 101, 112, 115, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 88, 86, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 88, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 111, 117, 98, 108, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 86, 97, 108, 117, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 70, 108, 111, 97, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 114, 111, 103, 114, 97, 109, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 114, 101, 97, 116, 101, 83, 101, 115, 115, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 114, 101, 97, 116, 101, 67, 108, 105, 101, 110, 116, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 118, 111, 99, 97, 116, 105, 111, 110, 67, 114, 101, 97, 116, 105, 111, 110, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 84, 114, 97, 110, 115, 105, 116, 105, 111, 110, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 67, 97, 108, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 83, 101, 115, 115, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 114, 103, 117, 109, 101, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 79, 117, 116, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 79, 117, 116, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 114, 103, 117, 109, 101, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 79, 117, 116, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 67, 97, 108, 108, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 82, 101, 116, 117, 114, 110, 83, 116, 97, 116, 117, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 116, 97, 116, 117, 115, 82, 101, 115, 117, 108, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 80, 114, 111, 103, 114, 97, 109, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99, 50, 68, 97, 116, 97, 84, 121, 112, 101, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 114, 101, 97, 116, 101, 83, 101, 115, 115, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 67, 114, 101, 97, 116, 101, 67, 108, 105, 101, 110, 116, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 73, 110, 118, 111, 99, 97, 116, 105, 111, 110, 67, 114, 101, 97, 116, 105, 111, 110, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 84, 114, 97, 110, 115, 105, 116, 105, 111, 110, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 67, 97, 108, 108, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 83, 101, 115, 115, 105, 111, 110, 73, 100, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 78, 111, 100, 101, 73, 100, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 114, 103, 117, 109, 101, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 73, 110, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 79, 117, 116, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 79, 117, 116, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 65, 114, 103, 117, 109, 101, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 79, 117, 116, 112, 117, 116, 65, 114, 103, 117, 109, 101, 110, 116, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 73, 110, 112, 117, 116, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 73, 110, 112, 117, 116, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 73, 110, 112, 117, 116, 86, 97, 108, 117, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 78, 111, 79, 102, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 79, 117, 116, 112, 117, 116, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 73, 110, 116, 51, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 79, 117, 116, 112, 117, 116, 86, 97, 108, 117, 101, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 117, 97, 58, 86, 97, 114, 105, 97, 110, 116, 34, 32, 76, 101, 110, 103, 116, 104, 70, 105, 101, 108, 100, 61, 34, 78, 111, 79, 102, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 79, 117, 116, 112, 117, 116, 86, 97, 108, 117, 101, 115, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 67, 97, 108, 108, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 76, 97, 115, 116, 77, 101, 116, 104, 111, 100, 82, 101, 116, 117, 114, 110, 83, 116, 97, 116, 117, 115, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 116, 110, 115, 58, 83, 116, 97, 116, 117, 115, 82, 101, 115, 117, 108, 116, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 34, 32, 66, 97, 115, 101, 84, 121, 112, 101, 61, 34, 117, 97, 58, 69, 120, 116, 101, 110, 115, 105, 111, 110, 79, 98, 106, 101, 99, 116, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 77, 101, 115, 115, 97, 103, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 85, 115, 101, 114, 78, 97, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 83, 116, 114, 105, 110, 103, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 70, 105, 101, 108, 100, 32, 78, 97, 109, 101, 61, 34, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 84, 105, 109, 101, 34, 32, 84, 121, 112, 101, 78, 97, 109, 101, 61, 34, 111, 112, 99, 58, 68, 97, 116, 101, 84, 105, 109, 101, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 83, 116, 114, 117, 99, 116, 117, 114, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 32, 78, 97, 109, 101, 61, 34, 69, 120, 99, 101, 112, 116, 105, 111, 110, 68, 101, 118, 105, 97, 116, 105, 111, 110, 70, 111, 114, 109, 97, 116, 34, 32, 76, 101, 110, 103, 116, 104, 73, 110, 66, 105, 116, 115, 61, 34, 51, 50, 34, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 65, 98, 115, 111, 108, 117, 116, 101, 86, 97, 108, 117, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 48, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 80, 101, 114, 99, 101, 110, 116, 79, 102, 86, 97, 108, 117, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 49, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 80, 101, 114, 99, 101, 110, 116, 79, 102, 82, 97, 110, 103, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 50, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 80, 101, 114, 99, 101, 110, 116, 79, 102, 69, 85, 82, 97, 110, 103, 101, 34, 32, 86, 97, 108, 117, 101, 61, 34, 51, 34, 32, 47, 62, 13, 10, 32, 32, 32, 32, 60, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 86, 97, 108, 117, 101, 32, 78, 97, 109, 101, 61, 34, 85, 110, 107, 110, 111, 119, 110, 34, 32, 86, 97, 108, 117, 101, 61, 34, 52, 34, 32, 47, 62, 13, 10, 32, 32, 60, 47, 111, 112, 99, 58, 69, 110, 117, 109, 101, 114, 97, 116, 101, 100, 84, 121, 112, 101, 62, 13, 10, 13, 10, 60, 47, 111, 112, 99, 58, 84, 121, 112, 101, 68, 105, 99, 116, 105, 111, 110, 97, 114, 121, 62};
92945
92946
92947
92948static UA_StatusCode function_namespace0_generated_814_begin(UA_Server *server, UA_UInt16* ns) {
92949UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92950UA_VariableAttributes attr = UA_VariableAttributes_default;
92951attr.minimumSamplingInterval = 0.000000;
92952attr.userAccessLevel = 1;
92953attr.accessLevel = 1;
92954/* Value rank inherited */
92955attr.valueRank = -2;
92956attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15LU);
92957UA_ByteString *variablenode_ns_0_i_7617_variant_DataContents = UA_ByteString_new();
92958if (!variablenode_ns_0_i_7617_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY;
92959UA_ByteString_init(p: variablenode_ns_0_i_7617_variant_DataContents);
92960variablenode_ns_0_i_7617_variant_DataContents->length = 177218;
92961variablenode_ns_0_i_7617_variant_DataContents->data = (UA_Byte *)(void*)(uintptr_t)variablenode_ns_0_i_7617_variant_DataContents_byteArray;
92962UA_Variant_setScalar(v: &attr.value, p: variablenode_ns_0_i_7617_variant_DataContents, type: &UA_TYPES[UA_TYPES_BYTESTRING]);
92963attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Opc.Ua");
92964retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
92965requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7617LU),
92966parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 93LU),
92967referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
92968browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Opc.Ua"),
92969typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 72LU),
92970attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
92971if (retVal != UA_STATUSCODE_GOOD) return retVal;
92972variablenode_ns_0_i_7617_variant_DataContents->data = NULL;
92973variablenode_ns_0_i_7617_variant_DataContents->length = 0;
92974UA_ByteString_delete(p: variablenode_ns_0_i_7617_variant_DataContents);
92975return retVal;
92976}
92977
92978static UA_StatusCode function_namespace0_generated_814_finish(UA_Server *server, UA_UInt16* ns) {
92979return UA_Server_addNode_finish(server,
92980nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7617LU)
92981);
92982}
92983
92984/* NamespaceUri - ns=0;i=107 */
92985
92986static UA_StatusCode function_namespace0_generated_815_begin(UA_Server *server, UA_UInt16* ns) {
92987UA_StatusCode retVal = UA_STATUSCODE_GOOD;
92988UA_VariableAttributes attr = UA_VariableAttributes_default;
92989attr.minimumSamplingInterval = 0.000000;
92990attr.userAccessLevel = 1;
92991attr.accessLevel = 1;
92992/* Value rank inherited */
92993attr.valueRank = -2;
92994attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
92995attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "NamespaceUri");
92996#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS
92997attr.description = UA_LOCALIZEDTEXT(locale: "", text: "A URI that uniquely identifies the dictionary.");
92998#endif
92999retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
93000requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 107LU),
93001parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 72LU),
93002referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
93003browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "NamespaceUri"),
93004typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
93005attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
93006if (retVal != UA_STATUSCODE_GOOD) return retVal;
93007retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 107LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), true);
93008if (retVal != UA_STATUSCODE_GOOD) return retVal;
93009return retVal;
93010}
93011
93012static UA_StatusCode function_namespace0_generated_815_finish(UA_Server *server, UA_UInt16* ns) {
93013return UA_Server_addNode_finish(server,
93014nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 107LU)
93015);
93016}
93017
93018/* DataTypeVersion - ns=0;i=106 */
93019
93020static UA_StatusCode function_namespace0_generated_816_begin(UA_Server *server, UA_UInt16* ns) {
93021UA_StatusCode retVal = UA_STATUSCODE_GOOD;
93022UA_VariableAttributes attr = UA_VariableAttributes_default;
93023attr.minimumSamplingInterval = 0.000000;
93024attr.userAccessLevel = 1;
93025attr.accessLevel = 1;
93026/* Value rank inherited */
93027attr.valueRank = -2;
93028attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
93029attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataTypeVersion");
93030retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
93031requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 106LU),
93032parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 72LU),
93033referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
93034browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataTypeVersion"),
93035typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
93036attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
93037if (retVal != UA_STATUSCODE_GOOD) return retVal;
93038retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 106LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), true);
93039if (retVal != UA_STATUSCODE_GOOD) return retVal;
93040return retVal;
93041}
93042
93043static UA_StatusCode function_namespace0_generated_816_finish(UA_Server *server, UA_UInt16* ns) {
93044return UA_Server_addNode_finish(server,
93045nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 106LU)
93046);
93047}
93048
93049/* DataTypeDescriptionType - ns=0;i=69 */
93050
93051static UA_StatusCode function_namespace0_generated_817_begin(UA_Server *server, UA_UInt16* ns) {
93052UA_StatusCode retVal = UA_STATUSCODE_GOOD;
93053UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default;
93054/* Value rank inherited */
93055attr.valueRank = -2;
93056attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
93057attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataTypeDescriptionType");
93058retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLETYPE,
93059requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 69LU),
93060parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 63LU),
93061referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 45LU),
93062browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataTypeDescriptionType"),
93063typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
93064attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL);
93065if (retVal != UA_STATUSCODE_GOOD) return retVal;
93066return retVal;
93067}
93068
93069static UA_StatusCode function_namespace0_generated_817_finish(UA_Server *server, UA_UInt16* ns) {
93070return UA_Server_addNode_finish(server,
93071nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 69LU)
93072);
93073}
93074
93075/* EnumValueType - ns=0;i=7656 */
93076
93077static UA_StatusCode function_namespace0_generated_818_begin(UA_Server *server, UA_UInt16* ns) {
93078UA_StatusCode retVal = UA_STATUSCODE_GOOD;
93079UA_VariableAttributes attr = UA_VariableAttributes_default;
93080attr.minimumSamplingInterval = 0.000000;
93081attr.userAccessLevel = 1;
93082attr.accessLevel = 1;
93083/* Value rank inherited */
93084attr.valueRank = -2;
93085attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
93086UA_String *variablenode_ns_0_i_7656_variant_DataContents = UA_String_new();
93087if (!variablenode_ns_0_i_7656_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY;
93088UA_String_init(p: variablenode_ns_0_i_7656_variant_DataContents);
93089*variablenode_ns_0_i_7656_variant_DataContents = UA_STRING_ALLOC("EnumValueType");
93090UA_Variant_setScalar(v: &attr.value, p: variablenode_ns_0_i_7656_variant_DataContents, type: &UA_TYPES[UA_TYPES_STRING]);
93091attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "EnumValueType");
93092retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
93093requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7656LU),
93094parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7617LU),
93095referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
93096browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "EnumValueType"),
93097typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 69LU),
93098attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
93099if (retVal != UA_STATUSCODE_GOOD) return retVal;
93100UA_String_delete(p: variablenode_ns_0_i_7656_variant_DataContents);
93101retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7656LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 39LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 8251LU), false);
93102if (retVal != UA_STATUSCODE_GOOD) return retVal;
93103return retVal;
93104}
93105
93106static UA_StatusCode function_namespace0_generated_818_finish(UA_Server *server, UA_UInt16* ns) {
93107return UA_Server_addNode_finish(server,
93108nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7656LU)
93109);
93110}
93111
93112/* Argument - ns=0;i=7650 */
93113
93114static UA_StatusCode function_namespace0_generated_819_begin(UA_Server *server, UA_UInt16* ns) {
93115UA_StatusCode retVal = UA_STATUSCODE_GOOD;
93116UA_VariableAttributes attr = UA_VariableAttributes_default;
93117attr.minimumSamplingInterval = 0.000000;
93118attr.userAccessLevel = 1;
93119attr.accessLevel = 1;
93120/* Value rank inherited */
93121attr.valueRank = -2;
93122attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
93123UA_String *variablenode_ns_0_i_7650_variant_DataContents = UA_String_new();
93124if (!variablenode_ns_0_i_7650_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY;
93125UA_String_init(p: variablenode_ns_0_i_7650_variant_DataContents);
93126*variablenode_ns_0_i_7650_variant_DataContents = UA_STRING_ALLOC("Argument");
93127UA_Variant_setScalar(v: &attr.value, p: variablenode_ns_0_i_7650_variant_DataContents, type: &UA_TYPES[UA_TYPES_STRING]);
93128attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Argument");
93129retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
93130requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7650LU),
93131parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7617LU),
93132referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 47LU),
93133browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Argument"),
93134typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 69LU),
93135attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
93136if (retVal != UA_STATUSCODE_GOOD) return retVal;
93137UA_String_delete(p: variablenode_ns_0_i_7650_variant_DataContents);
93138retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7650LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 39LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 298LU), false);
93139if (retVal != UA_STATUSCODE_GOOD) return retVal;
93140return retVal;
93141}
93142
93143static UA_StatusCode function_namespace0_generated_819_finish(UA_Server *server, UA_UInt16* ns) {
93144return UA_Server_addNode_finish(server,
93145nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 7650LU)
93146);
93147}
93148
93149/* DictionaryFragment - ns=0;i=105 */
93150
93151static UA_StatusCode function_namespace0_generated_820_begin(UA_Server *server, UA_UInt16* ns) {
93152UA_StatusCode retVal = UA_STATUSCODE_GOOD;
93153UA_VariableAttributes attr = UA_VariableAttributes_default;
93154attr.minimumSamplingInterval = 0.000000;
93155attr.userAccessLevel = 1;
93156attr.accessLevel = 1;
93157/* Value rank inherited */
93158attr.valueRank = -2;
93159attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 15LU);
93160attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DictionaryFragment");
93161retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
93162requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 105LU),
93163parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 69LU),
93164referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
93165browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DictionaryFragment"),
93166typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
93167attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
93168if (retVal != UA_STATUSCODE_GOOD) return retVal;
93169retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 105LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), true);
93170if (retVal != UA_STATUSCODE_GOOD) return retVal;
93171return retVal;
93172}
93173
93174static UA_StatusCode function_namespace0_generated_820_finish(UA_Server *server, UA_UInt16* ns) {
93175return UA_Server_addNode_finish(server,
93176nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 105LU)
93177);
93178}
93179
93180/* DataTypeVersion - ns=0;i=104 */
93181
93182static UA_StatusCode function_namespace0_generated_821_begin(UA_Server *server, UA_UInt16* ns) {
93183UA_StatusCode retVal = UA_STATUSCODE_GOOD;
93184UA_VariableAttributes attr = UA_VariableAttributes_default;
93185attr.minimumSamplingInterval = 0.000000;
93186attr.userAccessLevel = 1;
93187attr.accessLevel = 1;
93188/* Value rank inherited */
93189attr.valueRank = -2;
93190attr.dataType = UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 12LU);
93191attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "DataTypeVersion");
93192retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_VARIABLE,
93193requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 104LU),
93194parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 69LU),
93195referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 46LU),
93196browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "DataTypeVersion"),
93197typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 68LU),
93198attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL);
93199if (retVal != UA_STATUSCODE_GOOD) return retVal;
93200retVal |= UA_Server_addReference(server, sourceId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 104LU), refTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 37LU), targetId: UA_EXPANDEDNODEID_NUMERIC(nsIndex: ns[0], identifier: 80LU), true);
93201if (retVal != UA_STATUSCODE_GOOD) return retVal;
93202return retVal;
93203}
93204
93205static UA_StatusCode function_namespace0_generated_821_finish(UA_Server *server, UA_UInt16* ns) {
93206return UA_Server_addNode_finish(server,
93207nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 104LU)
93208);
93209}
93210
93211/* Default XML - ns=0;i=3063 */
93212
93213static UA_StatusCode function_namespace0_generated_822_begin(UA_Server *server, UA_UInt16* ns) {
93214UA_StatusCode retVal = UA_STATUSCODE_GOOD;
93215UA_ObjectAttributes attr = UA_ObjectAttributes_default;
93216attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Default XML");
93217retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
93218requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3063LU),
93219parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
93220referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
93221browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Default XML"),
93222typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
93223attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
93224if (retVal != UA_STATUSCODE_GOOD) return retVal;
93225return retVal;
93226}
93227
93228static UA_StatusCode function_namespace0_generated_822_finish(UA_Server *server, UA_UInt16* ns) {
93229return UA_Server_addNode_finish(server,
93230nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3063LU)
93231);
93232}
93233
93234/* Default Binary - ns=0;i=3062 */
93235
93236static UA_StatusCode function_namespace0_generated_823_begin(UA_Server *server, UA_UInt16* ns) {
93237UA_StatusCode retVal = UA_STATUSCODE_GOOD;
93238UA_ObjectAttributes attr = UA_ObjectAttributes_default;
93239attr.displayName = UA_LOCALIZEDTEXT(locale: "", text: "Default Binary");
93240retVal |= UA_Server_addNode_begin(server, nodeClass: UA_NODECLASS_OBJECT,
93241requestedNewNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3062LU),
93242parentNodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
93243referenceTypeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 0LU),
93244browseName: UA_QUALIFIEDNAME(nsIndex: ns[0], chars: "Default Binary"),
93245typeDefinition: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 58LU),
93246attr: (const UA_NodeAttributes*)&attr, attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL);
93247if (retVal != UA_STATUSCODE_GOOD) return retVal;
93248return retVal;
93249}
93250
93251static UA_StatusCode function_namespace0_generated_823_finish(UA_Server *server, UA_UInt16* ns) {
93252return UA_Server_addNode_finish(server,
93253nodeId: UA_NODEID_NUMERIC(nsIndex: ns[0], identifier: 3062LU)
93254);
93255}
93256
93257UA_StatusCode namespace0_generated(UA_Server *server) {
93258UA_StatusCode retVal = UA_STATUSCODE_GOOD;
93259/* Use namespace ids generated by the server */
93260UA_UInt16 ns[1];
93261ns[0] = UA_Server_addNamespace(server, name: "http://opcfoundation.org/UA/");
93262
93263/* Load custom datatype definitions into the server */
93264if((retVal = function_namespace0_generated_0_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93265if((retVal = function_namespace0_generated_0_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93266if((retVal = function_namespace0_generated_1_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93267if((retVal = function_namespace0_generated_1_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93268if((retVal = function_namespace0_generated_2_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93269if((retVal = function_namespace0_generated_2_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93270if((retVal = function_namespace0_generated_3_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93271if((retVal = function_namespace0_generated_3_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93272if((retVal = function_namespace0_generated_4_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93273if((retVal = function_namespace0_generated_4_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93274if((retVal = function_namespace0_generated_5_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93275if((retVal = function_namespace0_generated_5_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93276if((retVal = function_namespace0_generated_6_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93277if((retVal = function_namespace0_generated_6_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93278if((retVal = function_namespace0_generated_7_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93279if((retVal = function_namespace0_generated_7_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93280if((retVal = function_namespace0_generated_8_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93281if((retVal = function_namespace0_generated_8_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93282if((retVal = function_namespace0_generated_9_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93283if((retVal = function_namespace0_generated_9_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93284if((retVal = function_namespace0_generated_10_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93285if((retVal = function_namespace0_generated_10_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93286if((retVal = function_namespace0_generated_11_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93287if((retVal = function_namespace0_generated_12_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93288if((retVal = function_namespace0_generated_13_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93289if((retVal = function_namespace0_generated_14_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93290if((retVal = function_namespace0_generated_15_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93291if((retVal = function_namespace0_generated_16_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93292if((retVal = function_namespace0_generated_17_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93293if((retVal = function_namespace0_generated_18_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93294if((retVal = function_namespace0_generated_19_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93295if((retVal = function_namespace0_generated_20_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93296if((retVal = function_namespace0_generated_21_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93297if((retVal = function_namespace0_generated_22_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93298if((retVal = function_namespace0_generated_23_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93299if((retVal = function_namespace0_generated_24_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93300if((retVal = function_namespace0_generated_25_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93301if((retVal = function_namespace0_generated_26_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93302if((retVal = function_namespace0_generated_27_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93303if((retVal = function_namespace0_generated_28_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93304if((retVal = function_namespace0_generated_29_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93305if((retVal = function_namespace0_generated_30_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93306if((retVal = function_namespace0_generated_31_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93307if((retVal = function_namespace0_generated_32_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93308if((retVal = function_namespace0_generated_33_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93309if((retVal = function_namespace0_generated_34_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93310if((retVal = function_namespace0_generated_35_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93311if((retVal = function_namespace0_generated_36_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93312if((retVal = function_namespace0_generated_37_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93313if((retVal = function_namespace0_generated_38_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93314if((retVal = function_namespace0_generated_39_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93315if((retVal = function_namespace0_generated_40_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93316if((retVal = function_namespace0_generated_41_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93317if((retVal = function_namespace0_generated_42_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93318if((retVal = function_namespace0_generated_43_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93319if((retVal = function_namespace0_generated_44_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93320if((retVal = function_namespace0_generated_45_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93321if((retVal = function_namespace0_generated_46_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93322if((retVal = function_namespace0_generated_47_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93323if((retVal = function_namespace0_generated_48_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93324if((retVal = function_namespace0_generated_49_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93325if((retVal = function_namespace0_generated_50_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93326if((retVal = function_namespace0_generated_51_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93327if((retVal = function_namespace0_generated_52_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93328if((retVal = function_namespace0_generated_53_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93329if((retVal = function_namespace0_generated_54_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93330if((retVal = function_namespace0_generated_55_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93331if((retVal = function_namespace0_generated_56_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93332if((retVal = function_namespace0_generated_57_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93333if((retVal = function_namespace0_generated_58_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93334if((retVal = function_namespace0_generated_59_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93335if((retVal = function_namespace0_generated_60_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93336if((retVal = function_namespace0_generated_61_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93337if((retVal = function_namespace0_generated_62_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93338if((retVal = function_namespace0_generated_63_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93339if((retVal = function_namespace0_generated_64_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93340if((retVal = function_namespace0_generated_65_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93341if((retVal = function_namespace0_generated_66_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93342if((retVal = function_namespace0_generated_67_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93343if((retVal = function_namespace0_generated_68_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93344if((retVal = function_namespace0_generated_69_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93345if((retVal = function_namespace0_generated_70_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93346if((retVal = function_namespace0_generated_71_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93347if((retVal = function_namespace0_generated_72_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93348if((retVal = function_namespace0_generated_73_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93349if((retVal = function_namespace0_generated_74_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93350if((retVal = function_namespace0_generated_75_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93351if((retVal = function_namespace0_generated_76_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93352if((retVal = function_namespace0_generated_77_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93353if((retVal = function_namespace0_generated_78_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93354if((retVal = function_namespace0_generated_79_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93355if((retVal = function_namespace0_generated_80_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93356if((retVal = function_namespace0_generated_81_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93357if((retVal = function_namespace0_generated_82_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93358if((retVal = function_namespace0_generated_83_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93359if((retVal = function_namespace0_generated_84_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93360if((retVal = function_namespace0_generated_85_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93361if((retVal = function_namespace0_generated_86_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93362if((retVal = function_namespace0_generated_87_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93363if((retVal = function_namespace0_generated_88_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93364if((retVal = function_namespace0_generated_89_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93365if((retVal = function_namespace0_generated_90_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93366if((retVal = function_namespace0_generated_91_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93367if((retVal = function_namespace0_generated_92_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93368if((retVal = function_namespace0_generated_93_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93369if((retVal = function_namespace0_generated_94_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93370if((retVal = function_namespace0_generated_95_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93371if((retVal = function_namespace0_generated_96_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93372if((retVal = function_namespace0_generated_97_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93373if((retVal = function_namespace0_generated_98_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93374if((retVal = function_namespace0_generated_99_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93375if((retVal = function_namespace0_generated_100_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93376if((retVal = function_namespace0_generated_101_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93377if((retVal = function_namespace0_generated_102_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93378if((retVal = function_namespace0_generated_103_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93379if((retVal = function_namespace0_generated_104_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93380if((retVal = function_namespace0_generated_105_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93381if((retVal = function_namespace0_generated_106_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93382if((retVal = function_namespace0_generated_107_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93383if((retVal = function_namespace0_generated_108_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93384if((retVal = function_namespace0_generated_109_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93385if((retVal = function_namespace0_generated_110_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93386if((retVal = function_namespace0_generated_111_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93387if((retVal = function_namespace0_generated_112_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93388if((retVal = function_namespace0_generated_113_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93389if((retVal = function_namespace0_generated_114_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93390if((retVal = function_namespace0_generated_115_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93391if((retVal = function_namespace0_generated_116_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93392if((retVal = function_namespace0_generated_117_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93393if((retVal = function_namespace0_generated_118_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93394if((retVal = function_namespace0_generated_119_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93395if((retVal = function_namespace0_generated_120_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93396if((retVal = function_namespace0_generated_121_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93397if((retVal = function_namespace0_generated_122_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93398if((retVal = function_namespace0_generated_123_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93399if((retVal = function_namespace0_generated_124_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93400if((retVal = function_namespace0_generated_125_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93401if((retVal = function_namespace0_generated_126_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93402if((retVal = function_namespace0_generated_127_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93403if((retVal = function_namespace0_generated_128_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93404if((retVal = function_namespace0_generated_129_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93405if((retVal = function_namespace0_generated_130_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93406if((retVal = function_namespace0_generated_131_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93407if((retVal = function_namespace0_generated_132_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93408if((retVal = function_namespace0_generated_133_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93409if((retVal = function_namespace0_generated_134_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93410if((retVal = function_namespace0_generated_135_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93411if((retVal = function_namespace0_generated_136_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93412if((retVal = function_namespace0_generated_137_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93413if((retVal = function_namespace0_generated_138_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93414if((retVal = function_namespace0_generated_139_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93415if((retVal = function_namespace0_generated_140_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93416if((retVal = function_namespace0_generated_141_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93417if((retVal = function_namespace0_generated_142_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93418if((retVal = function_namespace0_generated_143_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93419if((retVal = function_namespace0_generated_144_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93420if((retVal = function_namespace0_generated_145_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93421if((retVal = function_namespace0_generated_146_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93422if((retVal = function_namespace0_generated_147_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93423if((retVal = function_namespace0_generated_148_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93424if((retVal = function_namespace0_generated_149_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93425if((retVal = function_namespace0_generated_150_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93426if((retVal = function_namespace0_generated_151_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93427if((retVal = function_namespace0_generated_152_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93428if((retVal = function_namespace0_generated_153_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93429if((retVal = function_namespace0_generated_154_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93430if((retVal = function_namespace0_generated_155_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93431if((retVal = function_namespace0_generated_156_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93432if((retVal = function_namespace0_generated_157_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93433if((retVal = function_namespace0_generated_158_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93434if((retVal = function_namespace0_generated_159_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93435if((retVal = function_namespace0_generated_160_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93436if((retVal = function_namespace0_generated_161_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93437if((retVal = function_namespace0_generated_162_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93438if((retVal = function_namespace0_generated_163_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93439if((retVal = function_namespace0_generated_164_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93440if((retVal = function_namespace0_generated_165_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93441if((retVal = function_namespace0_generated_166_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93442if((retVal = function_namespace0_generated_167_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93443if((retVal = function_namespace0_generated_168_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93444if((retVal = function_namespace0_generated_169_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93445if((retVal = function_namespace0_generated_170_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93446if((retVal = function_namespace0_generated_171_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93447if((retVal = function_namespace0_generated_172_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93448if((retVal = function_namespace0_generated_173_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93449if((retVal = function_namespace0_generated_174_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93450if((retVal = function_namespace0_generated_175_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93451if((retVal = function_namespace0_generated_176_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93452if((retVal = function_namespace0_generated_177_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93453if((retVal = function_namespace0_generated_178_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93454if((retVal = function_namespace0_generated_179_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93455if((retVal = function_namespace0_generated_180_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93456if((retVal = function_namespace0_generated_181_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93457if((retVal = function_namespace0_generated_182_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93458if((retVal = function_namespace0_generated_183_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93459if((retVal = function_namespace0_generated_184_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93460if((retVal = function_namespace0_generated_185_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93461if((retVal = function_namespace0_generated_186_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93462if((retVal = function_namespace0_generated_187_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93463if((retVal = function_namespace0_generated_188_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93464if((retVal = function_namespace0_generated_189_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93465if((retVal = function_namespace0_generated_190_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93466if((retVal = function_namespace0_generated_191_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93467if((retVal = function_namespace0_generated_192_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93468if((retVal = function_namespace0_generated_193_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93469if((retVal = function_namespace0_generated_194_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93470if((retVal = function_namespace0_generated_195_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93471if((retVal = function_namespace0_generated_196_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93472if((retVal = function_namespace0_generated_197_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93473if((retVal = function_namespace0_generated_198_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93474if((retVal = function_namespace0_generated_199_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93475if((retVal = function_namespace0_generated_200_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93476if((retVal = function_namespace0_generated_201_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93477if((retVal = function_namespace0_generated_202_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93478if((retVal = function_namespace0_generated_203_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93479if((retVal = function_namespace0_generated_204_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93480if((retVal = function_namespace0_generated_205_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93481if((retVal = function_namespace0_generated_206_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93482if((retVal = function_namespace0_generated_207_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93483if((retVal = function_namespace0_generated_208_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93484if((retVal = function_namespace0_generated_209_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93485if((retVal = function_namespace0_generated_210_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93486if((retVal = function_namespace0_generated_211_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93487if((retVal = function_namespace0_generated_212_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93488if((retVal = function_namespace0_generated_213_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93489if((retVal = function_namespace0_generated_214_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93490if((retVal = function_namespace0_generated_215_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93491if((retVal = function_namespace0_generated_216_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93492if((retVal = function_namespace0_generated_217_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93493if((retVal = function_namespace0_generated_218_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93494if((retVal = function_namespace0_generated_219_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93495if((retVal = function_namespace0_generated_220_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93496if((retVal = function_namespace0_generated_221_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93497if((retVal = function_namespace0_generated_222_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93498if((retVal = function_namespace0_generated_223_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93499if((retVal = function_namespace0_generated_224_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93500if((retVal = function_namespace0_generated_225_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93501if((retVal = function_namespace0_generated_226_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93502if((retVal = function_namespace0_generated_227_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93503if((retVal = function_namespace0_generated_228_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93504if((retVal = function_namespace0_generated_229_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93505if((retVal = function_namespace0_generated_230_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93506if((retVal = function_namespace0_generated_231_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93507if((retVal = function_namespace0_generated_232_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93508if((retVal = function_namespace0_generated_233_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93509if((retVal = function_namespace0_generated_234_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93510if((retVal = function_namespace0_generated_235_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93511if((retVal = function_namespace0_generated_236_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93512if((retVal = function_namespace0_generated_237_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93513if((retVal = function_namespace0_generated_238_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93514if((retVal = function_namespace0_generated_239_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93515if((retVal = function_namespace0_generated_240_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93516if((retVal = function_namespace0_generated_241_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93517if((retVal = function_namespace0_generated_242_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93518if((retVal = function_namespace0_generated_243_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93519if((retVal = function_namespace0_generated_244_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93520if((retVal = function_namespace0_generated_245_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93521if((retVal = function_namespace0_generated_246_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93522if((retVal = function_namespace0_generated_247_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93523if((retVal = function_namespace0_generated_248_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93524if((retVal = function_namespace0_generated_249_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93525if((retVal = function_namespace0_generated_250_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93526if((retVal = function_namespace0_generated_251_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93527if((retVal = function_namespace0_generated_252_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93528if((retVal = function_namespace0_generated_253_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93529if((retVal = function_namespace0_generated_254_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93530if((retVal = function_namespace0_generated_255_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93531if((retVal = function_namespace0_generated_256_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93532if((retVal = function_namespace0_generated_257_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93533if((retVal = function_namespace0_generated_258_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93534if((retVal = function_namespace0_generated_259_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93535if((retVal = function_namespace0_generated_260_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93536if((retVal = function_namespace0_generated_261_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93537if((retVal = function_namespace0_generated_262_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93538if((retVal = function_namespace0_generated_263_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93539if((retVal = function_namespace0_generated_264_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93540if((retVal = function_namespace0_generated_265_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93541if((retVal = function_namespace0_generated_266_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93542if((retVal = function_namespace0_generated_267_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93543if((retVal = function_namespace0_generated_268_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93544if((retVal = function_namespace0_generated_269_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93545if((retVal = function_namespace0_generated_270_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93546if((retVal = function_namespace0_generated_271_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93547if((retVal = function_namespace0_generated_272_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93548if((retVal = function_namespace0_generated_273_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93549if((retVal = function_namespace0_generated_274_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93550if((retVal = function_namespace0_generated_275_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93551if((retVal = function_namespace0_generated_276_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93552if((retVal = function_namespace0_generated_277_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93553if((retVal = function_namespace0_generated_278_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93554if((retVal = function_namespace0_generated_279_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93555if((retVal = function_namespace0_generated_280_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93556if((retVal = function_namespace0_generated_281_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93557if((retVal = function_namespace0_generated_282_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93558if((retVal = function_namespace0_generated_283_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93559if((retVal = function_namespace0_generated_284_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93560if((retVal = function_namespace0_generated_285_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93561if((retVal = function_namespace0_generated_286_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93562if((retVal = function_namespace0_generated_287_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93563if((retVal = function_namespace0_generated_288_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93564if((retVal = function_namespace0_generated_289_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93565if((retVal = function_namespace0_generated_290_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93566if((retVal = function_namespace0_generated_291_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93567if((retVal = function_namespace0_generated_292_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93568if((retVal = function_namespace0_generated_293_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93569if((retVal = function_namespace0_generated_294_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93570if((retVal = function_namespace0_generated_295_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93571if((retVal = function_namespace0_generated_296_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93572if((retVal = function_namespace0_generated_297_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93573if((retVal = function_namespace0_generated_298_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93574if((retVal = function_namespace0_generated_299_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93575if((retVal = function_namespace0_generated_300_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93576if((retVal = function_namespace0_generated_301_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93577if((retVal = function_namespace0_generated_302_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93578if((retVal = function_namespace0_generated_303_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93579if((retVal = function_namespace0_generated_304_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93580if((retVal = function_namespace0_generated_305_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93581if((retVal = function_namespace0_generated_306_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93582if((retVal = function_namespace0_generated_307_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93583if((retVal = function_namespace0_generated_308_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93584if((retVal = function_namespace0_generated_309_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93585if((retVal = function_namespace0_generated_310_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93586if((retVal = function_namespace0_generated_311_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93587if((retVal = function_namespace0_generated_312_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93588if((retVal = function_namespace0_generated_313_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93589if((retVal = function_namespace0_generated_314_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93590if((retVal = function_namespace0_generated_315_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93591if((retVal = function_namespace0_generated_316_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93592if((retVal = function_namespace0_generated_317_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93593if((retVal = function_namespace0_generated_318_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93594if((retVal = function_namespace0_generated_319_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93595if((retVal = function_namespace0_generated_320_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93596if((retVal = function_namespace0_generated_321_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93597if((retVal = function_namespace0_generated_322_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93598if((retVal = function_namespace0_generated_323_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93599if((retVal = function_namespace0_generated_324_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93600if((retVal = function_namespace0_generated_325_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93601if((retVal = function_namespace0_generated_326_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93602if((retVal = function_namespace0_generated_327_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93603if((retVal = function_namespace0_generated_328_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93604if((retVal = function_namespace0_generated_329_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93605if((retVal = function_namespace0_generated_330_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93606if((retVal = function_namespace0_generated_331_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93607if((retVal = function_namespace0_generated_332_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93608if((retVal = function_namespace0_generated_333_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93609if((retVal = function_namespace0_generated_334_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93610if((retVal = function_namespace0_generated_335_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93611if((retVal = function_namespace0_generated_336_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93612if((retVal = function_namespace0_generated_337_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93613if((retVal = function_namespace0_generated_338_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93614if((retVal = function_namespace0_generated_339_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93615if((retVal = function_namespace0_generated_340_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93616if((retVal = function_namespace0_generated_341_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93617if((retVal = function_namespace0_generated_342_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93618if((retVal = function_namespace0_generated_343_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93619if((retVal = function_namespace0_generated_344_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93620if((retVal = function_namespace0_generated_345_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93621if((retVal = function_namespace0_generated_346_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93622if((retVal = function_namespace0_generated_347_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93623if((retVal = function_namespace0_generated_348_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93624if((retVal = function_namespace0_generated_349_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93625if((retVal = function_namespace0_generated_350_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93626if((retVal = function_namespace0_generated_351_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93627if((retVal = function_namespace0_generated_352_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93628if((retVal = function_namespace0_generated_353_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93629if((retVal = function_namespace0_generated_354_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93630if((retVal = function_namespace0_generated_355_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93631if((retVal = function_namespace0_generated_356_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93632if((retVal = function_namespace0_generated_357_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93633if((retVal = function_namespace0_generated_358_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93634if((retVal = function_namespace0_generated_359_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93635if((retVal = function_namespace0_generated_360_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93636if((retVal = function_namespace0_generated_361_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93637if((retVal = function_namespace0_generated_362_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93638if((retVal = function_namespace0_generated_363_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93639if((retVal = function_namespace0_generated_364_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93640if((retVal = function_namespace0_generated_365_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93641if((retVal = function_namespace0_generated_366_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93642if((retVal = function_namespace0_generated_367_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93643if((retVal = function_namespace0_generated_368_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93644if((retVal = function_namespace0_generated_369_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93645if((retVal = function_namespace0_generated_370_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93646if((retVal = function_namespace0_generated_371_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93647if((retVal = function_namespace0_generated_372_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93648if((retVal = function_namespace0_generated_373_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93649if((retVal = function_namespace0_generated_374_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93650if((retVal = function_namespace0_generated_375_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93651if((retVal = function_namespace0_generated_376_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93652if((retVal = function_namespace0_generated_377_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93653if((retVal = function_namespace0_generated_378_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93654if((retVal = function_namespace0_generated_379_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93655if((retVal = function_namespace0_generated_380_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93656if((retVal = function_namespace0_generated_381_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93657if((retVal = function_namespace0_generated_382_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93658if((retVal = function_namespace0_generated_383_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93659if((retVal = function_namespace0_generated_384_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93660if((retVal = function_namespace0_generated_385_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93661if((retVal = function_namespace0_generated_386_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93662if((retVal = function_namespace0_generated_387_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93663if((retVal = function_namespace0_generated_388_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93664if((retVal = function_namespace0_generated_389_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93665if((retVal = function_namespace0_generated_390_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93666if((retVal = function_namespace0_generated_391_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93667if((retVal = function_namespace0_generated_392_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93668if((retVal = function_namespace0_generated_393_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93669if((retVal = function_namespace0_generated_394_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93670if((retVal = function_namespace0_generated_395_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93671if((retVal = function_namespace0_generated_396_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93672if((retVal = function_namespace0_generated_397_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93673if((retVal = function_namespace0_generated_398_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93674if((retVal = function_namespace0_generated_399_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93675if((retVal = function_namespace0_generated_400_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93676if((retVal = function_namespace0_generated_401_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93677if((retVal = function_namespace0_generated_402_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93678if((retVal = function_namespace0_generated_403_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93679if((retVal = function_namespace0_generated_404_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93680if((retVal = function_namespace0_generated_405_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93681if((retVal = function_namespace0_generated_406_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93682if((retVal = function_namespace0_generated_407_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93683if((retVal = function_namespace0_generated_408_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93684if((retVal = function_namespace0_generated_409_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93685if((retVal = function_namespace0_generated_410_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93686if((retVal = function_namespace0_generated_411_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93687if((retVal = function_namespace0_generated_412_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93688if((retVal = function_namespace0_generated_413_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93689if((retVal = function_namespace0_generated_414_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93690if((retVal = function_namespace0_generated_415_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93691if((retVal = function_namespace0_generated_416_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93692if((retVal = function_namespace0_generated_417_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93693if((retVal = function_namespace0_generated_418_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93694if((retVal = function_namespace0_generated_419_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93695if((retVal = function_namespace0_generated_420_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93696if((retVal = function_namespace0_generated_421_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93697if((retVal = function_namespace0_generated_422_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93698if((retVal = function_namespace0_generated_423_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93699if((retVal = function_namespace0_generated_424_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93700if((retVal = function_namespace0_generated_425_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93701if((retVal = function_namespace0_generated_426_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93702if((retVal = function_namespace0_generated_427_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93703if((retVal = function_namespace0_generated_428_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93704if((retVal = function_namespace0_generated_429_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93705if((retVal = function_namespace0_generated_430_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93706if((retVal = function_namespace0_generated_431_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93707if((retVal = function_namespace0_generated_432_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93708if((retVal = function_namespace0_generated_433_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93709if((retVal = function_namespace0_generated_434_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93710if((retVal = function_namespace0_generated_435_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93711if((retVal = function_namespace0_generated_436_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93712if((retVal = function_namespace0_generated_437_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93713if((retVal = function_namespace0_generated_438_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93714if((retVal = function_namespace0_generated_439_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93715if((retVal = function_namespace0_generated_440_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93716if((retVal = function_namespace0_generated_441_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93717if((retVal = function_namespace0_generated_442_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93718if((retVal = function_namespace0_generated_443_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93719if((retVal = function_namespace0_generated_444_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93720if((retVal = function_namespace0_generated_445_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93721if((retVal = function_namespace0_generated_446_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93722if((retVal = function_namespace0_generated_447_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93723if((retVal = function_namespace0_generated_448_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93724if((retVal = function_namespace0_generated_449_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93725if((retVal = function_namespace0_generated_450_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93726if((retVal = function_namespace0_generated_451_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93727if((retVal = function_namespace0_generated_452_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93728if((retVal = function_namespace0_generated_453_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93729if((retVal = function_namespace0_generated_454_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93730if((retVal = function_namespace0_generated_455_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93731if((retVal = function_namespace0_generated_456_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93732if((retVal = function_namespace0_generated_457_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93733if((retVal = function_namespace0_generated_458_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93734if((retVal = function_namespace0_generated_459_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93735if((retVal = function_namespace0_generated_460_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93736if((retVal = function_namespace0_generated_461_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93737if((retVal = function_namespace0_generated_462_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93738if((retVal = function_namespace0_generated_463_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93739if((retVal = function_namespace0_generated_464_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93740if((retVal = function_namespace0_generated_465_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93741if((retVal = function_namespace0_generated_466_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93742if((retVal = function_namespace0_generated_467_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93743if((retVal = function_namespace0_generated_468_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93744if((retVal = function_namespace0_generated_469_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93745if((retVal = function_namespace0_generated_470_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93746if((retVal = function_namespace0_generated_471_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93747if((retVal = function_namespace0_generated_472_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93748if((retVal = function_namespace0_generated_473_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93749if((retVal = function_namespace0_generated_474_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93750if((retVal = function_namespace0_generated_475_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93751if((retVal = function_namespace0_generated_476_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93752if((retVal = function_namespace0_generated_477_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93753if((retVal = function_namespace0_generated_478_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93754if((retVal = function_namespace0_generated_479_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93755if((retVal = function_namespace0_generated_480_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93756if((retVal = function_namespace0_generated_481_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93757if((retVal = function_namespace0_generated_482_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93758if((retVal = function_namespace0_generated_483_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93759if((retVal = function_namespace0_generated_484_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93760if((retVal = function_namespace0_generated_485_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93761if((retVal = function_namespace0_generated_486_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93762if((retVal = function_namespace0_generated_487_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93763if((retVal = function_namespace0_generated_488_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93764if((retVal = function_namespace0_generated_489_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93765if((retVal = function_namespace0_generated_490_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93766if((retVal = function_namespace0_generated_491_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93767if((retVal = function_namespace0_generated_492_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93768if((retVal = function_namespace0_generated_493_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93769if((retVal = function_namespace0_generated_494_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93770if((retVal = function_namespace0_generated_495_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93771if((retVal = function_namespace0_generated_496_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93772if((retVal = function_namespace0_generated_497_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93773if((retVal = function_namespace0_generated_498_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93774if((retVal = function_namespace0_generated_499_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93775if((retVal = function_namespace0_generated_500_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93776if((retVal = function_namespace0_generated_501_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93777if((retVal = function_namespace0_generated_502_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93778if((retVal = function_namespace0_generated_503_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93779if((retVal = function_namespace0_generated_504_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93780if((retVal = function_namespace0_generated_505_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93781if((retVal = function_namespace0_generated_506_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93782if((retVal = function_namespace0_generated_507_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93783if((retVal = function_namespace0_generated_508_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93784if((retVal = function_namespace0_generated_509_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93785if((retVal = function_namespace0_generated_510_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93786if((retVal = function_namespace0_generated_511_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93787if((retVal = function_namespace0_generated_512_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93788if((retVal = function_namespace0_generated_513_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93789if((retVal = function_namespace0_generated_514_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93790if((retVal = function_namespace0_generated_515_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93791if((retVal = function_namespace0_generated_516_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93792if((retVal = function_namespace0_generated_517_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93793if((retVal = function_namespace0_generated_518_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93794if((retVal = function_namespace0_generated_519_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93795if((retVal = function_namespace0_generated_520_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93796if((retVal = function_namespace0_generated_521_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93797if((retVal = function_namespace0_generated_522_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93798if((retVal = function_namespace0_generated_523_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93799if((retVal = function_namespace0_generated_524_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93800if((retVal = function_namespace0_generated_525_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93801if((retVal = function_namespace0_generated_526_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93802if((retVal = function_namespace0_generated_527_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93803if((retVal = function_namespace0_generated_528_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93804if((retVal = function_namespace0_generated_529_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93805if((retVal = function_namespace0_generated_530_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93806if((retVal = function_namespace0_generated_531_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93807if((retVal = function_namespace0_generated_532_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93808if((retVal = function_namespace0_generated_533_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93809if((retVal = function_namespace0_generated_534_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93810if((retVal = function_namespace0_generated_535_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93811if((retVal = function_namespace0_generated_536_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93812if((retVal = function_namespace0_generated_537_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93813if((retVal = function_namespace0_generated_538_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93814if((retVal = function_namespace0_generated_539_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93815if((retVal = function_namespace0_generated_540_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93816if((retVal = function_namespace0_generated_541_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93817if((retVal = function_namespace0_generated_542_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93818if((retVal = function_namespace0_generated_543_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93819if((retVal = function_namespace0_generated_544_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93820if((retVal = function_namespace0_generated_545_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93821if((retVal = function_namespace0_generated_546_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93822if((retVal = function_namespace0_generated_547_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93823if((retVal = function_namespace0_generated_548_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93824if((retVal = function_namespace0_generated_549_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93825if((retVal = function_namespace0_generated_550_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93826if((retVal = function_namespace0_generated_551_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93827if((retVal = function_namespace0_generated_552_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93828if((retVal = function_namespace0_generated_553_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93829if((retVal = function_namespace0_generated_554_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93830if((retVal = function_namespace0_generated_555_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93831if((retVal = function_namespace0_generated_556_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93832if((retVal = function_namespace0_generated_557_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93833if((retVal = function_namespace0_generated_558_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93834if((retVal = function_namespace0_generated_559_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93835if((retVal = function_namespace0_generated_560_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93836if((retVal = function_namespace0_generated_561_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93837if((retVal = function_namespace0_generated_562_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93838if((retVal = function_namespace0_generated_563_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93839if((retVal = function_namespace0_generated_564_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93840if((retVal = function_namespace0_generated_565_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93841if((retVal = function_namespace0_generated_566_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93842if((retVal = function_namespace0_generated_567_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93843if((retVal = function_namespace0_generated_568_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93844if((retVal = function_namespace0_generated_569_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93845if((retVal = function_namespace0_generated_570_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93846if((retVal = function_namespace0_generated_571_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93847if((retVal = function_namespace0_generated_572_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93848if((retVal = function_namespace0_generated_573_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93849if((retVal = function_namespace0_generated_574_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93850if((retVal = function_namespace0_generated_575_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93851if((retVal = function_namespace0_generated_576_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93852if((retVal = function_namespace0_generated_577_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93853if((retVal = function_namespace0_generated_578_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93854if((retVal = function_namespace0_generated_579_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93855if((retVal = function_namespace0_generated_580_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93856if((retVal = function_namespace0_generated_581_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93857if((retVal = function_namespace0_generated_582_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93858if((retVal = function_namespace0_generated_583_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93859if((retVal = function_namespace0_generated_584_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93860if((retVal = function_namespace0_generated_585_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93861if((retVal = function_namespace0_generated_586_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93862if((retVal = function_namespace0_generated_587_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93863if((retVal = function_namespace0_generated_588_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93864if((retVal = function_namespace0_generated_589_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93865if((retVal = function_namespace0_generated_590_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93866if((retVal = function_namespace0_generated_591_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93867if((retVal = function_namespace0_generated_592_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93868if((retVal = function_namespace0_generated_593_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93869if((retVal = function_namespace0_generated_594_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93870if((retVal = function_namespace0_generated_595_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93871if((retVal = function_namespace0_generated_596_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93872if((retVal = function_namespace0_generated_597_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93873if((retVal = function_namespace0_generated_598_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93874if((retVal = function_namespace0_generated_599_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93875if((retVal = function_namespace0_generated_600_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93876if((retVal = function_namespace0_generated_601_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93877if((retVal = function_namespace0_generated_602_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93878if((retVal = function_namespace0_generated_603_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93879if((retVal = function_namespace0_generated_604_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93880if((retVal = function_namespace0_generated_605_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93881if((retVal = function_namespace0_generated_606_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93882if((retVal = function_namespace0_generated_607_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93883if((retVal = function_namespace0_generated_608_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93884if((retVal = function_namespace0_generated_609_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93885if((retVal = function_namespace0_generated_610_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93886if((retVal = function_namespace0_generated_611_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93887if((retVal = function_namespace0_generated_612_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93888if((retVal = function_namespace0_generated_613_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93889if((retVal = function_namespace0_generated_614_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93890if((retVal = function_namespace0_generated_615_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93891if((retVal = function_namespace0_generated_616_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93892if((retVal = function_namespace0_generated_617_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93893if((retVal = function_namespace0_generated_618_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93894if((retVal = function_namespace0_generated_619_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93895if((retVal = function_namespace0_generated_620_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93896if((retVal = function_namespace0_generated_621_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93897if((retVal = function_namespace0_generated_622_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93898if((retVal = function_namespace0_generated_623_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93899if((retVal = function_namespace0_generated_624_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93900if((retVal = function_namespace0_generated_625_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93901if((retVal = function_namespace0_generated_626_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93902if((retVal = function_namespace0_generated_627_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93903if((retVal = function_namespace0_generated_628_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93904if((retVal = function_namespace0_generated_629_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93905if((retVal = function_namespace0_generated_630_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93906if((retVal = function_namespace0_generated_631_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93907if((retVal = function_namespace0_generated_632_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93908if((retVal = function_namespace0_generated_633_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93909if((retVal = function_namespace0_generated_634_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93910if((retVal = function_namespace0_generated_635_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93911if((retVal = function_namespace0_generated_636_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93912if((retVal = function_namespace0_generated_637_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93913if((retVal = function_namespace0_generated_638_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93914if((retVal = function_namespace0_generated_639_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93915if((retVal = function_namespace0_generated_640_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93916if((retVal = function_namespace0_generated_641_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93917if((retVal = function_namespace0_generated_642_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93918if((retVal = function_namespace0_generated_643_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93919if((retVal = function_namespace0_generated_644_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93920if((retVal = function_namespace0_generated_645_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93921if((retVal = function_namespace0_generated_646_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93922if((retVal = function_namespace0_generated_647_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93923if((retVal = function_namespace0_generated_648_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93924if((retVal = function_namespace0_generated_649_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93925if((retVal = function_namespace0_generated_650_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93926if((retVal = function_namespace0_generated_651_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93927if((retVal = function_namespace0_generated_652_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93928if((retVal = function_namespace0_generated_653_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93929if((retVal = function_namespace0_generated_654_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93930if((retVal = function_namespace0_generated_655_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93931if((retVal = function_namespace0_generated_656_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93932if((retVal = function_namespace0_generated_657_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93933if((retVal = function_namespace0_generated_658_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93934if((retVal = function_namespace0_generated_659_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93935if((retVal = function_namespace0_generated_660_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93936if((retVal = function_namespace0_generated_661_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93937if((retVal = function_namespace0_generated_662_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93938if((retVal = function_namespace0_generated_663_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93939if((retVal = function_namespace0_generated_664_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93940if((retVal = function_namespace0_generated_665_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93941if((retVal = function_namespace0_generated_666_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93942if((retVal = function_namespace0_generated_667_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93943if((retVal = function_namespace0_generated_668_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93944if((retVal = function_namespace0_generated_669_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93945if((retVal = function_namespace0_generated_670_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93946if((retVal = function_namespace0_generated_671_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93947if((retVal = function_namespace0_generated_672_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93948if((retVal = function_namespace0_generated_673_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93949if((retVal = function_namespace0_generated_674_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93950if((retVal = function_namespace0_generated_675_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93951if((retVal = function_namespace0_generated_676_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93952if((retVal = function_namespace0_generated_677_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93953if((retVal = function_namespace0_generated_678_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93954if((retVal = function_namespace0_generated_679_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93955if((retVal = function_namespace0_generated_680_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93956if((retVal = function_namespace0_generated_681_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93957if((retVal = function_namespace0_generated_682_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93958if((retVal = function_namespace0_generated_683_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93959if((retVal = function_namespace0_generated_684_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93960if((retVal = function_namespace0_generated_685_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93961if((retVal = function_namespace0_generated_686_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93962if((retVal = function_namespace0_generated_687_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93963if((retVal = function_namespace0_generated_688_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93964if((retVal = function_namespace0_generated_689_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93965if((retVal = function_namespace0_generated_690_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93966if((retVal = function_namespace0_generated_691_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93967if((retVal = function_namespace0_generated_692_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93968if((retVal = function_namespace0_generated_693_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93969if((retVal = function_namespace0_generated_694_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93970if((retVal = function_namespace0_generated_695_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93971if((retVal = function_namespace0_generated_696_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93972if((retVal = function_namespace0_generated_697_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93973if((retVal = function_namespace0_generated_698_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93974if((retVal = function_namespace0_generated_699_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93975if((retVal = function_namespace0_generated_700_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93976if((retVal = function_namespace0_generated_701_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93977if((retVal = function_namespace0_generated_702_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93978if((retVal = function_namespace0_generated_703_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93979if((retVal = function_namespace0_generated_704_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93980if((retVal = function_namespace0_generated_705_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93981if((retVal = function_namespace0_generated_706_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93982if((retVal = function_namespace0_generated_707_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93983if((retVal = function_namespace0_generated_708_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93984if((retVal = function_namespace0_generated_709_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93985if((retVal = function_namespace0_generated_710_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93986if((retVal = function_namespace0_generated_711_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93987if((retVal = function_namespace0_generated_712_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93988if((retVal = function_namespace0_generated_713_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93989if((retVal = function_namespace0_generated_714_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93990if((retVal = function_namespace0_generated_715_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93991if((retVal = function_namespace0_generated_716_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93992if((retVal = function_namespace0_generated_717_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93993if((retVal = function_namespace0_generated_718_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93994if((retVal = function_namespace0_generated_719_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93995if((retVal = function_namespace0_generated_720_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93996if((retVal = function_namespace0_generated_721_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93997if((retVal = function_namespace0_generated_722_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93998if((retVal = function_namespace0_generated_723_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
93999if((retVal = function_namespace0_generated_724_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94000if((retVal = function_namespace0_generated_725_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94001if((retVal = function_namespace0_generated_726_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94002if((retVal = function_namespace0_generated_727_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94003if((retVal = function_namespace0_generated_728_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94004if((retVal = function_namespace0_generated_729_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94005if((retVal = function_namespace0_generated_730_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94006if((retVal = function_namespace0_generated_731_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94007if((retVal = function_namespace0_generated_732_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94008if((retVal = function_namespace0_generated_733_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94009if((retVal = function_namespace0_generated_734_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94010if((retVal = function_namespace0_generated_735_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94011if((retVal = function_namespace0_generated_736_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94012if((retVal = function_namespace0_generated_737_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94013if((retVal = function_namespace0_generated_738_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94014if((retVal = function_namespace0_generated_739_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94015if((retVal = function_namespace0_generated_740_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94016if((retVal = function_namespace0_generated_741_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94017if((retVal = function_namespace0_generated_742_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94018if((retVal = function_namespace0_generated_743_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94019if((retVal = function_namespace0_generated_744_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94020if((retVal = function_namespace0_generated_745_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94021if((retVal = function_namespace0_generated_746_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94022if((retVal = function_namespace0_generated_747_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94023if((retVal = function_namespace0_generated_748_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94024if((retVal = function_namespace0_generated_749_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94025if((retVal = function_namespace0_generated_750_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94026if((retVal = function_namespace0_generated_751_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94027if((retVal = function_namespace0_generated_752_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94028if((retVal = function_namespace0_generated_753_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94029if((retVal = function_namespace0_generated_754_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94030if((retVal = function_namespace0_generated_755_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94031if((retVal = function_namespace0_generated_756_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94032if((retVal = function_namespace0_generated_757_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94033if((retVal = function_namespace0_generated_758_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94034if((retVal = function_namespace0_generated_759_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94035if((retVal = function_namespace0_generated_760_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94036if((retVal = function_namespace0_generated_761_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94037if((retVal = function_namespace0_generated_762_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94038if((retVal = function_namespace0_generated_763_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94039if((retVal = function_namespace0_generated_764_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94040if((retVal = function_namespace0_generated_765_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94041if((retVal = function_namespace0_generated_766_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94042if((retVal = function_namespace0_generated_767_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94043if((retVal = function_namespace0_generated_768_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94044if((retVal = function_namespace0_generated_769_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94045if((retVal = function_namespace0_generated_770_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94046if((retVal = function_namespace0_generated_771_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94047if((retVal = function_namespace0_generated_772_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94048if((retVal = function_namespace0_generated_773_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94049if((retVal = function_namespace0_generated_774_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94050if((retVal = function_namespace0_generated_775_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94051if((retVal = function_namespace0_generated_776_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94052if((retVal = function_namespace0_generated_777_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94053if((retVal = function_namespace0_generated_778_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94054if((retVal = function_namespace0_generated_779_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94055if((retVal = function_namespace0_generated_780_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94056if((retVal = function_namespace0_generated_781_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94057if((retVal = function_namespace0_generated_782_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94058if((retVal = function_namespace0_generated_783_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94059if((retVal = function_namespace0_generated_784_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94060if((retVal = function_namespace0_generated_785_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94061if((retVal = function_namespace0_generated_786_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94062if((retVal = function_namespace0_generated_787_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94063if((retVal = function_namespace0_generated_788_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94064if((retVal = function_namespace0_generated_789_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94065if((retVal = function_namespace0_generated_790_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94066if((retVal = function_namespace0_generated_791_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94067if((retVal = function_namespace0_generated_792_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94068if((retVal = function_namespace0_generated_793_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94069if((retVal = function_namespace0_generated_794_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94070if((retVal = function_namespace0_generated_795_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94071if((retVal = function_namespace0_generated_796_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94072if((retVal = function_namespace0_generated_797_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94073if((retVal = function_namespace0_generated_798_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94074if((retVal = function_namespace0_generated_799_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94075if((retVal = function_namespace0_generated_800_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94076if((retVal = function_namespace0_generated_801_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94077if((retVal = function_namespace0_generated_802_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94078if((retVal = function_namespace0_generated_803_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94079if((retVal = function_namespace0_generated_804_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94080if((retVal = function_namespace0_generated_805_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94081if((retVal = function_namespace0_generated_806_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94082if((retVal = function_namespace0_generated_807_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94083if((retVal = function_namespace0_generated_808_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94084if((retVal = function_namespace0_generated_809_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94085if((retVal = function_namespace0_generated_810_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94086if((retVal = function_namespace0_generated_811_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94087if((retVal = function_namespace0_generated_812_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94088if((retVal = function_namespace0_generated_813_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94089if((retVal = function_namespace0_generated_814_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94090if((retVal = function_namespace0_generated_815_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94091if((retVal = function_namespace0_generated_816_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94092if((retVal = function_namespace0_generated_817_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94093if((retVal = function_namespace0_generated_818_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94094if((retVal = function_namespace0_generated_819_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94095if((retVal = function_namespace0_generated_820_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94096if((retVal = function_namespace0_generated_821_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94097if((retVal = function_namespace0_generated_822_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94098if((retVal = function_namespace0_generated_823_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94099if((retVal = function_namespace0_generated_823_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94100if((retVal = function_namespace0_generated_822_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94101if((retVal = function_namespace0_generated_821_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94102if((retVal = function_namespace0_generated_820_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94103if((retVal = function_namespace0_generated_819_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94104if((retVal = function_namespace0_generated_818_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94105if((retVal = function_namespace0_generated_817_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94106if((retVal = function_namespace0_generated_816_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94107if((retVal = function_namespace0_generated_815_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94108if((retVal = function_namespace0_generated_814_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94109if((retVal = function_namespace0_generated_813_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94110if((retVal = function_namespace0_generated_812_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94111if((retVal = function_namespace0_generated_811_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94112if((retVal = function_namespace0_generated_810_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94113if((retVal = function_namespace0_generated_809_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94114if((retVal = function_namespace0_generated_808_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94115if((retVal = function_namespace0_generated_807_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94116if((retVal = function_namespace0_generated_806_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94117if((retVal = function_namespace0_generated_805_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94118if((retVal = function_namespace0_generated_804_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94119if((retVal = function_namespace0_generated_803_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94120if((retVal = function_namespace0_generated_802_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94121if((retVal = function_namespace0_generated_801_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94122if((retVal = function_namespace0_generated_800_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94123if((retVal = function_namespace0_generated_799_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94124if((retVal = function_namespace0_generated_798_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94125if((retVal = function_namespace0_generated_797_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94126if((retVal = function_namespace0_generated_796_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94127if((retVal = function_namespace0_generated_795_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94128if((retVal = function_namespace0_generated_794_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94129if((retVal = function_namespace0_generated_793_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94130if((retVal = function_namespace0_generated_792_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94131if((retVal = function_namespace0_generated_791_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94132if((retVal = function_namespace0_generated_790_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94133if((retVal = function_namespace0_generated_789_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94134if((retVal = function_namespace0_generated_788_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94135if((retVal = function_namespace0_generated_787_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94136if((retVal = function_namespace0_generated_786_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94137if((retVal = function_namespace0_generated_785_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94138if((retVal = function_namespace0_generated_784_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94139if((retVal = function_namespace0_generated_783_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94140if((retVal = function_namespace0_generated_782_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94141if((retVal = function_namespace0_generated_781_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94142if((retVal = function_namespace0_generated_780_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94143if((retVal = function_namespace0_generated_779_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94144if((retVal = function_namespace0_generated_778_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94145if((retVal = function_namespace0_generated_777_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94146if((retVal = function_namespace0_generated_776_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94147if((retVal = function_namespace0_generated_775_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94148if((retVal = function_namespace0_generated_774_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94149if((retVal = function_namespace0_generated_773_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94150if((retVal = function_namespace0_generated_772_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94151if((retVal = function_namespace0_generated_771_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94152if((retVal = function_namespace0_generated_770_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94153if((retVal = function_namespace0_generated_769_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94154if((retVal = function_namespace0_generated_768_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94155if((retVal = function_namespace0_generated_767_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94156if((retVal = function_namespace0_generated_766_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94157if((retVal = function_namespace0_generated_765_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94158if((retVal = function_namespace0_generated_764_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94159if((retVal = function_namespace0_generated_763_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94160if((retVal = function_namespace0_generated_762_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94161if((retVal = function_namespace0_generated_761_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94162if((retVal = function_namespace0_generated_760_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94163if((retVal = function_namespace0_generated_759_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94164if((retVal = function_namespace0_generated_758_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94165if((retVal = function_namespace0_generated_757_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94166if((retVal = function_namespace0_generated_756_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94167if((retVal = function_namespace0_generated_755_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94168if((retVal = function_namespace0_generated_754_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94169if((retVal = function_namespace0_generated_753_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94170if((retVal = function_namespace0_generated_752_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94171if((retVal = function_namespace0_generated_751_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94172if((retVal = function_namespace0_generated_750_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94173if((retVal = function_namespace0_generated_749_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94174if((retVal = function_namespace0_generated_748_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94175if((retVal = function_namespace0_generated_747_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94176if((retVal = function_namespace0_generated_746_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94177if((retVal = function_namespace0_generated_745_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94178if((retVal = function_namespace0_generated_744_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94179if((retVal = function_namespace0_generated_743_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94180if((retVal = function_namespace0_generated_742_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94181if((retVal = function_namespace0_generated_741_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94182if((retVal = function_namespace0_generated_740_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94183if((retVal = function_namespace0_generated_739_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94184if((retVal = function_namespace0_generated_738_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94185if((retVal = function_namespace0_generated_737_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94186if((retVal = function_namespace0_generated_736_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94187if((retVal = function_namespace0_generated_735_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94188if((retVal = function_namespace0_generated_734_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94189if((retVal = function_namespace0_generated_733_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94190if((retVal = function_namespace0_generated_732_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94191if((retVal = function_namespace0_generated_731_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94192if((retVal = function_namespace0_generated_730_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94193if((retVal = function_namespace0_generated_729_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94194if((retVal = function_namespace0_generated_728_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94195if((retVal = function_namespace0_generated_727_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94196if((retVal = function_namespace0_generated_726_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94197if((retVal = function_namespace0_generated_725_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94198if((retVal = function_namespace0_generated_724_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94199if((retVal = function_namespace0_generated_723_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94200if((retVal = function_namespace0_generated_722_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94201if((retVal = function_namespace0_generated_721_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94202if((retVal = function_namespace0_generated_720_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94203if((retVal = function_namespace0_generated_719_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94204if((retVal = function_namespace0_generated_718_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94205if((retVal = function_namespace0_generated_717_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94206if((retVal = function_namespace0_generated_716_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94207if((retVal = function_namespace0_generated_715_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94208if((retVal = function_namespace0_generated_714_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94209if((retVal = function_namespace0_generated_713_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94210if((retVal = function_namespace0_generated_712_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94211if((retVal = function_namespace0_generated_711_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94212if((retVal = function_namespace0_generated_710_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94213if((retVal = function_namespace0_generated_709_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94214if((retVal = function_namespace0_generated_708_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94215if((retVal = function_namespace0_generated_707_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94216if((retVal = function_namespace0_generated_706_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94217if((retVal = function_namespace0_generated_705_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94218if((retVal = function_namespace0_generated_704_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94219if((retVal = function_namespace0_generated_703_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94220if((retVal = function_namespace0_generated_702_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94221if((retVal = function_namespace0_generated_701_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94222if((retVal = function_namespace0_generated_700_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94223if((retVal = function_namespace0_generated_699_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94224if((retVal = function_namespace0_generated_698_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94225if((retVal = function_namespace0_generated_697_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94226if((retVal = function_namespace0_generated_696_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94227if((retVal = function_namespace0_generated_695_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94228if((retVal = function_namespace0_generated_694_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94229if((retVal = function_namespace0_generated_693_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94230if((retVal = function_namespace0_generated_692_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94231if((retVal = function_namespace0_generated_691_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94232if((retVal = function_namespace0_generated_690_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94233if((retVal = function_namespace0_generated_689_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94234if((retVal = function_namespace0_generated_688_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94235if((retVal = function_namespace0_generated_687_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94236if((retVal = function_namespace0_generated_686_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94237if((retVal = function_namespace0_generated_685_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94238if((retVal = function_namespace0_generated_684_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94239if((retVal = function_namespace0_generated_683_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94240if((retVal = function_namespace0_generated_682_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94241if((retVal = function_namespace0_generated_681_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94242if((retVal = function_namespace0_generated_680_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94243if((retVal = function_namespace0_generated_679_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94244if((retVal = function_namespace0_generated_678_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94245if((retVal = function_namespace0_generated_677_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94246if((retVal = function_namespace0_generated_676_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94247if((retVal = function_namespace0_generated_675_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94248if((retVal = function_namespace0_generated_674_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94249if((retVal = function_namespace0_generated_673_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94250if((retVal = function_namespace0_generated_672_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94251if((retVal = function_namespace0_generated_671_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94252if((retVal = function_namespace0_generated_670_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94253if((retVal = function_namespace0_generated_669_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94254if((retVal = function_namespace0_generated_668_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94255if((retVal = function_namespace0_generated_667_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94256if((retVal = function_namespace0_generated_666_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94257if((retVal = function_namespace0_generated_665_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94258if((retVal = function_namespace0_generated_664_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94259if((retVal = function_namespace0_generated_663_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94260if((retVal = function_namespace0_generated_662_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94261if((retVal = function_namespace0_generated_661_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94262if((retVal = function_namespace0_generated_660_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94263if((retVal = function_namespace0_generated_659_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94264if((retVal = function_namespace0_generated_658_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94265if((retVal = function_namespace0_generated_657_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94266if((retVal = function_namespace0_generated_656_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94267if((retVal = function_namespace0_generated_655_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94268if((retVal = function_namespace0_generated_654_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94269if((retVal = function_namespace0_generated_653_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94270if((retVal = function_namespace0_generated_652_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94271if((retVal = function_namespace0_generated_651_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94272if((retVal = function_namespace0_generated_650_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94273if((retVal = function_namespace0_generated_649_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94274if((retVal = function_namespace0_generated_648_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94275if((retVal = function_namespace0_generated_647_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94276if((retVal = function_namespace0_generated_646_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94277if((retVal = function_namespace0_generated_645_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94278if((retVal = function_namespace0_generated_644_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94279if((retVal = function_namespace0_generated_643_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94280if((retVal = function_namespace0_generated_642_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94281if((retVal = function_namespace0_generated_641_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94282if((retVal = function_namespace0_generated_640_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94283if((retVal = function_namespace0_generated_639_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94284if((retVal = function_namespace0_generated_638_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94285if((retVal = function_namespace0_generated_637_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94286if((retVal = function_namespace0_generated_636_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94287if((retVal = function_namespace0_generated_635_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94288if((retVal = function_namespace0_generated_634_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94289if((retVal = function_namespace0_generated_633_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94290if((retVal = function_namespace0_generated_632_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94291if((retVal = function_namespace0_generated_631_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94292if((retVal = function_namespace0_generated_630_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94293if((retVal = function_namespace0_generated_629_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94294if((retVal = function_namespace0_generated_628_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94295if((retVal = function_namespace0_generated_627_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94296if((retVal = function_namespace0_generated_626_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94297if((retVal = function_namespace0_generated_625_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94298if((retVal = function_namespace0_generated_624_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94299if((retVal = function_namespace0_generated_623_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94300if((retVal = function_namespace0_generated_622_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94301if((retVal = function_namespace0_generated_621_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94302if((retVal = function_namespace0_generated_620_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94303if((retVal = function_namespace0_generated_619_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94304if((retVal = function_namespace0_generated_618_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94305if((retVal = function_namespace0_generated_617_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94306if((retVal = function_namespace0_generated_616_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94307if((retVal = function_namespace0_generated_615_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94308if((retVal = function_namespace0_generated_614_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94309if((retVal = function_namespace0_generated_613_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94310if((retVal = function_namespace0_generated_612_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94311if((retVal = function_namespace0_generated_611_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94312if((retVal = function_namespace0_generated_610_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94313if((retVal = function_namespace0_generated_609_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94314if((retVal = function_namespace0_generated_608_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94315if((retVal = function_namespace0_generated_607_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94316if((retVal = function_namespace0_generated_606_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94317if((retVal = function_namespace0_generated_605_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94318if((retVal = function_namespace0_generated_604_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94319if((retVal = function_namespace0_generated_603_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94320if((retVal = function_namespace0_generated_602_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94321if((retVal = function_namespace0_generated_601_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94322if((retVal = function_namespace0_generated_600_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94323if((retVal = function_namespace0_generated_599_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94324if((retVal = function_namespace0_generated_598_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94325if((retVal = function_namespace0_generated_597_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94326if((retVal = function_namespace0_generated_596_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94327if((retVal = function_namespace0_generated_595_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94328if((retVal = function_namespace0_generated_594_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94329if((retVal = function_namespace0_generated_593_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94330if((retVal = function_namespace0_generated_592_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94331if((retVal = function_namespace0_generated_591_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94332if((retVal = function_namespace0_generated_590_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94333if((retVal = function_namespace0_generated_589_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94334if((retVal = function_namespace0_generated_588_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94335if((retVal = function_namespace0_generated_587_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94336if((retVal = function_namespace0_generated_586_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94337if((retVal = function_namespace0_generated_585_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94338if((retVal = function_namespace0_generated_584_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94339if((retVal = function_namespace0_generated_583_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94340if((retVal = function_namespace0_generated_582_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94341if((retVal = function_namespace0_generated_581_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94342if((retVal = function_namespace0_generated_580_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94343if((retVal = function_namespace0_generated_579_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94344if((retVal = function_namespace0_generated_578_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94345if((retVal = function_namespace0_generated_577_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94346if((retVal = function_namespace0_generated_576_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94347if((retVal = function_namespace0_generated_575_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94348if((retVal = function_namespace0_generated_574_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94349if((retVal = function_namespace0_generated_573_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94350if((retVal = function_namespace0_generated_572_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94351if((retVal = function_namespace0_generated_571_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94352if((retVal = function_namespace0_generated_570_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94353if((retVal = function_namespace0_generated_569_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94354if((retVal = function_namespace0_generated_568_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94355if((retVal = function_namespace0_generated_567_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94356if((retVal = function_namespace0_generated_566_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94357if((retVal = function_namespace0_generated_565_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94358if((retVal = function_namespace0_generated_564_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94359if((retVal = function_namespace0_generated_563_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94360if((retVal = function_namespace0_generated_562_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94361if((retVal = function_namespace0_generated_561_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94362if((retVal = function_namespace0_generated_560_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94363if((retVal = function_namespace0_generated_559_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94364if((retVal = function_namespace0_generated_558_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94365if((retVal = function_namespace0_generated_557_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94366if((retVal = function_namespace0_generated_556_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94367if((retVal = function_namespace0_generated_555_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94368if((retVal = function_namespace0_generated_554_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94369if((retVal = function_namespace0_generated_553_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94370if((retVal = function_namespace0_generated_552_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94371if((retVal = function_namespace0_generated_551_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94372if((retVal = function_namespace0_generated_550_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94373if((retVal = function_namespace0_generated_549_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94374if((retVal = function_namespace0_generated_548_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94375if((retVal = function_namespace0_generated_547_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94376if((retVal = function_namespace0_generated_546_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94377if((retVal = function_namespace0_generated_545_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94378if((retVal = function_namespace0_generated_544_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94379if((retVal = function_namespace0_generated_543_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94380if((retVal = function_namespace0_generated_542_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94381if((retVal = function_namespace0_generated_541_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94382if((retVal = function_namespace0_generated_540_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94383if((retVal = function_namespace0_generated_539_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94384if((retVal = function_namespace0_generated_538_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94385if((retVal = function_namespace0_generated_537_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94386if((retVal = function_namespace0_generated_536_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94387if((retVal = function_namespace0_generated_535_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94388if((retVal = function_namespace0_generated_534_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94389if((retVal = function_namespace0_generated_533_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94390if((retVal = function_namespace0_generated_532_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94391if((retVal = function_namespace0_generated_531_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94392if((retVal = function_namespace0_generated_530_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94393if((retVal = function_namespace0_generated_529_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94394if((retVal = function_namespace0_generated_528_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94395if((retVal = function_namespace0_generated_527_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94396if((retVal = function_namespace0_generated_526_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94397if((retVal = function_namespace0_generated_525_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94398if((retVal = function_namespace0_generated_524_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94399if((retVal = function_namespace0_generated_523_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94400if((retVal = function_namespace0_generated_522_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94401if((retVal = function_namespace0_generated_521_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94402if((retVal = function_namespace0_generated_520_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94403if((retVal = function_namespace0_generated_519_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94404if((retVal = function_namespace0_generated_518_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94405if((retVal = function_namespace0_generated_517_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94406if((retVal = function_namespace0_generated_516_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94407if((retVal = function_namespace0_generated_515_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94408if((retVal = function_namespace0_generated_514_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94409if((retVal = function_namespace0_generated_513_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94410if((retVal = function_namespace0_generated_512_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94411if((retVal = function_namespace0_generated_511_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94412if((retVal = function_namespace0_generated_510_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94413if((retVal = function_namespace0_generated_509_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94414if((retVal = function_namespace0_generated_508_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94415if((retVal = function_namespace0_generated_507_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94416if((retVal = function_namespace0_generated_506_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94417if((retVal = function_namespace0_generated_505_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94418if((retVal = function_namespace0_generated_504_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94419if((retVal = function_namespace0_generated_503_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94420if((retVal = function_namespace0_generated_502_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94421if((retVal = function_namespace0_generated_501_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94422if((retVal = function_namespace0_generated_500_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94423if((retVal = function_namespace0_generated_499_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94424if((retVal = function_namespace0_generated_498_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94425if((retVal = function_namespace0_generated_497_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94426if((retVal = function_namespace0_generated_496_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94427if((retVal = function_namespace0_generated_495_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94428if((retVal = function_namespace0_generated_494_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94429if((retVal = function_namespace0_generated_493_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94430if((retVal = function_namespace0_generated_492_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94431if((retVal = function_namespace0_generated_491_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94432if((retVal = function_namespace0_generated_490_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94433if((retVal = function_namespace0_generated_489_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94434if((retVal = function_namespace0_generated_488_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94435if((retVal = function_namespace0_generated_487_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94436if((retVal = function_namespace0_generated_486_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94437if((retVal = function_namespace0_generated_485_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94438if((retVal = function_namespace0_generated_484_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94439if((retVal = function_namespace0_generated_483_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94440if((retVal = function_namespace0_generated_482_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94441if((retVal = function_namespace0_generated_481_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94442if((retVal = function_namespace0_generated_480_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94443if((retVal = function_namespace0_generated_479_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94444if((retVal = function_namespace0_generated_478_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94445if((retVal = function_namespace0_generated_477_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94446if((retVal = function_namespace0_generated_476_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94447if((retVal = function_namespace0_generated_475_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94448if((retVal = function_namespace0_generated_474_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94449if((retVal = function_namespace0_generated_473_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94450if((retVal = function_namespace0_generated_472_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94451if((retVal = function_namespace0_generated_471_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94452if((retVal = function_namespace0_generated_470_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94453if((retVal = function_namespace0_generated_469_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94454if((retVal = function_namespace0_generated_468_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94455if((retVal = function_namespace0_generated_467_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94456if((retVal = function_namespace0_generated_466_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94457if((retVal = function_namespace0_generated_465_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94458if((retVal = function_namespace0_generated_464_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94459if((retVal = function_namespace0_generated_463_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94460if((retVal = function_namespace0_generated_462_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94461if((retVal = function_namespace0_generated_461_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94462if((retVal = function_namespace0_generated_460_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94463if((retVal = function_namespace0_generated_459_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94464if((retVal = function_namespace0_generated_458_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94465if((retVal = function_namespace0_generated_457_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94466if((retVal = function_namespace0_generated_456_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94467if((retVal = function_namespace0_generated_455_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94468if((retVal = function_namespace0_generated_454_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94469if((retVal = function_namespace0_generated_453_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94470if((retVal = function_namespace0_generated_452_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94471if((retVal = function_namespace0_generated_451_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94472if((retVal = function_namespace0_generated_450_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94473if((retVal = function_namespace0_generated_449_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94474if((retVal = function_namespace0_generated_448_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94475if((retVal = function_namespace0_generated_447_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94476if((retVal = function_namespace0_generated_446_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94477if((retVal = function_namespace0_generated_445_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94478if((retVal = function_namespace0_generated_444_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94479if((retVal = function_namespace0_generated_443_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94480if((retVal = function_namespace0_generated_442_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94481if((retVal = function_namespace0_generated_441_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94482if((retVal = function_namespace0_generated_440_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94483if((retVal = function_namespace0_generated_439_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94484if((retVal = function_namespace0_generated_438_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94485if((retVal = function_namespace0_generated_437_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94486if((retVal = function_namespace0_generated_436_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94487if((retVal = function_namespace0_generated_435_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94488if((retVal = function_namespace0_generated_434_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94489if((retVal = function_namespace0_generated_433_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94490if((retVal = function_namespace0_generated_432_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94491if((retVal = function_namespace0_generated_431_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94492if((retVal = function_namespace0_generated_430_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94493if((retVal = function_namespace0_generated_429_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94494if((retVal = function_namespace0_generated_428_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94495if((retVal = function_namespace0_generated_427_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94496if((retVal = function_namespace0_generated_426_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94497if((retVal = function_namespace0_generated_425_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94498if((retVal = function_namespace0_generated_424_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94499if((retVal = function_namespace0_generated_423_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94500if((retVal = function_namespace0_generated_422_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94501if((retVal = function_namespace0_generated_421_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94502if((retVal = function_namespace0_generated_420_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94503if((retVal = function_namespace0_generated_419_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94504if((retVal = function_namespace0_generated_418_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94505if((retVal = function_namespace0_generated_417_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94506if((retVal = function_namespace0_generated_416_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94507if((retVal = function_namespace0_generated_415_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94508if((retVal = function_namespace0_generated_414_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94509if((retVal = function_namespace0_generated_413_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94510if((retVal = function_namespace0_generated_412_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94511if((retVal = function_namespace0_generated_411_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94512if((retVal = function_namespace0_generated_410_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94513if((retVal = function_namespace0_generated_409_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94514if((retVal = function_namespace0_generated_408_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94515if((retVal = function_namespace0_generated_407_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94516if((retVal = function_namespace0_generated_406_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94517if((retVal = function_namespace0_generated_405_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94518if((retVal = function_namespace0_generated_404_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94519if((retVal = function_namespace0_generated_403_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94520if((retVal = function_namespace0_generated_402_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94521if((retVal = function_namespace0_generated_401_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94522if((retVal = function_namespace0_generated_400_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94523if((retVal = function_namespace0_generated_399_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94524if((retVal = function_namespace0_generated_398_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94525if((retVal = function_namespace0_generated_397_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94526if((retVal = function_namespace0_generated_396_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94527if((retVal = function_namespace0_generated_395_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94528if((retVal = function_namespace0_generated_394_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94529if((retVal = function_namespace0_generated_393_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94530if((retVal = function_namespace0_generated_392_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94531if((retVal = function_namespace0_generated_391_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94532if((retVal = function_namespace0_generated_390_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94533if((retVal = function_namespace0_generated_389_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94534if((retVal = function_namespace0_generated_388_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94535if((retVal = function_namespace0_generated_387_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94536if((retVal = function_namespace0_generated_386_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94537if((retVal = function_namespace0_generated_385_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94538if((retVal = function_namespace0_generated_384_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94539if((retVal = function_namespace0_generated_383_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94540if((retVal = function_namespace0_generated_382_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94541if((retVal = function_namespace0_generated_381_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94542if((retVal = function_namespace0_generated_380_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94543if((retVal = function_namespace0_generated_379_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94544if((retVal = function_namespace0_generated_378_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94545if((retVal = function_namespace0_generated_377_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94546if((retVal = function_namespace0_generated_376_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94547if((retVal = function_namespace0_generated_375_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94548if((retVal = function_namespace0_generated_374_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94549if((retVal = function_namespace0_generated_373_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94550if((retVal = function_namespace0_generated_372_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94551if((retVal = function_namespace0_generated_371_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94552if((retVal = function_namespace0_generated_370_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94553if((retVal = function_namespace0_generated_369_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94554if((retVal = function_namespace0_generated_368_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94555if((retVal = function_namespace0_generated_367_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94556if((retVal = function_namespace0_generated_366_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94557if((retVal = function_namespace0_generated_365_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94558if((retVal = function_namespace0_generated_364_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94559if((retVal = function_namespace0_generated_363_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94560if((retVal = function_namespace0_generated_362_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94561if((retVal = function_namespace0_generated_361_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94562if((retVal = function_namespace0_generated_360_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94563if((retVal = function_namespace0_generated_359_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94564if((retVal = function_namespace0_generated_358_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94565if((retVal = function_namespace0_generated_357_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94566if((retVal = function_namespace0_generated_356_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94567if((retVal = function_namespace0_generated_355_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94568if((retVal = function_namespace0_generated_354_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94569if((retVal = function_namespace0_generated_353_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94570if((retVal = function_namespace0_generated_352_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94571if((retVal = function_namespace0_generated_351_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94572if((retVal = function_namespace0_generated_350_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94573if((retVal = function_namespace0_generated_349_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94574if((retVal = function_namespace0_generated_348_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94575if((retVal = function_namespace0_generated_347_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94576if((retVal = function_namespace0_generated_346_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94577if((retVal = function_namespace0_generated_345_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94578if((retVal = function_namespace0_generated_344_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94579if((retVal = function_namespace0_generated_343_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94580if((retVal = function_namespace0_generated_342_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94581if((retVal = function_namespace0_generated_341_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94582if((retVal = function_namespace0_generated_340_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94583if((retVal = function_namespace0_generated_339_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94584if((retVal = function_namespace0_generated_338_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94585if((retVal = function_namespace0_generated_337_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94586if((retVal = function_namespace0_generated_336_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94587if((retVal = function_namespace0_generated_335_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94588if((retVal = function_namespace0_generated_334_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94589if((retVal = function_namespace0_generated_333_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94590if((retVal = function_namespace0_generated_332_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94591if((retVal = function_namespace0_generated_331_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94592if((retVal = function_namespace0_generated_330_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94593if((retVal = function_namespace0_generated_329_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94594if((retVal = function_namespace0_generated_328_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94595if((retVal = function_namespace0_generated_327_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94596if((retVal = function_namespace0_generated_326_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94597if((retVal = function_namespace0_generated_325_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94598if((retVal = function_namespace0_generated_324_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94599if((retVal = function_namespace0_generated_323_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94600if((retVal = function_namespace0_generated_322_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94601if((retVal = function_namespace0_generated_321_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94602if((retVal = function_namespace0_generated_320_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94603if((retVal = function_namespace0_generated_319_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94604if((retVal = function_namespace0_generated_318_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94605if((retVal = function_namespace0_generated_317_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94606if((retVal = function_namespace0_generated_316_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94607if((retVal = function_namespace0_generated_315_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94608if((retVal = function_namespace0_generated_314_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94609if((retVal = function_namespace0_generated_313_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94610if((retVal = function_namespace0_generated_312_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94611if((retVal = function_namespace0_generated_311_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94612if((retVal = function_namespace0_generated_310_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94613if((retVal = function_namespace0_generated_309_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94614if((retVal = function_namespace0_generated_308_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94615if((retVal = function_namespace0_generated_307_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94616if((retVal = function_namespace0_generated_306_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94617if((retVal = function_namespace0_generated_305_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94618if((retVal = function_namespace0_generated_304_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94619if((retVal = function_namespace0_generated_303_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94620if((retVal = function_namespace0_generated_302_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94621if((retVal = function_namespace0_generated_301_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94622if((retVal = function_namespace0_generated_300_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94623if((retVal = function_namespace0_generated_299_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94624if((retVal = function_namespace0_generated_298_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94625if((retVal = function_namespace0_generated_297_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94626if((retVal = function_namespace0_generated_296_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94627if((retVal = function_namespace0_generated_295_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94628if((retVal = function_namespace0_generated_294_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94629if((retVal = function_namespace0_generated_293_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94630if((retVal = function_namespace0_generated_292_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94631if((retVal = function_namespace0_generated_291_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94632if((retVal = function_namespace0_generated_290_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94633if((retVal = function_namespace0_generated_289_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94634if((retVal = function_namespace0_generated_288_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94635if((retVal = function_namespace0_generated_287_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94636if((retVal = function_namespace0_generated_286_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94637if((retVal = function_namespace0_generated_285_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94638if((retVal = function_namespace0_generated_284_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94639if((retVal = function_namespace0_generated_283_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94640if((retVal = function_namespace0_generated_282_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94641if((retVal = function_namespace0_generated_281_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94642if((retVal = function_namespace0_generated_280_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94643if((retVal = function_namespace0_generated_279_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94644if((retVal = function_namespace0_generated_278_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94645if((retVal = function_namespace0_generated_277_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94646if((retVal = function_namespace0_generated_276_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94647if((retVal = function_namespace0_generated_275_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94648if((retVal = function_namespace0_generated_274_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94649if((retVal = function_namespace0_generated_273_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94650if((retVal = function_namespace0_generated_272_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94651if((retVal = function_namespace0_generated_271_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94652if((retVal = function_namespace0_generated_270_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94653if((retVal = function_namespace0_generated_269_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94654if((retVal = function_namespace0_generated_268_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94655if((retVal = function_namespace0_generated_267_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94656if((retVal = function_namespace0_generated_266_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94657if((retVal = function_namespace0_generated_265_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94658if((retVal = function_namespace0_generated_264_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94659if((retVal = function_namespace0_generated_263_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94660if((retVal = function_namespace0_generated_262_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94661if((retVal = function_namespace0_generated_261_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94662if((retVal = function_namespace0_generated_260_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94663if((retVal = function_namespace0_generated_259_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94664if((retVal = function_namespace0_generated_258_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94665if((retVal = function_namespace0_generated_257_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94666if((retVal = function_namespace0_generated_256_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94667if((retVal = function_namespace0_generated_255_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94668if((retVal = function_namespace0_generated_254_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94669if((retVal = function_namespace0_generated_253_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94670if((retVal = function_namespace0_generated_252_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94671if((retVal = function_namespace0_generated_251_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94672if((retVal = function_namespace0_generated_250_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94673if((retVal = function_namespace0_generated_249_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94674if((retVal = function_namespace0_generated_248_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94675if((retVal = function_namespace0_generated_247_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94676if((retVal = function_namespace0_generated_246_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94677if((retVal = function_namespace0_generated_245_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94678if((retVal = function_namespace0_generated_244_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94679if((retVal = function_namespace0_generated_243_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94680if((retVal = function_namespace0_generated_242_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94681if((retVal = function_namespace0_generated_241_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94682if((retVal = function_namespace0_generated_240_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94683if((retVal = function_namespace0_generated_239_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94684if((retVal = function_namespace0_generated_238_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94685if((retVal = function_namespace0_generated_237_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94686if((retVal = function_namespace0_generated_236_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94687if((retVal = function_namespace0_generated_235_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94688if((retVal = function_namespace0_generated_234_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94689if((retVal = function_namespace0_generated_233_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94690if((retVal = function_namespace0_generated_232_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94691if((retVal = function_namespace0_generated_231_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94692if((retVal = function_namespace0_generated_230_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94693if((retVal = function_namespace0_generated_229_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94694if((retVal = function_namespace0_generated_228_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94695if((retVal = function_namespace0_generated_227_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94696if((retVal = function_namespace0_generated_226_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94697if((retVal = function_namespace0_generated_225_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94698if((retVal = function_namespace0_generated_224_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94699if((retVal = function_namespace0_generated_223_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94700if((retVal = function_namespace0_generated_222_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94701if((retVal = function_namespace0_generated_221_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94702if((retVal = function_namespace0_generated_220_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94703if((retVal = function_namespace0_generated_219_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94704if((retVal = function_namespace0_generated_218_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94705if((retVal = function_namespace0_generated_217_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94706if((retVal = function_namespace0_generated_216_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94707if((retVal = function_namespace0_generated_215_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94708if((retVal = function_namespace0_generated_214_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94709if((retVal = function_namespace0_generated_213_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94710if((retVal = function_namespace0_generated_212_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94711if((retVal = function_namespace0_generated_211_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94712if((retVal = function_namespace0_generated_210_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94713if((retVal = function_namespace0_generated_209_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94714if((retVal = function_namespace0_generated_208_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94715if((retVal = function_namespace0_generated_207_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94716if((retVal = function_namespace0_generated_206_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94717if((retVal = function_namespace0_generated_205_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94718if((retVal = function_namespace0_generated_204_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94719if((retVal = function_namespace0_generated_203_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94720if((retVal = function_namespace0_generated_202_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94721if((retVal = function_namespace0_generated_201_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94722if((retVal = function_namespace0_generated_200_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94723if((retVal = function_namespace0_generated_199_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94724if((retVal = function_namespace0_generated_198_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94725if((retVal = function_namespace0_generated_197_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94726if((retVal = function_namespace0_generated_196_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94727if((retVal = function_namespace0_generated_195_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94728if((retVal = function_namespace0_generated_194_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94729if((retVal = function_namespace0_generated_193_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94730if((retVal = function_namespace0_generated_192_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94731if((retVal = function_namespace0_generated_191_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94732if((retVal = function_namespace0_generated_190_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94733if((retVal = function_namespace0_generated_189_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94734if((retVal = function_namespace0_generated_188_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94735if((retVal = function_namespace0_generated_187_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94736if((retVal = function_namespace0_generated_186_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94737if((retVal = function_namespace0_generated_185_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94738if((retVal = function_namespace0_generated_184_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94739if((retVal = function_namespace0_generated_183_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94740if((retVal = function_namespace0_generated_182_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94741if((retVal = function_namespace0_generated_181_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94742if((retVal = function_namespace0_generated_180_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94743if((retVal = function_namespace0_generated_179_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94744if((retVal = function_namespace0_generated_178_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94745if((retVal = function_namespace0_generated_177_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94746if((retVal = function_namespace0_generated_176_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94747if((retVal = function_namespace0_generated_175_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94748if((retVal = function_namespace0_generated_174_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94749if((retVal = function_namespace0_generated_173_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94750if((retVal = function_namespace0_generated_172_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94751if((retVal = function_namespace0_generated_171_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94752if((retVal = function_namespace0_generated_170_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94753if((retVal = function_namespace0_generated_169_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94754if((retVal = function_namespace0_generated_168_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94755if((retVal = function_namespace0_generated_167_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94756if((retVal = function_namespace0_generated_166_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94757if((retVal = function_namespace0_generated_165_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94758if((retVal = function_namespace0_generated_164_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94759if((retVal = function_namespace0_generated_163_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94760if((retVal = function_namespace0_generated_162_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94761if((retVal = function_namespace0_generated_161_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94762if((retVal = function_namespace0_generated_160_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94763if((retVal = function_namespace0_generated_159_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94764if((retVal = function_namespace0_generated_158_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94765if((retVal = function_namespace0_generated_157_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94766if((retVal = function_namespace0_generated_156_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94767if((retVal = function_namespace0_generated_155_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94768if((retVal = function_namespace0_generated_154_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94769if((retVal = function_namespace0_generated_153_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94770if((retVal = function_namespace0_generated_152_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94771if((retVal = function_namespace0_generated_151_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94772if((retVal = function_namespace0_generated_150_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94773if((retVal = function_namespace0_generated_149_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94774if((retVal = function_namespace0_generated_148_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94775if((retVal = function_namespace0_generated_147_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94776if((retVal = function_namespace0_generated_146_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94777if((retVal = function_namespace0_generated_145_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94778if((retVal = function_namespace0_generated_144_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94779if((retVal = function_namespace0_generated_143_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94780if((retVal = function_namespace0_generated_142_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94781if((retVal = function_namespace0_generated_141_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94782if((retVal = function_namespace0_generated_140_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94783if((retVal = function_namespace0_generated_139_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94784if((retVal = function_namespace0_generated_138_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94785if((retVal = function_namespace0_generated_137_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94786if((retVal = function_namespace0_generated_136_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94787if((retVal = function_namespace0_generated_135_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94788if((retVal = function_namespace0_generated_134_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94789if((retVal = function_namespace0_generated_133_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94790if((retVal = function_namespace0_generated_132_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94791if((retVal = function_namespace0_generated_131_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94792if((retVal = function_namespace0_generated_130_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94793if((retVal = function_namespace0_generated_129_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94794if((retVal = function_namespace0_generated_128_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94795if((retVal = function_namespace0_generated_127_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94796if((retVal = function_namespace0_generated_126_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94797if((retVal = function_namespace0_generated_125_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94798if((retVal = function_namespace0_generated_124_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94799if((retVal = function_namespace0_generated_123_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94800if((retVal = function_namespace0_generated_122_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94801if((retVal = function_namespace0_generated_121_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94802if((retVal = function_namespace0_generated_120_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94803if((retVal = function_namespace0_generated_119_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94804if((retVal = function_namespace0_generated_118_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94805if((retVal = function_namespace0_generated_117_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94806if((retVal = function_namespace0_generated_116_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94807if((retVal = function_namespace0_generated_115_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94808if((retVal = function_namespace0_generated_114_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94809if((retVal = function_namespace0_generated_113_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94810if((retVal = function_namespace0_generated_112_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94811if((retVal = function_namespace0_generated_111_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94812if((retVal = function_namespace0_generated_110_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94813if((retVal = function_namespace0_generated_109_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94814if((retVal = function_namespace0_generated_108_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94815if((retVal = function_namespace0_generated_107_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94816if((retVal = function_namespace0_generated_106_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94817if((retVal = function_namespace0_generated_105_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94818if((retVal = function_namespace0_generated_104_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94819if((retVal = function_namespace0_generated_103_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94820if((retVal = function_namespace0_generated_102_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94821if((retVal = function_namespace0_generated_101_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94822if((retVal = function_namespace0_generated_100_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94823if((retVal = function_namespace0_generated_99_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94824if((retVal = function_namespace0_generated_98_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94825if((retVal = function_namespace0_generated_97_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94826if((retVal = function_namespace0_generated_96_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94827if((retVal = function_namespace0_generated_95_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94828if((retVal = function_namespace0_generated_94_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94829if((retVal = function_namespace0_generated_93_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94830if((retVal = function_namespace0_generated_92_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94831if((retVal = function_namespace0_generated_91_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94832if((retVal = function_namespace0_generated_90_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94833if((retVal = function_namespace0_generated_89_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94834if((retVal = function_namespace0_generated_88_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94835if((retVal = function_namespace0_generated_87_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94836if((retVal = function_namespace0_generated_86_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94837if((retVal = function_namespace0_generated_85_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94838if((retVal = function_namespace0_generated_84_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94839if((retVal = function_namespace0_generated_83_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94840if((retVal = function_namespace0_generated_82_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94841if((retVal = function_namespace0_generated_81_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94842if((retVal = function_namespace0_generated_80_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94843if((retVal = function_namespace0_generated_79_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94844if((retVal = function_namespace0_generated_78_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94845if((retVal = function_namespace0_generated_77_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94846if((retVal = function_namespace0_generated_76_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94847if((retVal = function_namespace0_generated_75_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94848if((retVal = function_namespace0_generated_74_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94849if((retVal = function_namespace0_generated_73_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94850if((retVal = function_namespace0_generated_72_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94851if((retVal = function_namespace0_generated_71_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94852if((retVal = function_namespace0_generated_70_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94853if((retVal = function_namespace0_generated_69_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94854if((retVal = function_namespace0_generated_68_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94855if((retVal = function_namespace0_generated_67_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94856if((retVal = function_namespace0_generated_66_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94857if((retVal = function_namespace0_generated_65_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94858if((retVal = function_namespace0_generated_64_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94859if((retVal = function_namespace0_generated_63_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94860if((retVal = function_namespace0_generated_62_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94861if((retVal = function_namespace0_generated_61_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94862if((retVal = function_namespace0_generated_60_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94863if((retVal = function_namespace0_generated_59_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94864if((retVal = function_namespace0_generated_58_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94865if((retVal = function_namespace0_generated_57_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94866if((retVal = function_namespace0_generated_56_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94867if((retVal = function_namespace0_generated_55_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94868if((retVal = function_namespace0_generated_54_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94869if((retVal = function_namespace0_generated_53_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94870if((retVal = function_namespace0_generated_52_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94871if((retVal = function_namespace0_generated_51_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94872if((retVal = function_namespace0_generated_50_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94873if((retVal = function_namespace0_generated_49_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94874if((retVal = function_namespace0_generated_48_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94875if((retVal = function_namespace0_generated_47_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94876if((retVal = function_namespace0_generated_46_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94877if((retVal = function_namespace0_generated_45_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94878if((retVal = function_namespace0_generated_44_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94879if((retVal = function_namespace0_generated_43_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94880if((retVal = function_namespace0_generated_42_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94881if((retVal = function_namespace0_generated_41_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94882if((retVal = function_namespace0_generated_40_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94883if((retVal = function_namespace0_generated_39_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94884if((retVal = function_namespace0_generated_38_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94885if((retVal = function_namespace0_generated_37_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94886if((retVal = function_namespace0_generated_36_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94887if((retVal = function_namespace0_generated_35_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94888if((retVal = function_namespace0_generated_34_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94889if((retVal = function_namespace0_generated_33_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94890if((retVal = function_namespace0_generated_32_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94891if((retVal = function_namespace0_generated_31_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94892if((retVal = function_namespace0_generated_30_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94893if((retVal = function_namespace0_generated_29_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94894if((retVal = function_namespace0_generated_28_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94895if((retVal = function_namespace0_generated_27_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94896if((retVal = function_namespace0_generated_26_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94897if((retVal = function_namespace0_generated_25_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94898if((retVal = function_namespace0_generated_24_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94899if((retVal = function_namespace0_generated_23_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94900if((retVal = function_namespace0_generated_22_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94901if((retVal = function_namespace0_generated_21_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94902if((retVal = function_namespace0_generated_20_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94903if((retVal = function_namespace0_generated_19_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94904if((retVal = function_namespace0_generated_18_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94905if((retVal = function_namespace0_generated_17_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94906if((retVal = function_namespace0_generated_16_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94907if((retVal = function_namespace0_generated_15_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94908if((retVal = function_namespace0_generated_14_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94909if((retVal = function_namespace0_generated_13_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94910if((retVal = function_namespace0_generated_12_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94911if((retVal = function_namespace0_generated_11_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;
94912return retVal;
94913}
94914
94915/**** amalgamated original file "/src/ua_types_lex.c" ****/
94916
94917/* Generated by re2c 3.1 */
94918/* This Source Code Form is subject to the terms of the Mozilla Public
94919 * License, v. 2.0. If a copy of the MPL was not distributed with this
94920 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
94921 *
94922 * Copyright 2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
94923 *
94924 */
94925
94926
94927/* Lexing and parsing of builtin data types. These are helper functions that not
94928 * required by the SDK internally. But they are useful for users who want to use
94929 * standard-specified humand readable encodings for NodeIds, etc.
94930 *
94931 * This compilation unit uses the re2c lexer generator. The final C source is
94932 * generated with the following script:
94933 *
94934 * re2c -i --no-generation-date ua_types_lex.re > ua_types_lex.c
94935 *
94936 * In order that users of the SDK don't need to install re2c, always commit a
94937 * recent ua_types_lex.c if changes are made to the lexer. */
94938
94939#define YYCURSOR pos
94940#define YYMARKER context.marker
94941#define YYPEEK() (YYCURSOR < end) ? *YYCURSOR : 0 /* The lexer sees a stream of
94942 * \0 when the input ends*/
94943#define YYSKIP() ++YYCURSOR;
94944#define YYBACKUP() YYMARKER = YYCURSOR
94945#define YYRESTORE() YYCURSOR = YYMARKER
94946#define YYSTAGP(t) t = YYCURSOR
94947#define YYSTAGN(t) t = NULL
94948#define YYSHIFTSTAG(t, shift) t += shift
94949
94950typedef struct {
94951 const char *marker;
94952 const char *yyt1;const char *yyt2;const char *yyt3;const char *yyt4;
94953} LexContext;
94954
94955
94956
94957static UA_StatusCode
94958parse_guid(UA_Guid *guid, const UA_Byte *s, const UA_Byte *e) {
94959 size_t len = (size_t)(e - s);
94960 if(len != 36 || s[8] != '-' || s[13] != '-' || s[23] != '-')
94961 return UA_STATUSCODE_BADDECODINGERROR;
94962
94963 UA_UInt32 tmp;
94964 if(UA_readNumberWithBase(buf: s, buflen: 8, number: &tmp, base: 16) != 8)
94965 return UA_STATUSCODE_BADDECODINGERROR;
94966 guid->data1 = tmp;
94967
94968 if(UA_readNumberWithBase(buf: &s[9], buflen: 4, number: &tmp, base: 16) != 4)
94969 return UA_STATUSCODE_BADDECODINGERROR;
94970 guid->data2 = (UA_UInt16)tmp;
94971
94972 if(UA_readNumberWithBase(buf: &s[14], buflen: 4, number: &tmp, base: 16) != 4)
94973 return UA_STATUSCODE_BADDECODINGERROR;
94974 guid->data3 = (UA_UInt16)tmp;
94975
94976 if(UA_readNumberWithBase(buf: &s[19], buflen: 2, number: &tmp, base: 16) != 2)
94977 return UA_STATUSCODE_BADDECODINGERROR;
94978 guid->data4[0] = (UA_Byte)tmp;
94979
94980 if(UA_readNumberWithBase(buf: &s[21], buflen: 2, number: &tmp, base: 16) != 2)
94981 return UA_STATUSCODE_BADDECODINGERROR;
94982 guid->data4[1] = (UA_Byte)tmp;
94983
94984 for(size_t pos = 2, spos = 24; pos < 8; pos++, spos += 2) {
94985 if(UA_readNumberWithBase(buf: &s[spos], buflen: 2, number: &tmp, base: 16) != 2)
94986 return UA_STATUSCODE_BADDECODINGERROR;
94987 guid->data4[pos] = (UA_Byte)tmp;
94988 }
94989
94990 return UA_STATUSCODE_GOOD;
94991}
94992
94993UA_StatusCode
94994UA_Guid_parse(UA_Guid *guid, const UA_String str) {
94995 UA_StatusCode res = parse_guid(guid, s: str.data, e: str.data + str.length);
94996 if(res != UA_STATUSCODE_GOOD)
94997 *guid = UA_GUID_NULL;
94998 return res;
94999}
95000
95001static UA_StatusCode
95002parse_nodeid_body(UA_NodeId *id, const char *body, const char *end) {
95003 size_t len = (size_t)(end - (body+2));
95004 UA_StatusCode res = UA_STATUSCODE_GOOD;
95005 switch(*body) {
95006 case 'i': {
95007 if(UA_readNumber(buf: (const UA_Byte*)body+2, buflen: len, number: &id->identifier.numeric) != len)
95008 return UA_STATUSCODE_BADDECODINGERROR;
95009 id->identifierType = UA_NODEIDTYPE_NUMERIC;
95010 break;
95011 }
95012 case 's': {
95013 UA_String tmpstr;
95014 tmpstr.data = (UA_Byte*)(uintptr_t)body+2;
95015 tmpstr.length = len;
95016 res = UA_String_copy(src: &tmpstr, dst: &id->identifier.string);
95017 if(res != UA_STATUSCODE_GOOD)
95018 break;
95019 id->identifierType = UA_NODEIDTYPE_STRING;
95020 break;
95021 }
95022 case 'g':
95023 res = parse_guid(guid: &id->identifier.guid, s: (const UA_Byte*)body+2, e: (const UA_Byte*)end);
95024 if(res == UA_STATUSCODE_GOOD)
95025 id->identifierType = UA_NODEIDTYPE_GUID;
95026 break;
95027 case 'b':
95028 id->identifier.byteString.data =
95029 UA_unbase64(src: (const unsigned char*)body+2, len,
95030 out_len: &id->identifier.byteString.length);
95031 if(!id->identifier.byteString.data && len > 0)
95032 return UA_STATUSCODE_BADDECODINGERROR;
95033 id->identifierType = UA_NODEIDTYPE_BYTESTRING;
95034 break;
95035 default:
95036 return UA_STATUSCODE_BADDECODINGERROR;
95037 }
95038 return res;
95039}
95040
95041static UA_StatusCode
95042parse_nodeid(UA_NodeId *id, const char *pos, const char *end) {
95043 *id = UA_NODEID_NULL; /* Reset the NodeId */
95044 LexContext context;
95045 memset(s: &context, c: 0, n: sizeof(LexContext));
95046 const char *ns = NULL, *nse= NULL;
95047
95048
95049{
95050 char yych;
95051 yych = YYPEEK();
95052 switch (yych) {
95053 case 'b':
95054 case 'g':
95055 case 'i':
95056 case 's':
95057 YYSTAGN(context.yyt1);
95058 YYSTAGN(context.yyt2);
95059 goto yy3;
95060 case 'n': goto yy4;
95061 default: goto yy1;
95062 }
95063yy1:
95064 YYSKIP();
95065yy2:
95066 { (void)pos; return UA_STATUSCODE_BADDECODINGERROR; }
95067yy3:
95068 YYSKIP();
95069 yych = YYPEEK();
95070 switch (yych) {
95071 case '=': goto yy5;
95072 default: goto yy2;
95073 }
95074yy4:
95075 YYSKIP();
95076 YYBACKUP();
95077 yych = YYPEEK();
95078 switch (yych) {
95079 case 's': goto yy6;
95080 default: goto yy2;
95081 }
95082yy5:
95083 YYSKIP();
95084 ns = context.yyt1;
95085 nse = context.yyt2;
95086 {
95087 (void)pos; // Get rid of a dead store clang-analyzer warning
95088 if(ns) {
95089 UA_UInt32 tmp;
95090 size_t len = (size_t)(nse - ns);
95091 if(UA_readNumber(buf: (const UA_Byte*)ns, buflen: len, number: &tmp) != len)
95092 return UA_STATUSCODE_BADDECODINGERROR;
95093 id->namespaceIndex = (UA_UInt16)tmp;
95094 }
95095
95096 // From the current position until the end
95097 return parse_nodeid_body(id, body: &pos[-2], end);
95098 }
95099yy6:
95100 YYSKIP();
95101 yych = YYPEEK();
95102 switch (yych) {
95103 case '=': goto yy8;
95104 default: goto yy7;
95105 }
95106yy7:
95107 YYRESTORE();
95108 goto yy2;
95109yy8:
95110 YYSKIP();
95111 yych = YYPEEK();
95112 switch (yych) {
95113 case '0':
95114 case '1':
95115 case '2':
95116 case '3':
95117 case '4':
95118 case '5':
95119 case '6':
95120 case '7':
95121 case '8':
95122 case '9':
95123 YYSTAGP(context.yyt1);
95124 goto yy9;
95125 default: goto yy7;
95126 }
95127yy9:
95128 YYSKIP();
95129 yych = YYPEEK();
95130 switch (yych) {
95131 case '0':
95132 case '1':
95133 case '2':
95134 case '3':
95135 case '4':
95136 case '5':
95137 case '6':
95138 case '7':
95139 case '8':
95140 case '9': goto yy9;
95141 case ';':
95142 YYSTAGP(context.yyt2);
95143 goto yy10;
95144 default: goto yy7;
95145 }
95146yy10:
95147 YYSKIP();
95148 yych = YYPEEK();
95149 switch (yych) {
95150 case 'b':
95151 case 'g':
95152 case 'i':
95153 case 's': goto yy11;
95154 default: goto yy7;
95155 }
95156yy11:
95157 YYSKIP();
95158 yych = YYPEEK();
95159 switch (yych) {
95160 case '=': goto yy5;
95161 default: goto yy7;
95162 }
95163}
95164
95165}
95166
95167UA_StatusCode
95168UA_NodeId_parse(UA_NodeId *id, const UA_String str) {
95169 UA_StatusCode res =
95170 parse_nodeid(id, pos: (const char*)str.data, end: (const char*)str.data+str.length);
95171 if(res != UA_STATUSCODE_GOOD)
95172 UA_NodeId_clear(p: id);
95173 return res;
95174}
95175
95176static UA_StatusCode
95177parse_expandednodeid(UA_ExpandedNodeId *id, const char *pos, const char *end) {
95178 *id = UA_EXPANDEDNODEID_NULL; /* Reset the NodeId */
95179 LexContext context;
95180 memset(s: &context, c: 0, n: sizeof(LexContext));
95181 const char *svr = NULL, *svre = NULL, *nsu = NULL, *ns = NULL, *body = NULL;
95182
95183
95184{
95185 char yych;
95186 yych = YYPEEK();
95187 switch (yych) {
95188 case 'b':
95189 case 'g':
95190 case 'i':
95191 YYSTAGN(context.yyt1);
95192 YYSTAGN(context.yyt2);
95193 YYSTAGN(context.yyt3);
95194 YYSTAGN(context.yyt4);
95195 goto yy15;
95196 case 'n':
95197 YYSTAGN(context.yyt1);
95198 YYSTAGN(context.yyt2);
95199 goto yy16;
95200 case 's':
95201 YYSTAGN(context.yyt1);
95202 YYSTAGN(context.yyt2);
95203 YYSTAGN(context.yyt3);
95204 YYSTAGN(context.yyt4);
95205 goto yy17;
95206 default: goto yy13;
95207 }
95208yy13:
95209 YYSKIP();
95210yy14:
95211 { (void)pos; return UA_STATUSCODE_BADDECODINGERROR; }
95212yy15:
95213 YYSKIP();
95214 yych = YYPEEK();
95215 switch (yych) {
95216 case '=': goto yy18;
95217 default: goto yy14;
95218 }
95219yy16:
95220 YYSKIP();
95221 YYBACKUP();
95222 yych = YYPEEK();
95223 switch (yych) {
95224 case 's': goto yy19;
95225 default: goto yy14;
95226 }
95227yy17:
95228 YYSKIP();
95229 YYBACKUP();
95230 yych = YYPEEK();
95231 switch (yych) {
95232 case '=': goto yy18;
95233 case 'v': goto yy21;
95234 default: goto yy14;
95235 }
95236yy18:
95237 YYSKIP();
95238 svr = context.yyt1;
95239 svre = context.yyt2;
95240 ns = context.yyt3;
95241 nsu = context.yyt4;
95242 YYSTAGP(body);
95243 YYSHIFTSTAG(body, -2);
95244 {
95245 (void)pos; // Get rid of a dead store clang-analyzer warning
95246 if(svr) {
95247 size_t len = (size_t)((svre) - svr);
95248 if(UA_readNumber(buf: (const UA_Byte*)svr, buflen: len, number: &id->serverIndex) != len)
95249 return UA_STATUSCODE_BADDECODINGERROR;
95250 }
95251
95252 if(nsu) {
95253 size_t len = (size_t)((body-1) - nsu);
95254 UA_String nsuri;
95255 nsuri.data = (UA_Byte*)(uintptr_t)nsu;
95256 nsuri.length = len;
95257 UA_StatusCode res = UA_String_copy(src: &nsuri, dst: &id->namespaceUri);
95258 if(res != UA_STATUSCODE_GOOD)
95259 return res;
95260 } else if(ns) {
95261 UA_UInt32 tmp;
95262 size_t len = (size_t)((body-1) - ns);
95263 if(UA_readNumber(buf: (const UA_Byte*)ns, buflen: len, number: &tmp) != len)
95264 return UA_STATUSCODE_BADDECODINGERROR;
95265 id->nodeId.namespaceIndex = (UA_UInt16)tmp;
95266 }
95267
95268 // From the current position until the end
95269 return parse_nodeid_body(id: &id->nodeId, body: &pos[-2], end);
95270 }
95271yy19:
95272 YYSKIP();
95273 yych = YYPEEK();
95274 switch (yych) {
95275 case '=': goto yy22;
95276 case 'u': goto yy23;
95277 default: goto yy20;
95278 }
95279yy20:
95280 YYRESTORE();
95281 goto yy14;
95282yy21:
95283 YYSKIP();
95284 yych = YYPEEK();
95285 switch (yych) {
95286 case 'r': goto yy24;
95287 default: goto yy20;
95288 }
95289yy22:
95290 YYSKIP();
95291 yych = YYPEEK();
95292 switch (yych) {
95293 case '0':
95294 case '1':
95295 case '2':
95296 case '3':
95297 case '4':
95298 case '5':
95299 case '6':
95300 case '7':
95301 case '8':
95302 case '9':
95303 YYSTAGP(context.yyt3);
95304 goto yy25;
95305 default: goto yy20;
95306 }
95307yy23:
95308 YYSKIP();
95309 yych = YYPEEK();
95310 switch (yych) {
95311 case '=': goto yy26;
95312 default: goto yy20;
95313 }
95314yy24:
95315 YYSKIP();
95316 yych = YYPEEK();
95317 switch (yych) {
95318 case '=': goto yy27;
95319 default: goto yy20;
95320 }
95321yy25:
95322 YYSKIP();
95323 yych = YYPEEK();
95324 switch (yych) {
95325 case '0':
95326 case '1':
95327 case '2':
95328 case '3':
95329 case '4':
95330 case '5':
95331 case '6':
95332 case '7':
95333 case '8':
95334 case '9': goto yy25;
95335 case ';': goto yy28;
95336 default: goto yy20;
95337 }
95338yy26:
95339 YYSKIP();
95340 yych = YYPEEK();
95341 switch (yych) {
95342 case 0x00:
95343 case '\n': goto yy20;
95344 case ';':
95345 YYSTAGP(context.yyt4);
95346 goto yy30;
95347 default:
95348 YYSTAGP(context.yyt4);
95349 goto yy29;
95350 }
95351yy27:
95352 YYSKIP();
95353 yych = YYPEEK();
95354 switch (yych) {
95355 case '0':
95356 case '1':
95357 case '2':
95358 case '3':
95359 case '4':
95360 case '5':
95361 case '6':
95362 case '7':
95363 case '8':
95364 case '9':
95365 YYSTAGP(context.yyt1);
95366 goto yy31;
95367 default: goto yy20;
95368 }
95369yy28:
95370 YYSKIP();
95371 yych = YYPEEK();
95372 switch (yych) {
95373 case 'b':
95374 case 'g':
95375 case 'i':
95376 case 's':
95377 YYSTAGN(context.yyt4);
95378 goto yy32;
95379 default: goto yy20;
95380 }
95381yy29:
95382 YYSKIP();
95383 yych = YYPEEK();
95384 switch (yych) {
95385 case 0x00:
95386 case '\n': goto yy20;
95387 case ';': goto yy30;
95388 default: goto yy29;
95389 }
95390yy30:
95391 YYSKIP();
95392 yych = YYPEEK();
95393 switch (yych) {
95394 case 'b':
95395 case 'g':
95396 case 'i':
95397 case 's':
95398 YYSTAGN(context.yyt3);
95399 goto yy32;
95400 default: goto yy20;
95401 }
95402yy31:
95403 YYSKIP();
95404 yych = YYPEEK();
95405 switch (yych) {
95406 case '0':
95407 case '1':
95408 case '2':
95409 case '3':
95410 case '4':
95411 case '5':
95412 case '6':
95413 case '7':
95414 case '8':
95415 case '9': goto yy31;
95416 case ';':
95417 YYSTAGP(context.yyt2);
95418 goto yy33;
95419 default: goto yy20;
95420 }
95421yy32:
95422 YYSKIP();
95423 yych = YYPEEK();
95424 switch (yych) {
95425 case '=': goto yy18;
95426 default: goto yy20;
95427 }
95428yy33:
95429 YYSKIP();
95430 yych = YYPEEK();
95431 switch (yych) {
95432 case 'b':
95433 case 'g':
95434 case 'i':
95435 case 's':
95436 YYSTAGN(context.yyt3);
95437 YYSTAGN(context.yyt4);
95438 goto yy32;
95439 case 'n': goto yy34;
95440 default: goto yy20;
95441 }
95442yy34:
95443 YYSKIP();
95444 yych = YYPEEK();
95445 switch (yych) {
95446 case 's': goto yy19;
95447 default: goto yy20;
95448 }
95449}
95450
95451}
95452
95453UA_StatusCode
95454UA_ExpandedNodeId_parse(UA_ExpandedNodeId *id, const UA_String str) {
95455 UA_StatusCode res =
95456 parse_expandednodeid(id, pos: (const char*)str.data, end: (const char*)str.data+str.length);
95457 if(res != UA_STATUSCODE_GOOD)
95458 UA_ExpandedNodeId_clear(p: id);
95459 return res;
95460}
95461
95462static UA_StatusCode
95463relativepath_addelem(UA_RelativePath *rp, UA_RelativePathElement *el) {
95464 /* Allocate memory */
95465 UA_RelativePathElement *newArray = (UA_RelativePathElement*)
95466 UA_realloc(ptr: rp->elements, size: sizeof(UA_RelativePathElement) * (rp->elementsSize + 1));
95467 if(!newArray)
95468 return UA_STATUSCODE_BADOUTOFMEMORY;
95469 rp->elements = newArray;
95470
95471 /* Move to the target */
95472 rp->elements[rp->elementsSize] = *el;
95473 rp->elementsSize++;
95474 return UA_STATUSCODE_GOOD;
95475}
95476
95477/* Parse name string with '&' as the escape character */
95478static UA_StatusCode
95479parse_refpath_qn_name(UA_QualifiedName *qn, const char **pos, const char *end) {
95480 /* Allocate the max length the name can have */
95481 size_t maxlen = (size_t)(end - *pos);
95482 if(maxlen == 0) {
95483 qn->name.data = (UA_Byte*)UA_EMPTY_ARRAY_SENTINEL;
95484 return UA_STATUSCODE_GOOD;
95485 }
95486 char *name = (char*)UA_malloc(size: maxlen);
95487 if(!name)
95488 return UA_STATUSCODE_BADOUTOFMEMORY;
95489
95490 size_t index = 0;
95491 for(; *pos < end; (*pos)++) {
95492 char c = **pos;
95493 /* Unescaped special characer: The end of the QualifiedName */
95494 if(c == '/' || c == '.' || c == '<' || c == '>' ||
95495 c == ':' || c == '#' || c == '!')
95496 break;
95497
95498 /* Escaped character */
95499 if(c == '&') {
95500 (*pos)++;
95501 if(*pos >= end ||
95502 (**pos != '/' && **pos != '.' && **pos != '<' && **pos != '>' &&
95503 **pos != ':' && **pos != '#' && **pos != '!' && **pos != '&')) {
95504 UA_free(ptr: name);
95505 return UA_STATUSCODE_BADDECODINGERROR;
95506 }
95507 c = **pos;
95508 }
95509
95510 /* Unescaped normal character */
95511 name[index] = c;
95512 index++;
95513 }
95514
95515 if(index > 0) {
95516 qn->name.data = (UA_Byte*)name;
95517 qn->name.length = index;
95518 } else {
95519 qn->name.data = (UA_Byte*)UA_EMPTY_ARRAY_SENTINEL;
95520 UA_free(ptr: name);
95521 }
95522 return UA_STATUSCODE_GOOD;
95523}
95524
95525static UA_StatusCode
95526parse_refpath_qn(UA_QualifiedName *qn, const char *pos, const char *end) {
95527 LexContext context;
95528 memset(s: &context, c: 0, n: sizeof(LexContext));
95529 const char *ns = NULL, *nse = NULL;
95530 UA_QualifiedName_init(p: qn);
95531
95532
95533{
95534 char yych;
95535 yych = YYPEEK();
95536 switch (yych) {
95537 case '0':
95538 case '1':
95539 case '2':
95540 case '3':
95541 case '4':
95542 case '5':
95543 case '6':
95544 case '7':
95545 case '8':
95546 case '9':
95547 YYSTAGP(context.yyt1);
95548 goto yy38;
95549 default: goto yy36;
95550 }
95551yy36:
95552 YYSKIP();
95553yy37:
95554 { pos--; goto parse_qn_name; }
95555yy38:
95556 YYSKIP();
95557 YYBACKUP();
95558 yych = YYPEEK();
95559 switch (yych) {
95560 case '0':
95561 case '1':
95562 case '2':
95563 case '3':
95564 case '4':
95565 case '5':
95566 case '6':
95567 case '7':
95568 case '8':
95569 case '9':
95570 case ':': goto yy40;
95571 default: goto yy37;
95572 }
95573yy39:
95574 YYSKIP();
95575 yych = YYPEEK();
95576yy40:
95577 switch (yych) {
95578 case '0':
95579 case '1':
95580 case '2':
95581 case '3':
95582 case '4':
95583 case '5':
95584 case '6':
95585 case '7':
95586 case '8':
95587 case '9': goto yy39;
95588 case ':': goto yy42;
95589 default: goto yy41;
95590 }
95591yy41:
95592 YYRESTORE();
95593 goto yy37;
95594yy42:
95595 YYSKIP();
95596 ns = context.yyt1;
95597 YYSTAGP(nse);
95598 YYSHIFTSTAG(nse, -1);
95599 {
95600 UA_UInt32 tmp;
95601 size_t len = (size_t)(nse - ns);
95602 if(UA_readNumber(buf: (const UA_Byte*)ns, buflen: len, number: &tmp) != len)
95603 return UA_STATUSCODE_BADDECODINGERROR;
95604 qn->namespaceIndex = (UA_UInt16)tmp;
95605 goto parse_qn_name;
95606 }
95607}
95608
95609
95610 parse_qn_name:
95611 return parse_refpath_qn_name(qn, pos: &pos, end);
95612}
95613
95614/* List of well-known ReferenceTypes that don't require lookup in the server */
95615
95616typedef struct {
95617 char *browseName;
95618 UA_UInt32 identifier;
95619} RefTypeNames;
95620
95621#define KNOWNREFTYPES 17
95622static const RefTypeNames knownRefTypes[KNOWNREFTYPES] = {
95623 {"References", UA_NS0ID_REFERENCES},
95624 {"HierachicalReferences", UA_NS0ID_HIERARCHICALREFERENCES},
95625 {"NonHierachicalReferences", UA_NS0ID_NONHIERARCHICALREFERENCES},
95626 {"HasChild", UA_NS0ID_HASCHILD},
95627 {"Aggregates", UA_NS0ID_AGGREGATES},
95628 {"HasComponent", UA_NS0ID_HASCOMPONENT},
95629 {"HasProperty", UA_NS0ID_HASPROPERTY},
95630 {"HasOrderedComponent", UA_NS0ID_HASORDEREDCOMPONENT},
95631 {"HasSubtype", UA_NS0ID_HASSUBTYPE},
95632 {"Organizes", UA_NS0ID_ORGANIZES},
95633 {"HasModellingRule", UA_NS0ID_HASMODELLINGRULE},
95634 {"HasTypeDefinition", UA_NS0ID_HASTYPEDEFINITION},
95635 {"HasEncoding", UA_NS0ID_HASENCODING},
95636 {"GeneratesEvent", UA_NS0ID_GENERATESEVENT},
95637 {"AlwaysGeneratesEvent", UA_NS0ID_ALWAYSGENERATESEVENT},
95638 {"HasEventSource", UA_NS0ID_HASEVENTSOURCE},
95639 {"HasNotifier", UA_NS0ID_HASNOTIFIER}
95640};
95641
95642static UA_StatusCode
95643lookup_reftype(UA_NodeId *refTypeId, UA_QualifiedName *qn) {
95644 if(qn->namespaceIndex != 0)
95645 return UA_STATUSCODE_BADNOTFOUND;
95646
95647 for(size_t i = 0; i < KNOWNREFTYPES; i++) {
95648 UA_String tmp = UA_STRING(chars: knownRefTypes[i].browseName);
95649 if(UA_String_equal(p1: &qn->name, p2: &tmp)) {
95650 *refTypeId = UA_NODEID_NUMERIC(nsIndex: 0, identifier: knownRefTypes[i].identifier);
95651 return UA_STATUSCODE_GOOD;
95652 }
95653 }
95654
95655 return UA_STATUSCODE_BADNOTFOUND;
95656}
95657
95658static UA_StatusCode
95659parse_relativepath(UA_RelativePath *rp, const char *pos, const char *end) {
95660 LexContext context;
95661 memset(s: &context, c: 0, n: sizeof(LexContext));
95662 const char *begin = NULL, *finish = NULL;
95663 UA_StatusCode res = UA_STATUSCODE_GOOD;
95664 UA_RelativePath_init(p: rp); /* Reset the BrowsePath */
95665
95666 /* Add one element to the path in every iteration */
95667 UA_RelativePathElement current;
95668 loop:
95669 UA_RelativePathElement_init(p: &current);
95670 current.includeSubtypes = true; /* Follow subtypes by default */
95671
95672 /* Get the ReferenceType and its modifiers */
95673
95674{
95675 char yych;
95676 unsigned int yyaccept = 0;
95677 yych = YYPEEK();
95678 switch (yych) {
95679 case 0x00: goto yy44;
95680 case '.': goto yy47;
95681 case '/': goto yy48;
95682 case '<': goto yy49;
95683 default: goto yy45;
95684 }
95685yy44:
95686 YYSKIP();
95687 { (void)pos; return UA_STATUSCODE_GOOD; }
95688yy45:
95689 YYSKIP();
95690yy46:
95691 { (void)pos; return UA_STATUSCODE_BADDECODINGERROR; }
95692yy47:
95693 YYSKIP();
95694 {
95695 current.referenceTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_AGGREGATES);
95696 goto reftype_target;
95697 }
95698yy48:
95699 YYSKIP();
95700 {
95701 current.referenceTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_HIERARCHICALREFERENCES);
95702 goto reftype_target;
95703 }
95704yy49:
95705 yyaccept = 0;
95706 YYSKIP();
95707 YYBACKUP();
95708 yych = YYPEEK();
95709 switch (yych) {
95710 case 0x00:
95711 case '>': goto yy46;
95712 case '&':
95713 YYSTAGP(context.yyt1);
95714 goto yy52;
95715 default:
95716 YYSTAGP(context.yyt1);
95717 goto yy50;
95718 }
95719yy50:
95720 YYSKIP();
95721 yych = YYPEEK();
95722 switch (yych) {
95723 case 0x00: goto yy51;
95724 case '&': goto yy52;
95725 case '>': goto yy53;
95726 default: goto yy50;
95727 }
95728yy51:
95729 YYRESTORE();
95730 if (yyaccept == 0) {
95731 goto yy46;
95732 } else {
95733 goto yy54;
95734 }
95735yy52:
95736 YYSKIP();
95737 yych = YYPEEK();
95738 switch (yych) {
95739 case 0x00: goto yy51;
95740 case '&': goto yy52;
95741 case '>': goto yy55;
95742 default: goto yy50;
95743 }
95744yy53:
95745 YYSKIP();
95746yy54:
95747 begin = context.yyt1;
95748 YYSTAGP(finish);
95749 YYSHIFTSTAG(finish, -1);
95750 {
95751 for(; begin < finish; begin++) {
95752 if(*begin== '#')
95753 current.includeSubtypes = false;
95754 else if(*begin == '!')
95755 current.isInverse = true;
95756 else
95757 break;
95758 }
95759 UA_QualifiedName refqn;
95760 res |= parse_refpath_qn(qn: &refqn, pos: begin, end: finish);
95761 res |= lookup_reftype(refTypeId: &current.referenceTypeId, qn: &refqn);
95762 UA_QualifiedName_clear(p: &refqn);
95763 goto reftype_target;
95764 }
95765yy55:
95766 yyaccept = 1;
95767 YYSKIP();
95768 YYBACKUP();
95769 yych = YYPEEK();
95770 switch (yych) {
95771 case 0x00: goto yy54;
95772 case '&': goto yy52;
95773 case '>': goto yy53;
95774 default: goto yy50;
95775 }
95776}
95777
95778
95779 /* Get the TargetName component */
95780 reftype_target:
95781 if(res != UA_STATUSCODE_GOOD)
95782 return res;
95783
95784
95785{
95786 char yych;
95787 yych = YYPEEK();
95788 switch (yych) {
95789 case 0x00:
95790 case '.':
95791 case '/':
95792 case '<': goto yy57;
95793 case '&':
95794 YYSTAGP(context.yyt1);
95795 goto yy60;
95796 default:
95797 YYSTAGP(context.yyt1);
95798 goto yy58;
95799 }
95800yy57:
95801 YYSKIP();
95802 { pos--; goto add_element; }
95803yy58:
95804 YYSKIP();
95805 yych = YYPEEK();
95806 switch (yych) {
95807 case 0x00:
95808 case '.':
95809 case '/':
95810 case '<': goto yy59;
95811 case '&': goto yy60;
95812 default: goto yy58;
95813 }
95814yy59:
95815 begin = context.yyt1;
95816 {
95817 res = parse_refpath_qn(qn: &current.targetName, pos: begin, end: pos);
95818 goto add_element;
95819 }
95820yy60:
95821 YYSKIP();
95822 yych = YYPEEK();
95823 switch (yych) {
95824 case 0x00: goto yy59;
95825 case '&': goto yy60;
95826 default: goto yy58;
95827 }
95828}
95829
95830
95831 /* Add the current element to the path and continue to the next element */
95832 add_element:
95833 res |= relativepath_addelem(rp, el: &current);
95834 if(res != UA_STATUSCODE_GOOD) {
95835 UA_RelativePathElement_clear(p: &current);
95836 return res;
95837 }
95838 goto loop;
95839}
95840
95841UA_StatusCode
95842UA_RelativePath_parse(UA_RelativePath *rp, const UA_String str) {
95843 UA_StatusCode res =
95844 parse_relativepath(rp, pos: (const char*)str.data, end: (const char*)str.data+str.length);
95845 if(res != UA_STATUSCODE_GOOD)
95846 UA_RelativePath_clear(p: rp);
95847 return res;
95848}
95849
95850/**** amalgamated original file "/src/pubsub/ua_pubsub_networkmessage_json.c" ****/
95851
95852/* This Source Code Form is subject to the terms of the Mozilla Public
95853 * License, v. 2.0. If a copy of the MPL was not distributed with this
95854 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
95855 *
95856 * Copyright (c) 2019 Fraunhofer IOSB (Author: Lukas Meling)
95857 */
95858
95859
95860
95861/* Json keys for dsm */
95862const char * UA_DECODEKEY_MESSAGES = "Messages";
95863const char * UA_DECODEKEY_MESSAGETYPE = "MessageType";
95864const char * UA_DECODEKEY_MESSAGEID = "MessageId";
95865const char * UA_DECODEKEY_PUBLISHERID = "PublisherId";
95866const char * UA_DECODEKEY_DATASETCLASSID = "DataSetClassId";
95867
95868/* Json keys for dsm */
95869const char * UA_DECODEKEY_DATASETWRITERID = "DataSetWriterId";
95870const char * UA_DECODEKEY_SEQUENCENUMBER = "SequenceNumber";
95871const char * UA_DECODEKEY_METADATAVERSION = "MetaDataVersion";
95872const char * UA_DECODEKEY_TIMESTAMP = "Timestamp";
95873const char * UA_DECODEKEY_DSM_STATUS = "Status";
95874const char * UA_DECODEKEY_PAYLOAD = "Payload";
95875const char * UA_DECODEKEY_DS_TYPE = "Type";
95876
95877/* -- json encoding/decoding -- */
95878static UA_StatusCode writeJsonKey_UA_String(CtxJson *ctx, UA_String *in) {
95879 UA_STACKARRAY(char, out, in->length + 1);
95880 memcpy(dest: out, src: in->data, n: in->length);
95881 out[in->length] = 0;
95882 return writeJsonKey(ctx, key: out);
95883}
95884
95885static UA_StatusCode
95886UA_DataSetMessage_encodeJson_internal(const UA_DataSetMessage* src,
95887 UA_UInt16 dataSetWriterId,
95888 CtxJson *ctx) {
95889 status rv = writeJsonObjStart(ctx);
95890
95891 /* DataSetWriterId */
95892 rv |= writeJsonObjElm(ctx, key: UA_DECODEKEY_DATASETWRITERID,
95893 value: &dataSetWriterId, type: &UA_TYPES[UA_TYPES_UINT16]);
95894 if(rv != UA_STATUSCODE_GOOD)
95895 return rv;
95896
95897 /* DataSetMessageSequenceNr */
95898 if(src->header.dataSetMessageSequenceNrEnabled) {
95899 rv |= writeJsonObjElm(ctx, key: UA_DECODEKEY_SEQUENCENUMBER,
95900 value: &src->header.dataSetMessageSequenceNr,
95901 type: &UA_TYPES[UA_TYPES_UINT16]);
95902 if(rv != UA_STATUSCODE_GOOD)
95903 return rv;
95904 }
95905
95906 /* MetaDataVersion */
95907 if(src->header.configVersionMajorVersionEnabled ||
95908 src->header.configVersionMinorVersionEnabled) {
95909 UA_ConfigurationVersionDataType cvd;
95910 cvd.majorVersion = src->header.configVersionMajorVersion;
95911 cvd.minorVersion = src->header.configVersionMinorVersion;
95912 rv |= writeJsonObjElm(ctx, key: UA_DECODEKEY_METADATAVERSION, value: &cvd,
95913 type: &UA_TYPES[UA_TYPES_CONFIGURATIONVERSIONDATATYPE]);
95914 if(rv != UA_STATUSCODE_GOOD)
95915 return rv;
95916 }
95917
95918 /* Timestamp */
95919 if(src->header.timestampEnabled) {
95920 rv |= writeJsonObjElm(ctx, key: UA_DECODEKEY_TIMESTAMP, value: &src->header.timestamp,
95921 type: &UA_TYPES[UA_TYPES_DATETIME]);
95922 if(rv != UA_STATUSCODE_GOOD)
95923 return rv;
95924 }
95925
95926 /* Status */
95927 if(src->header.statusEnabled) {
95928 rv |= writeJsonObjElm(ctx, key: UA_DECODEKEY_DSM_STATUS,
95929 value: &src->header.status, type: &UA_TYPES[UA_TYPES_UINT16]);
95930 if(rv != UA_STATUSCODE_GOOD)
95931 return rv;
95932 }
95933
95934 rv |= writeJsonKey(ctx, key: UA_DECODEKEY_PAYLOAD);
95935 rv |= writeJsonObjStart(ctx);
95936
95937 /* TODO: currently no difference between delta and key frames. Own
95938 * dataSetMessageType for json?. If the field names are not defined, write
95939 * out empty field names. */
95940 if(src->header.dataSetMessageType != UA_DATASETMESSAGE_DATAKEYFRAME)
95941 return UA_STATUSCODE_BADNOTSUPPORTED; /* Delta frames not supported */
95942
95943 if(src->header.fieldEncoding == UA_FIELDENCODING_VARIANT) {
95944 /* KEYFRAME VARIANT */
95945 for(UA_UInt16 i = 0; i < src->data.keyFrameData.fieldCount; i++) {
95946 if(src->data.keyFrameData.fieldNames)
95947 rv |= writeJsonKey_UA_String(ctx, in: &src->data.keyFrameData.fieldNames[i]);
95948 else
95949 rv |= writeJsonKey(ctx, key: "");
95950 rv |= encodeJsonJumpTable[UA_DATATYPEKIND_VARIANT]
95951 (ctx, &src->data.keyFrameData.dataSetFields[i].value, NULL);
95952 if(rv != UA_STATUSCODE_GOOD)
95953 return rv;
95954 }
95955 } else if(src->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) {
95956 /* KEYFRAME DATAVALUE */
95957 for(UA_UInt16 i = 0; i < src->data.keyFrameData.fieldCount; i++) {
95958 if(src->data.keyFrameData.fieldNames)
95959 rv |= writeJsonKey_UA_String(ctx, in: &src->data.keyFrameData.fieldNames[i]);
95960 else
95961 rv |= writeJsonKey(ctx, key: "");
95962 rv |= encodeJsonJumpTable[UA_DATATYPEKIND_DATAVALUE]
95963 (ctx, &src->data.keyFrameData.dataSetFields[i], NULL);
95964 if(rv != UA_STATUSCODE_GOOD)
95965 return rv;
95966 }
95967 } else {
95968 /* RawData */
95969 return UA_STATUSCODE_BADNOTIMPLEMENTED;
95970 }
95971 rv |= writeJsonObjEnd(ctx); /* Payload */
95972 rv |= writeJsonObjEnd(ctx); /* DataSetMessage */
95973 return rv;
95974}
95975
95976static UA_StatusCode
95977UA_NetworkMessage_encodeJson_internal(const UA_NetworkMessage* src, CtxJson *ctx) {
95978 status rv = UA_STATUSCODE_GOOD;
95979 const UA_DataType *publisherIdType;
95980 /* currently only ua-data is supported, no discovery message implemented */
95981 if(src->networkMessageType != UA_NETWORKMESSAGE_DATASET)
95982 return UA_STATUSCODE_BADNOTIMPLEMENTED;
95983
95984 writeJsonObjStart(ctx);
95985
95986 /* Table 91 – JSON NetworkMessage Definition
95987 * MessageId | String | A globally unique identifier for the message.
95988 * This value is mandatory. But we don't check uniqueness in the
95989 * encoding layer. */
95990 rv |= writeJsonObjElm(ctx, key: UA_DECODEKEY_MESSAGEID,
95991 value: &src->messageId, type: &UA_TYPES[UA_TYPES_STRING]);
95992
95993 /* MessageType */
95994 UA_String s = UA_STRING(chars: "ua-data");
95995 rv |= writeJsonObjElm(ctx, key: UA_DECODEKEY_MESSAGETYPE,
95996 value: &s, type: &UA_TYPES[UA_TYPES_STRING]);
95997
95998 /* PublisherId */
95999 if(src->publisherIdEnabled) {
96000 rv = writeJsonKey(ctx, key: UA_DECODEKEY_PUBLISHERID);
96001 switch (src->publisherIdType) {
96002 case UA_PUBLISHERIDTYPE_BYTE:
96003 publisherIdType = &UA_TYPES[UA_TYPES_BYTE];
96004 break;
96005 case UA_PUBLISHERIDTYPE_UINT16:
96006 publisherIdType = &UA_TYPES[UA_TYPES_UINT16];
96007 break;
96008 case UA_PUBLISHERIDTYPE_UINT32:
96009 publisherIdType = &UA_TYPES[UA_TYPES_UINT32];
96010 break;
96011 case UA_PUBLISHERIDTYPE_UINT64:
96012 publisherIdType = &UA_TYPES[UA_TYPES_UINT64];
96013 break;
96014 case UA_PUBLISHERIDTYPE_STRING:
96015 publisherIdType = &UA_TYPES[UA_TYPES_STRING];
96016 break;
96017 }
96018 rv |= encodeJsonJumpTable[publisherIdType->typeKind]
96019 (ctx, &src->publisherId, publisherIdType);
96020 }
96021 if(rv != UA_STATUSCODE_GOOD)
96022 return rv;
96023
96024 /* DataSetClassId */
96025 if(src->dataSetClassIdEnabled) {
96026 rv |= writeJsonObjElm(ctx, key: UA_DECODEKEY_DATASETCLASSID,
96027 value: &src->dataSetClassId, type: &UA_TYPES[UA_TYPES_GUID]);
96028 if(rv != UA_STATUSCODE_GOOD)
96029 return rv;
96030 }
96031
96032 /* Payload: DataSetMessages */
96033 UA_Byte count = src->payloadHeader.dataSetPayloadHeader.count;
96034 if(count > 0) {
96035 UA_UInt16 *dataSetWriterIds =
96036 src->payloadHeader.dataSetPayloadHeader.dataSetWriterIds;
96037 if(!dataSetWriterIds)
96038 return UA_STATUSCODE_BADENCODINGERROR;
96039
96040 rv |= writeJsonKey(ctx, key: UA_DECODEKEY_MESSAGES);
96041 rv |= writeJsonArrStart(ctx); /* start array */
96042
96043 const UA_DataSetMessage *dataSetMessages =
96044 src->payload.dataSetPayload.dataSetMessages;
96045 for(UA_UInt16 i = 0; i < count; i++) {
96046 rv |= writeJsonBeforeElement(ctx, true);
96047 rv |= UA_DataSetMessage_encodeJson_internal(src: &dataSetMessages[i],
96048 dataSetWriterId: dataSetWriterIds[i], ctx);
96049 if(rv != UA_STATUSCODE_GOOD)
96050 return rv;
96051 /* comma is needed if more dsm are present */
96052 ctx->commaNeeded[ctx->depth] = true;
96053 }
96054 rv |= writeJsonArrEnd(ctx); /* end array */
96055 }
96056
96057 rv |= writeJsonObjEnd(ctx);
96058 return rv;
96059}
96060
96061UA_StatusCode
96062UA_NetworkMessage_encodeJson(const UA_NetworkMessage *src,
96063 UA_Byte **bufPos, const UA_Byte **bufEnd,
96064 UA_String *namespaces, size_t namespaceSize,
96065 UA_String *serverUris, size_t serverUriSize,
96066 UA_Boolean useReversible) {
96067 /* Set up the context */
96068 CtxJson ctx;
96069 memset(s: &ctx, c: 0, n: sizeof(ctx));
96070 ctx.pos = *bufPos;
96071 ctx.end = *bufEnd;
96072 ctx.depth = 0;
96073 ctx.namespaces = namespaces;
96074 ctx.namespacesSize = namespaceSize;
96075 ctx.serverUris = serverUris;
96076 ctx.serverUrisSize = serverUriSize;
96077 ctx.useReversible = useReversible;
96078 ctx.calcOnly = false;
96079
96080 status ret = UA_NetworkMessage_encodeJson_internal(src, ctx: &ctx);
96081
96082 *bufPos = ctx.pos;
96083 *bufEnd = ctx.end;
96084 return ret;
96085}
96086
96087size_t
96088UA_NetworkMessage_calcSizeJson(const UA_NetworkMessage *src,
96089 UA_String *namespaces, size_t namespaceSize,
96090 UA_String *serverUris, size_t serverUriSize,
96091 UA_Boolean useReversible){
96092 /* Set up the context */
96093 CtxJson ctx;
96094 memset(s: &ctx, c: 0, n: sizeof(ctx));
96095 ctx.pos = 0;
96096 ctx.end = (const UA_Byte*)(uintptr_t)SIZE_MAX;
96097 ctx.depth = 0;
96098 ctx.namespaces = namespaces;
96099 ctx.namespacesSize = namespaceSize;
96100 ctx.serverUris = serverUris;
96101 ctx.serverUrisSize = serverUriSize;
96102 ctx.useReversible = useReversible;
96103 ctx.calcOnly = true;
96104
96105 status ret = UA_NetworkMessage_encodeJson_internal(src, ctx: &ctx);
96106 if(ret != UA_STATUSCODE_GOOD)
96107 return 0;
96108 return (size_t)ctx.pos;
96109}
96110
96111/* decode json */
96112static status
96113MetaDataVersion_decodeJsonInternal(ParseCtx *ctx, void* cvd, const UA_DataType *type) {
96114 return decodeJsonJumpTable[UA_DATATYPEKIND_STRUCTURE]
96115 (ctx, cvd, &UA_TYPES[UA_TYPES_CONFIGURATIONVERSIONDATATYPE]);
96116}
96117
96118static status
96119DataSetPayload_decodeJsonInternal(ParseCtx *ctx, void* dsmP, const UA_DataType *type) {
96120 UA_DataSetMessage* dsm = (UA_DataSetMessage*)dsmP;
96121 dsm->header.dataSetMessageValid = true;
96122 if(currentTokenType(ctx) == CJ5_TOKEN_NULL) {
96123 ctx->index++;
96124 return UA_STATUSCODE_GOOD;
96125 }
96126
96127 if(currentTokenType(ctx) != CJ5_TOKEN_OBJECT)
96128 return UA_STATUSCODE_BADDECODINGERROR;
96129
96130 /* The number of key-value pairs */
96131 UA_assert(ctx->tokens[ctx->index].size % 2 == 0);
96132 size_t length = (size_t)(ctx->tokens[ctx->index].size) / 2;
96133
96134 UA_String *fieldNames = (UA_String*)UA_calloc(nmemb: length, size: sizeof(UA_String));
96135 if(!fieldNames)
96136 return UA_STATUSCODE_BADOUTOFMEMORY;
96137 dsm->data.keyFrameData.fieldNames = fieldNames;
96138 dsm->data.keyFrameData.fieldCount = (UA_UInt16)length;
96139
96140 dsm->data.keyFrameData.dataSetFields = (UA_DataValue *)
96141 UA_Array_new(size: dsm->data.keyFrameData.fieldCount, type: &UA_TYPES[UA_TYPES_DATAVALUE]);
96142 if(!dsm->data.keyFrameData.dataSetFields)
96143 return UA_STATUSCODE_BADOUTOFMEMORY;
96144
96145 ctx->index++; /* Go to the first key */
96146
96147 /* Iterate over the key/value pairs in the object. Keys are stored in fieldnames. */
96148 status ret = UA_STATUSCODE_GOOD;
96149 for(size_t i = 0; i < length; ++i) {
96150 UA_assert(currentTokenType(ctx) == CJ5_TOKEN_STRING);
96151 ret = decodeJsonJumpTable[UA_DATATYPEKIND_STRING](ctx, &fieldNames[i], type);
96152 if(ret != UA_STATUSCODE_GOOD)
96153 return ret;
96154
96155 /* TODO: Is field value a variant or datavalue? Current check if type and body present. */
96156 size_t searchResult = 0;
96157 status foundType = lookAheadForKey(ctx, search: "Type", resultIndex: &searchResult);
96158 status foundBody = lookAheadForKey(ctx, search: "Body", resultIndex: &searchResult);
96159 if(foundType == UA_STATUSCODE_GOOD && foundBody == UA_STATUSCODE_GOOD) {
96160 dsm->header.fieldEncoding = UA_FIELDENCODING_VARIANT;
96161 ret = decodeJsonJumpTable[UA_DATATYPEKIND_VARIANT]
96162 (ctx, &dsm->data.keyFrameData.dataSetFields[i].value, type);
96163 dsm->data.keyFrameData.dataSetFields[i].hasValue = true;
96164 } else {
96165 dsm->header.fieldEncoding = UA_FIELDENCODING_DATAVALUE;
96166 ret = decodeJsonJumpTable[UA_DATATYPEKIND_DATAVALUE]
96167 (ctx, &dsm->data.keyFrameData.dataSetFields[i], type);
96168 dsm->data.keyFrameData.dataSetFields[i].hasValue = true;
96169 }
96170
96171 if(ret != UA_STATUSCODE_GOOD)
96172 return ret;
96173 }
96174
96175 return ret;
96176}
96177
96178static status
96179DatasetMessage_Payload_decodeJsonInternal(ParseCtx *ctx, UA_DataSetMessage* dsm,
96180 const UA_DataType *type) {
96181 UA_ConfigurationVersionDataType cvd;
96182 UA_UInt16 dataSetWriterId;
96183
96184 dsm->header.fieldEncoding = UA_FIELDENCODING_DATAVALUE;
96185
96186 DecodeEntry entries[6] = {
96187 {UA_DECODEKEY_DATASETWRITERID, &dataSetWriterId, NULL, false, &UA_TYPES[UA_TYPES_UINT16]},
96188 {UA_DECODEKEY_SEQUENCENUMBER, &dsm->header.dataSetMessageSequenceNr, NULL, false, &UA_TYPES[UA_TYPES_UINT16]},
96189 {UA_DECODEKEY_METADATAVERSION, &cvd, &MetaDataVersion_decodeJsonInternal, false, NULL},
96190 {UA_DECODEKEY_TIMESTAMP, &dsm->header.timestamp, NULL, false, &UA_TYPES[UA_TYPES_DATETIME]},
96191 {UA_DECODEKEY_DSM_STATUS, &dsm->header.status, NULL, false, &UA_TYPES[UA_TYPES_UINT16]},
96192 {UA_DECODEKEY_PAYLOAD, dsm, &DataSetPayload_decodeJsonInternal, false, NULL}
96193 };
96194 status ret = decodeFields(ctx, entries, entryCount: 6);
96195
96196 /* Error or no DatasetWriterId found or no payload found */
96197 if(ret != UA_STATUSCODE_GOOD || !entries[0].found || !entries[5].found)
96198 return UA_STATUSCODE_BADDECODINGERROR;
96199
96200 /* Set the DatasetWriterId in the context */
96201 if(!ctx->custom)
96202 return UA_STATUSCODE_BADDECODINGERROR;
96203 if(ctx->currentCustomIndex >= ctx->numCustom)
96204 return UA_STATUSCODE_BADDECODINGERROR;
96205 UA_UInt16* dataSetWriterIdsArray = (UA_UInt16*)ctx->custom;
96206 dataSetWriterIdsArray[ctx->currentCustomIndex] = dataSetWriterId;
96207 ctx->currentCustomIndex++;
96208
96209 dsm->header.dataSetMessageSequenceNrEnabled = entries[1].found;
96210 dsm->header.configVersionMajorVersion = cvd.majorVersion;
96211 dsm->header.configVersionMinorVersion = cvd.minorVersion;
96212 dsm->header.configVersionMajorVersionEnabled = entries[2].found;
96213 dsm->header.configVersionMinorVersionEnabled = entries[2].found;
96214 dsm->header.timestampEnabled = entries[3].found;
96215 dsm->header.statusEnabled = entries[4].found;
96216
96217 dsm->header.dataSetMessageType = UA_DATASETMESSAGE_DATAKEYFRAME;
96218 dsm->header.picoSecondsIncluded = false;
96219 dsm->header.dataSetMessageValid = true;
96220 dsm->header.fieldEncoding = UA_FIELDENCODING_VARIANT;
96221 return UA_STATUSCODE_GOOD;
96222}
96223
96224static status
96225DatasetMessage_Array_decodeJsonInternal(ParseCtx *ctx, void *UA_RESTRICT dst,
96226 const UA_DataType *type) {
96227 /* Array! */
96228 if(currentTokenType(ctx) != CJ5_TOKEN_ARRAY)
96229 return UA_STATUSCODE_BADDECODINGERROR;
96230 size_t length = (size_t)ctx->tokens[ctx->index].size;
96231
96232 /* Return early for empty arrays */
96233 if(length == 0)
96234 return UA_STATUSCODE_GOOD;
96235
96236 /* Allocate memory */
96237 UA_DataSetMessage *dsm = (UA_DataSetMessage*)
96238 UA_calloc(nmemb: length, size: sizeof(UA_DataSetMessage));
96239 if(!dsm)
96240 return UA_STATUSCODE_BADOUTOFMEMORY;
96241
96242 /* Copy new Pointer do dest */
96243 memcpy(dest: dst, src: &dsm, n: sizeof(void*));
96244
96245 /* We go to first Array member! */
96246 ctx->index++;
96247
96248 status ret = UA_STATUSCODE_BADDECODINGERROR;
96249 /* Decode array members */
96250 for(size_t i = 0; i < length; ++i) {
96251 ret = DatasetMessage_Payload_decodeJsonInternal(ctx, dsm: &dsm[i], NULL);
96252 if(ret != UA_STATUSCODE_GOOD)
96253 return ret;
96254 }
96255
96256 return ret;
96257}
96258
96259static status
96260NetworkMessage_decodeJsonInternal(ParseCtx *ctx, UA_NetworkMessage *dst) {
96261 memset(s: dst, c: 0, n: sizeof(UA_NetworkMessage));
96262 dst->chunkMessage = false;
96263 dst->groupHeaderEnabled = false;
96264 dst->payloadHeaderEnabled = false;
96265 dst->picosecondsEnabled = false;
96266 dst->promotedFieldsEnabled = false;
96267
96268 /* Look forward for publisheId, if present check if type if primitve (Number) or String. */
96269 const UA_DataType *pubIdType = &UA_TYPES[UA_TYPES_STRING];
96270 size_t searchResultPublishIdType = 0;
96271 status found = lookAheadForKey(ctx, search: UA_DECODEKEY_PUBLISHERID, resultIndex: &searchResultPublishIdType);
96272 if(found == UA_STATUSCODE_GOOD) {
96273 cj5_token *publishIdToken = &ctx->tokens[searchResultPublishIdType];
96274 if(publishIdToken->type == CJ5_TOKEN_NUMBER) {
96275 // store in biggest possible. The problem is that with a UInt64 a
96276 // string is expected in the json. Therefore, the maximum value is
96277 // set to UInt32.
96278 pubIdType = &UA_TYPES[UA_TYPES_UINT32];
96279 dst->publisherIdType = UA_PUBLISHERIDTYPE_UINT32;
96280 } else if(publishIdToken->type == CJ5_TOKEN_STRING) {
96281 dst->publisherIdType = UA_PUBLISHERIDTYPE_STRING;
96282 } else {
96283 return UA_STATUSCODE_BADDECODINGERROR;
96284 }
96285 }
96286
96287 /* Is Messages an Array? How big? */
96288 size_t searchResultMessages = 0;
96289 found = lookAheadForKey(ctx, search: UA_DECODEKEY_MESSAGES, resultIndex: &searchResultMessages);
96290 if(found != UA_STATUSCODE_GOOD)
96291 return UA_STATUSCODE_BADNOTIMPLEMENTED;
96292 const cj5_token *bodyToken = &ctx->tokens[searchResultMessages];
96293 if(bodyToken->type != CJ5_TOKEN_ARRAY)
96294 return UA_STATUSCODE_BADNOTIMPLEMENTED;
96295 size_t messageCount = (size_t)ctx->tokens[searchResultMessages].size;
96296
96297 /* Set up custom context for the dataSetwriterId */
96298 ctx->custom = (void*)UA_calloc(nmemb: messageCount, size: sizeof(UA_UInt16));
96299 ctx->currentCustomIndex = 0;
96300 ctx->numCustom = messageCount;
96301
96302 /* MessageType */
96303 UA_Boolean isUaData = true;
96304 size_t searchResultMessageType = 0;
96305 found = lookAheadForKey(ctx, search: UA_DECODEKEY_MESSAGETYPE, resultIndex: &searchResultMessageType);
96306 if(found != UA_STATUSCODE_GOOD)
96307 return UA_STATUSCODE_BADDECODINGERROR;
96308 size_t size = getTokenLength(t: &ctx->tokens[searchResultMessageType]);
96309 const char* msgType = &ctx->json5[ctx->tokens[searchResultMessageType].start];
96310 if(size == 7) { //ua-data
96311 if(strncmp(s1: msgType, s2: "ua-data", n: size) != 0)
96312 return UA_STATUSCODE_BADDECODINGERROR;
96313 isUaData = true;
96314 } else if(size == 11) { //ua-metadata
96315 if(strncmp(s1: msgType, s2: "ua-metadata", n: size) != 0)
96316 return UA_STATUSCODE_BADDECODINGERROR;
96317 isUaData = false;
96318 } else {
96319 return UA_STATUSCODE_BADDECODINGERROR;
96320 }
96321
96322 //TODO: MetaData
96323 if(!isUaData)
96324 return UA_STATUSCODE_BADNOTIMPLEMENTED;
96325
96326 /* Network Message */
96327 UA_String messageType;
96328 DecodeEntry entries[5] = {
96329 {UA_DECODEKEY_MESSAGEID, &dst->messageId, NULL, false, &UA_TYPES[UA_TYPES_STRING]},
96330 {UA_DECODEKEY_MESSAGETYPE, &messageType, NULL, false, NULL},
96331 {UA_DECODEKEY_PUBLISHERID, &dst->publisherId, NULL, false, pubIdType},
96332 {UA_DECODEKEY_DATASETCLASSID, &dst->dataSetClassId, NULL, false, &UA_TYPES[UA_TYPES_GUID]},
96333 {UA_DECODEKEY_MESSAGES, &dst->payload.dataSetPayload.dataSetMessages, &DatasetMessage_Array_decodeJsonInternal, false, NULL}
96334 };
96335
96336 status ret = decodeFields(ctx, entries, entryCount: 5);
96337 if(ret != UA_STATUSCODE_GOOD)
96338 return ret;
96339
96340 dst->messageIdEnabled = entries[0].found;
96341 dst->publisherIdEnabled = entries[2].found;
96342 if(dst->publisherIdEnabled) {
96343 if(pubIdType == &UA_TYPES[UA_TYPES_UINT32]) {
96344 dst->publisherIdType = UA_PUBLISHERIDTYPE_UINT32;
96345 } else {
96346 dst->publisherIdType = UA_PUBLISHERIDTYPE_STRING;
96347 }
96348 }
96349 dst->dataSetClassIdEnabled = entries[3].found;
96350 dst->payloadHeaderEnabled = true;
96351 dst->payloadHeader.dataSetPayloadHeader.count = (UA_Byte)messageCount;
96352
96353 /* Set the dataSetWriterIds. They are filled in the dataSet decoding. */
96354 dst->payloadHeader.dataSetPayloadHeader.dataSetWriterIds = (UA_UInt16*)ctx->custom;
96355 return ret;
96356}
96357
96358status
96359UA_NetworkMessage_decodeJson(UA_NetworkMessage *dst, const UA_ByteString *src) {
96360 /* Set up the context */
96361 cj5_token tokens[UA_JSON_MAXTOKENCOUNT];
96362 ParseCtx ctx;
96363 memset(s: &ctx, c: 0, n: sizeof(ParseCtx));
96364 ctx.tokens = tokens;
96365 status ret = tokenize(ctx: &ctx, src, UA_JSON_MAXTOKENCOUNT);
96366 if(ret != UA_STATUSCODE_GOOD)
96367 goto cleanup;
96368
96369 ret = NetworkMessage_decodeJsonInternal(ctx: &ctx, dst);
96370
96371 cleanup:
96372 /* Free token array on the heap */
96373 if(ctx.tokens != tokens)
96374 UA_free(ptr: (void*)(uintptr_t)ctx.tokens);
96375 return ret;
96376}
96377
96378/**** amalgamated original file "/deps/cj5.c" ****/
96379
96380// MIT License
96381//
96382// Copyright (c) 2020 Sepehr Taghdisian
96383// Copyright (c) 2022 Julius Pfrommer
96384//
96385// Permission is hereby granted, free of charge, to any person obtaining a copy
96386// of this software and associated documentation files (the "Software"), to deal
96387// in the Software without restriction, including without limitation the rights
96388// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
96389// copies of the Software, and to permit persons to whom the Software is
96390// furnished to do so, subject to the following conditions:
96391//
96392// The above copyright notice and this permission notice shall be included in all
96393// copies or substantial portions of the Software.
96394//
96395// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
96396// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
96397// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
96398// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
96399// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
96400// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
96401// SOFTWARE.
96402
96403
96404#include <math.h>
96405#include <float.h>
96406#include <string.h>
96407
96408#if defined(_MSC_VER)
96409# define CJ5_INLINE __inline
96410#else
96411# define CJ5_INLINE inline
96412#endif
96413
96414/* vs2008 does not have INFINITY and NAN defined */
96415#ifndef INFINITY
96416# define INFINITY ((double)(DBL_MAX+DBL_MAX))
96417#endif
96418#ifndef NAN
96419# define NAN ((double)(INFINITY-INFINITY))
96420#endif
96421
96422#if defined(_MSC_VER)
96423# pragma warning(disable: 4056)
96424# pragma warning(disable: 4756)
96425#endif
96426
96427/* Max nesting depth of objects and arrays */
96428#define CJ5_MAX_NESTING 32
96429
96430#define CJ5__FOURCC(_a, _b, _c, _d) \
96431 (((uint32_t)(_a) | ((uint32_t)(_b) << 8) | \
96432 ((uint32_t)(_c) << 16) | ((uint32_t)(_d) << 24)))
96433
96434static const uint32_t CJ5__NULL_FOURCC = CJ5__FOURCC('n', 'u', 'l', 'l');
96435static const uint32_t CJ5__TRUE_FOURCC = CJ5__FOURCC('t', 'r', 'u', 'e');
96436static const uint32_t CJ5__FALSE_FOURCC = CJ5__FOURCC('f', 'a', 'l', 's');
96437
96438typedef struct {
96439 unsigned int pos;
96440 unsigned int line_start;
96441 unsigned int line;
96442 cj5_error_code error;
96443
96444 const char *json5;
96445 unsigned int len;
96446
96447 unsigned int curr_tok_idx;
96448
96449 cj5_token *tokens;
96450 unsigned int token_count;
96451 unsigned int max_tokens;
96452
96453 bool stop_early;
96454} cj5__parser;
96455
96456static CJ5_INLINE bool
96457cj5__isrange(char ch, char from, char to) {
96458 return (uint8_t)(ch - from) <= (uint8_t)(to - from);
96459}
96460
96461#define cj5__isupperchar(ch) cj5__isrange(ch, 'A', 'Z')
96462#define cj5__islowerchar(ch) cj5__isrange(ch, 'a', 'z')
96463#define cj5__isnum(ch) cj5__isrange(ch, '0', '9')
96464
96465static cj5_token *
96466cj5__alloc_token(cj5__parser *parser) {
96467 cj5_token* token = NULL;
96468 if(parser->token_count < parser->max_tokens) {
96469 token = &parser->tokens[parser->token_count];
96470 memset(s: token, c: 0x0, n: sizeof(cj5_token));
96471 } else {
96472 parser->error = CJ5_ERROR_OVERFLOW;
96473 }
96474
96475 // Always increase the index. So we know eventually how many token would be
96476 // required (if there are not enough).
96477 parser->token_count++;
96478 return token;
96479}
96480
96481static void
96482cj5__parse_string(cj5__parser *parser) {
96483 const char *json5 = parser->json5;
96484 unsigned int len = parser->len;
96485 unsigned int start = parser->pos;
96486 char str_open = json5[start];
96487
96488 parser->pos++;
96489 for(; parser->pos < len; parser->pos++) {
96490 char c = json5[parser->pos];
96491
96492 // End of string
96493 if(str_open == c) {
96494 cj5_token *token = cj5__alloc_token(parser);
96495 if(token) {
96496 token->type = CJ5_TOKEN_STRING;
96497 token->start = start + 1;
96498 token->end = parser->pos - 1;
96499 token->size = token->end - token->start + 1;
96500 token->parent_id = parser->curr_tok_idx;
96501 }
96502 return;
96503 }
96504
96505 // Unescaped newlines are forbidden
96506 if(c == '\n') {
96507 parser->error = CJ5_ERROR_INVALID;
96508 return;
96509 }
96510
96511 // Escape char
96512 if(c == '\\') {
96513 if(parser->pos + 1 >= len) {
96514 parser->error = CJ5_ERROR_INCOMPLETE;
96515 return;
96516 }
96517 parser->pos++;
96518 switch(json5[parser->pos]) {
96519 case '\"':
96520 case '/':
96521 case '\\':
96522 case 'b':
96523 case 'f':
96524 case 'r':
96525 case 'n':
96526 case 't':
96527 break;
96528 case 'u': // The next four characters are an utf8 code
96529 parser->pos++;
96530 if(parser->pos + 4 >= len) {
96531 parser->error = CJ5_ERROR_INVALID;
96532 return;
96533 }
96534 for(unsigned int i = 0; i < 4; i++) {
96535 // If it isn't a hex character we have an error
96536 if(!(json5[parser->pos] >= 48 && json5[parser->pos] <= 57) && /* 0-9 */
96537 !(json5[parser->pos] >= 65 && json5[parser->pos] <= 70) && /* A-F */
96538 !(json5[parser->pos] >= 97 && json5[parser->pos] <= 102)) /* a-f */
96539 {
96540 parser->error = CJ5_ERROR_INVALID;
96541 return;
96542 }
96543 parser->pos++;
96544 }
96545 parser->pos--;
96546 break;
96547 case '\n': // Escape break line
96548 parser->line++;
96549 parser->line_start = parser->pos;
96550 break;
96551 default:
96552 parser->error = CJ5_ERROR_INVALID;
96553 return;
96554 }
96555 }
96556 }
96557
96558 // The file has ended before the string terminates
96559 parser->error = CJ5_ERROR_INCOMPLETE;
96560}
96561
96562// parser->pos is advanced a last time in the next iteration of the main
96563// parse-loop. So we leave parse-primitive in a state where parse->pos points to
96564// the last character of the primitive value (or the quote-character of the
96565// string).
96566static void
96567cj5__parse_primitive(cj5__parser* parser) {
96568 const char* json5 = parser->json5;
96569 unsigned int len = parser->len;
96570 unsigned int start = parser->pos;
96571
96572 // String value
96573 if(json5[start] == '\"' ||
96574 json5[start] == '\'') {
96575 cj5__parse_string(parser);
96576 return;
96577 }
96578
96579 // Fast comparison of bool, and null.
96580 // We have to use memcpy here or we can get unaligned accesses
96581 uint32_t fourcc = 0;
96582 if(start + 4 < len)
96583 memcpy(dest: &fourcc, src: &json5[start], n: 4);
96584
96585 cj5_token_type type;
96586 if(fourcc == CJ5__NULL_FOURCC) {
96587 type = CJ5_TOKEN_NULL;
96588 parser->pos += 3;
96589 } else if(fourcc == CJ5__TRUE_FOURCC) {
96590 type = CJ5_TOKEN_BOOL;
96591 parser->pos += 3;
96592 } else if(fourcc == CJ5__FALSE_FOURCC) {
96593 // "false" has five characters
96594 type = CJ5_TOKEN_BOOL;
96595 if(start + 4 >= len || json5[start+4] != 'e') {
96596 parser->error = CJ5_ERROR_INVALID;
96597 return;
96598 }
96599 parser->pos += 4;
96600 } else {
96601 // Numbers are checked for basic compatibility.
96602 // But they are fully parsed only in the cj5_get_XXX functions.
96603 type = CJ5_TOKEN_NUMBER;
96604 for(; parser->pos < len; parser->pos++) {
96605 if(!cj5__isnum(json5[parser->pos]) &&
96606 !(json5[parser->pos] == '.') &&
96607 !cj5__islowerchar(json5[parser->pos]) &&
96608 !cj5__isupperchar(json5[parser->pos]) &&
96609 !(json5[parser->pos] == '+') && !(json5[parser->pos] == '-')) {
96610 break;
96611 }
96612 }
96613 parser->pos--; // Point to the last character that is still inside the
96614 // primitive value
96615 }
96616
96617 cj5_token *token = cj5__alloc_token(parser);
96618 if(token) {
96619 token->type = type;
96620 token->start = start;
96621 token->end = parser->pos;
96622 token->size = parser->pos - start + 1;
96623 token->parent_id = parser->curr_tok_idx;
96624 }
96625}
96626
96627static void
96628cj5__parse_key(cj5__parser* parser) {
96629 const char* json5 = parser->json5;
96630 unsigned int start = parser->pos;
96631 cj5_token* token;
96632
96633 // Key is a a normal string
96634 if(json5[start] == '\"' || json5[start] == '\'') {
96635 cj5__parse_string(parser);
96636 return;
96637 }
96638
96639 // An unquoted key. Must start with a-ZA-Z_$. Can contain numbers later on.
96640 unsigned int len = parser->len;
96641 for(; parser->pos < len; parser->pos++) {
96642 if(cj5__islowerchar(json5[parser->pos]) ||
96643 cj5__isupperchar(json5[parser->pos]) ||
96644 json5[parser->pos] == '_' || json5[parser->pos] == '$')
96645 continue;
96646 if(cj5__isnum(json5[parser->pos]) && parser->pos != start)
96647 continue;
96648 break;
96649 }
96650
96651 // An empty key is not allowed
96652 if(parser->pos <= start) {
96653 parser->error = CJ5_ERROR_INVALID;
96654 return;
96655 }
96656
96657 // Move pos to the last character within the unquoted key
96658 parser->pos--;
96659
96660 token = cj5__alloc_token(parser);
96661 if(token) {
96662 token->type = CJ5_TOKEN_STRING;
96663 token->start = start;
96664 token->end = parser->pos;
96665 token->size = parser->pos - start + 1;
96666 token->parent_id = parser->curr_tok_idx;
96667 }
96668}
96669
96670static void
96671cj5__skip_comment(cj5__parser* parser) {
96672 const char* json5 = parser->json5;
96673
96674 // Single-line comment
96675 if(json5[parser->pos] == '#') {
96676 skip_line:
96677 while(parser->pos < parser->len) {
96678 if(json5[parser->pos] == '\n') {
96679 parser->pos--; // Reparse the newline in the main parse loop
96680 return;
96681 }
96682 parser->pos++;
96683 }
96684 return;
96685 }
96686
96687 // Comment begins with '/' but not enough space for another character
96688 if(parser->pos + 1 >= parser->len) {
96689 parser->error = CJ5_ERROR_INVALID;
96690 return;
96691 }
96692 parser->pos++;
96693
96694 // Comment begins with '//' -> single-line comment
96695 if(json5[parser->pos] == '/')
96696 goto skip_line;
96697
96698 // Multi-line comments begin with '/*' and end with '*/'
96699 if(json5[parser->pos] == '*') {
96700 parser->pos++;
96701 for(; parser->pos + 1 < parser->len; parser->pos++) {
96702 if(json5[parser->pos] == '*' && json5[parser->pos + 1] == '/') {
96703 parser->pos++;
96704 return;
96705 }
96706 // Remember we passed a newline
96707 if(json5[parser->pos] == '\n') {
96708 parser->line++;
96709 parser->line_start = parser->pos;
96710 }
96711 }
96712 }
96713
96714 // Unknown comment type or the multi-line comment is not terminated
96715 parser->error = CJ5_ERROR_INCOMPLETE;
96716}
96717
96718cj5_result
96719cj5_parse(const char *json5, unsigned int len,
96720 cj5_token *tokens, unsigned int max_tokens,
96721 cj5_options *options) {
96722 cj5_result r;
96723 cj5__parser parser;
96724 memset(s: &parser, c: 0x0, n: sizeof(parser));
96725 parser.curr_tok_idx = 0;
96726 parser.json5 = json5;
96727 parser.len = len;
96728 parser.tokens = tokens;
96729 parser.max_tokens = max_tokens;
96730
96731 if(options)
96732 parser.stop_early = options->stop_early;
96733
96734 unsigned short depth = 0; // Nesting depth zero means "outside the root object"
96735 char nesting[CJ5_MAX_NESTING]; // Contains either '\0', '{' or '[' for the
96736 // type of nesting at each depth. '\0'
96737 // indicates we are out of the root object.
96738 char next[CJ5_MAX_NESTING]; // Next content to parse: 'k' (key), ':', 'v'
96739 // (value) or ',' (comma).
96740 next[0] = 'v'; // The root is a "value" (object, array or primitive). If we
96741 // detect a colon after the first value then everything is
96742 // wrapped into a "virtual root object" and the parsing is
96743 // restarted.
96744 nesting[0] = 0; // Becomes '{' if there is a virtual root object
96745
96746 cj5_token *token = NULL; // The current token
96747
96748 start_parsing:
96749 for(; parser.pos < len; parser.pos++) {
96750 char c = json5[parser.pos];
96751 switch(c) {
96752 case '\n': // Skip newline
96753 parser.line++;
96754 parser.line_start = parser.pos;
96755 break;
96756
96757 case '\r': // Skip whitespace
96758 case '\t':
96759 case ' ':
96760 break;
96761
96762 case '#': // Skip comment
96763 case '/':
96764 cj5__skip_comment(parser: &parser);
96765 if(parser.error != CJ5_ERROR_NONE &&
96766 parser.error != CJ5_ERROR_OVERFLOW)
96767 goto finish;
96768 break;
96769
96770 case '{': // Open an object or array
96771 case '[':
96772 // Check the nesting depth
96773 if(depth + 1 >= CJ5_MAX_NESTING) {
96774 parser.error = CJ5_ERROR_INVALID;
96775 goto finish;
96776 }
96777
96778 // Correct next?
96779 if(next[depth] != 'v') {
96780 parser.error = CJ5_ERROR_INVALID;
96781 goto finish;
96782 }
96783
96784 depth++; // Increase the nesting depth
96785 nesting[depth] = c; // Set the nesting type
96786 next[depth] = (c == '{') ? 'k' : 'v'; // next is either a key or a value
96787
96788 // Create a token for the object or array
96789 token = cj5__alloc_token(parser: &parser);
96790 if(token) {
96791 token->parent_id = parser.curr_tok_idx;
96792 token->type = (c == '{') ? CJ5_TOKEN_OBJECT : CJ5_TOKEN_ARRAY;
96793 token->start = parser.pos;
96794 token->size = 0;
96795 parser.curr_tok_idx = parser.token_count - 1; // The new curr_tok_idx
96796 // is for this token
96797 }
96798 break;
96799
96800 case '}': // Close an object or array
96801 case ']':
96802 // Check the nesting depth. Note that a "virtual root object" at
96803 // depth zero must not be closed.
96804 if(depth == 0) {
96805 parser.error = CJ5_ERROR_INVALID;
96806 goto finish;
96807 }
96808
96809 // Check and adjust the nesting. Note that ']' - '[' == 2 and '}' -
96810 // '{' == 2. Arrays can always be closed. Objects can only close
96811 // when a key or a comma is expected.
96812 if(c - nesting[depth] != 2 ||
96813 (c == '}' && next[depth] != 'k' && next[depth] != ',')) {
96814 parser.error = CJ5_ERROR_INVALID;
96815 goto finish;
96816 }
96817
96818 if(token) {
96819 // Finalize the current token
96820 token->end = parser.pos;
96821
96822 // Move to the parent and increase the parent size. Omit this
96823 // when we leave the root (parent the same as the current
96824 // token).
96825 if(parser.curr_tok_idx != token->parent_id) {
96826 parser.curr_tok_idx = token->parent_id;
96827 token = &tokens[token->parent_id];
96828 token->size++;
96829 }
96830 }
96831
96832 // Step one level up
96833 depth--;
96834 next[depth] = (depth == 0) ? 0 : ','; // zero if we step out the root
96835 // object. then we do not look for
96836 // another element.
96837
96838 // The first element was successfully parsed. Stop early or try to
96839 // parse the full input string?
96840 if(depth == 0 && parser.stop_early)
96841 goto finish;
96842
96843 break;
96844
96845 case ':': // Colon (between key and value)
96846 if(next[depth] != ':') {
96847 parser.error = CJ5_ERROR_INVALID;
96848 goto finish;
96849 }
96850 next[depth] = 'v';
96851 break;
96852
96853 case ',': // Comma
96854 if(next[depth] != ',') {
96855 parser.error = CJ5_ERROR_INVALID;
96856 goto finish;
96857 }
96858 next[depth] = (nesting[depth] == '{') ? 'k' : 'v';
96859 break;
96860
96861 default: // Value or key
96862 if(next[depth] == 'v') {
96863 cj5__parse_primitive(parser: &parser); // Parse primitive value
96864 if(nesting[depth] != 0) {
96865 // Parent is object or array
96866 if(token)
96867 token->size++;
96868 next[depth] = ',';
96869 } else {
96870 // The current value was the root element. Don't look for
96871 // any next element.
96872 next[depth] = 0;
96873
96874 // The first element was successfully parsed. Stop early or try to
96875 // parse the full input string?
96876 if(parser.stop_early)
96877 goto finish;
96878 }
96879 } else if(next[depth] == 'k') {
96880 cj5__parse_key(parser: &parser);
96881 if(token)
96882 token->size++; // Keys count towards the length
96883 next[depth] = ':';
96884 } else {
96885 parser.error = CJ5_ERROR_INVALID;
96886 }
96887
96888 if(parser.error && parser.error != CJ5_ERROR_OVERFLOW)
96889 goto finish;
96890
96891 break;
96892 }
96893 }
96894
96895 // Are we back to the initial nesting depth?
96896 if(depth != 0) {
96897 parser.error = CJ5_ERROR_INCOMPLETE;
96898 goto finish;
96899 }
96900
96901 // Close the virtual root object if there is one
96902 if(nesting[0] == '{' && parser.error != CJ5_ERROR_OVERFLOW) {
96903 // Check the we end after a complete key-value pair (or dangling comma)
96904 if(next[0] != 'k' && next[0] != ',')
96905 parser.error = CJ5_ERROR_INVALID;
96906 tokens[0].end = parser.pos - 1;
96907 }
96908
96909 finish:
96910 // If parsing failed at the initial nesting depth, create a virtual root object
96911 // and restart parsing.
96912 if(parser.error != CJ5_ERROR_NONE &&
96913 parser.error != CJ5_ERROR_OVERFLOW &&
96914 depth == 0 && nesting[0] != '{') {
96915 parser.token_count = 0;
96916 token = cj5__alloc_token(parser: &parser);
96917 if(token) {
96918 token->parent_id = 0;
96919 token->type = CJ5_TOKEN_OBJECT;
96920 token->start = 0;
96921 token->size = 0;
96922
96923 nesting[0] = '{';
96924 next[0] = 'k';
96925
96926 parser.curr_tok_idx = 0;
96927 parser.pos = 0;
96928 parser.error = CJ5_ERROR_NONE;
96929 goto start_parsing;
96930 }
96931 }
96932
96933 memset(s: &r, c: 0x0, n: sizeof(r));
96934 r.error = parser.error;
96935 r.error_line = parser.line;
96936 r.error_col = parser.pos - parser.line_start;
96937 r.num_tokens = parser.token_count; // How many tokens (would) have been
96938 // consumed by the parser?
96939
96940 // Not a single token was parsed -> return an error
96941 if(r.num_tokens == 0)
96942 r.error = CJ5_ERROR_INCOMPLETE;
96943
96944 // Set the tokens and original string only if successfully parsed
96945 if(r.error == CJ5_ERROR_NONE) {
96946 r.tokens = tokens;
96947 r.json5 = json5;
96948 }
96949
96950 return r;
96951}
96952
96953cj5_error_code
96954cj5_get_bool(const cj5_result *r, unsigned int tok_index, bool *out) {
96955 const cj5_token *token = &r->tokens[tok_index];
96956 if(token->type != CJ5_TOKEN_BOOL)
96957 return CJ5_ERROR_INVALID;
96958 *out = (r->json5[token->start] == 't');
96959 return CJ5_ERROR_NONE;
96960}
96961
96962cj5_error_code
96963cj5_get_float(const cj5_result *r, unsigned int tok_index, double *out) {
96964 const cj5_token *token = &r->tokens[tok_index];
96965 if(token->type != CJ5_TOKEN_NUMBER)
96966 return CJ5_ERROR_INVALID;
96967
96968 const char *tokstr = &r->json5[token->start];
96969 size_t toksize = token->end - token->start + 1;
96970 if(toksize == 0)
96971 return CJ5_ERROR_INVALID;
96972
96973 // Skip prefixed +/-
96974 bool neg = false;
96975 if(tokstr[0] == '+' || tokstr[0] == '-') {
96976 neg = (tokstr[0] == '-');
96977 tokstr++;
96978 toksize--;
96979 }
96980
96981 // Detect prefixed inf/nan
96982 if(strncmp(s1: tokstr, s2: "Infinity", n: toksize) == 0) {
96983 *out = neg ? -INFINITY : INFINITY;
96984 return CJ5_ERROR_NONE;
96985 } else if(strncmp(s1: tokstr, s2: "NaN", n: toksize) == 0) {
96986 *out = NAN;
96987 return CJ5_ERROR_NONE;
96988 }
96989
96990 // reset the +/- detection and parse
96991 tokstr = &r->json5[token->start];
96992 toksize = token->end - token->start + 1;
96993 size_t parsed = parseDouble(str: tokstr, size: toksize, result: out);
96994
96995 // There must only be whitespace between the end of the parsed number and
96996 // the end of the token
96997 for(size_t i = parsed; i < toksize; i++) {
96998 if(tokstr[i] != ' ' && tokstr[i] -'\t' >= 5)
96999 return CJ5_ERROR_INVALID;
97000 }
97001
97002 return (parsed != 0) ? CJ5_ERROR_NONE : CJ5_ERROR_INVALID;
97003}
97004
97005cj5_error_code
97006cj5_get_int(const cj5_result *r, unsigned int tok_index,
97007 int64_t *out) {
97008 const cj5_token *token = &r->tokens[tok_index];
97009 if(token->type != CJ5_TOKEN_NUMBER)
97010 return CJ5_ERROR_INVALID;
97011 size_t parsed = parseInt64(str: &r->json5[token->start], size: token->size, result: out);
97012 return (parsed != 0) ? CJ5_ERROR_NONE : CJ5_ERROR_INVALID;
97013}
97014
97015cj5_error_code
97016cj5_get_uint(const cj5_result *r, unsigned int tok_index,
97017 uint64_t *out) {
97018 const cj5_token *token = &r->tokens[tok_index];
97019 if(token->type != CJ5_TOKEN_NUMBER)
97020 return CJ5_ERROR_INVALID;
97021 size_t parsed = parseUInt64(str: &r->json5[token->start], size: token->size, result: out);
97022 return (parsed != 0) ? CJ5_ERROR_NONE : CJ5_ERROR_INVALID;
97023}
97024
97025static const uint32_t SURROGATE_OFFSET = 0x10000u - (0xD800u << 10) - 0xDC00;
97026
97027static cj5_error_code
97028parse_codepoint(const char *pos, uint32_t *out_utf) {
97029 uint32_t utf = 0;
97030 for(unsigned int i = 0; i < 4; i++) {
97031 char byte = pos[i];
97032 if(cj5__isnum(byte)) {
97033 byte = (char)(byte - '0');
97034 } else if(cj5__isrange(ch: byte, from: 'a', to: 'f')) {
97035 byte = (char)(byte - ('a' - 10));
97036 } else if(cj5__isrange(ch: byte, from: 'A', to: 'F')) {
97037 byte = (char)(byte - ('A' - 10));
97038 } else {
97039 return CJ5_ERROR_INVALID;
97040 }
97041 utf = (utf << 4) | ((uint8_t)byte & 0xF);
97042 }
97043 *out_utf = utf;
97044 return CJ5_ERROR_NONE;
97045}
97046
97047cj5_error_code
97048cj5_get_str(const cj5_result *r, unsigned int tok_index,
97049 char *buf, unsigned int *buflen) {
97050 const cj5_token *token = &r->tokens[tok_index];
97051 if(token->type != CJ5_TOKEN_STRING)
97052 return CJ5_ERROR_INVALID;
97053
97054 const char *pos = &r->json5[token->start];
97055 const char *end = &r->json5[token->end + 1];
97056 unsigned int outpos = 0;
97057 for(; pos < end; pos++) {
97058 uint8_t c = (uint8_t)*pos;
97059
97060 // Process an escape character
97061 if(c == '\\') {
97062 if(pos + 1 >= end)
97063 return CJ5_ERROR_INCOMPLETE;
97064 pos++;
97065 c = (uint8_t)*pos;
97066 switch(c) {
97067 case '\"': buf[outpos++] = '\"'; break;
97068 case '\\': buf[outpos++] = '\\'; break;
97069 case '\n': buf[outpos++] = '\n'; break; // escape newline
97070 case '/': buf[outpos++] = '/'; break;
97071 case 'b': buf[outpos++] = '\b'; break;
97072 case 'f': buf[outpos++] = '\f'; break;
97073 case 'r': buf[outpos++] = '\r'; break;
97074 case 'n': buf[outpos++] = '\n'; break;
97075 case 't': buf[outpos++] = '\t'; break;
97076 case 'u': {
97077 // Parse the unicode code point
97078 if(pos + 4 >= end)
97079 return CJ5_ERROR_INCOMPLETE;
97080 pos++;
97081 uint32_t utf;
97082 cj5_error_code err = parse_codepoint(pos, out_utf: &utf);
97083 if(err != CJ5_ERROR_NONE)
97084 return err;
97085 pos += 3;
97086
97087 if(0xD800 <= utf && utf <= 0xDBFF) {
97088 // Parse a surrogate pair
97089 if(pos + 6 >= end)
97090 return CJ5_ERROR_INVALID;
97091 if(pos[1] != '\\' && pos[3] != 'u')
97092 return CJ5_ERROR_INVALID;
97093 pos += 3;
97094 uint32_t trail;
97095 err = parse_codepoint(pos, out_utf: &trail);
97096 if(err != CJ5_ERROR_NONE)
97097 return err;
97098 pos += 3;
97099 utf = (utf << 10) + trail + SURROGATE_OFFSET;
97100 } else if(0xDC00 <= utf && utf <= 0xDFFF) {
97101 // Invalid Unicode '\\u%04X'
97102 return CJ5_ERROR_INVALID;
97103 }
97104
97105 // Write the utf8 bytes of the code point
97106 if(utf <= 0x7F) { // Plain ASCII
97107 buf[outpos++] = (char)utf;
97108 } else if(utf <= 0x07FF) { // 2-byte unicode
97109 buf[outpos++] = (char)(((utf >> 6) & 0x1F) | 0xC0);
97110 buf[outpos++] = (char)(((utf >> 0) & 0x3F) | 0x80);
97111 } else if(utf <= 0xFFFF) { // 3-byte unicode
97112 buf[outpos++] = (char)(((utf >> 12) & 0x0F) | 0xE0);
97113 buf[outpos++] = (char)(((utf >> 6) & 0x3F) | 0x80);
97114 buf[outpos++] = (char)(((utf >> 0) & 0x3F) | 0x80);
97115 } else if(utf <= 0x10FFFF) { // 4-byte unicode
97116 buf[outpos++] = (char)(((utf >> 18) & 0x07) | 0xF0);
97117 buf[outpos++] = (char)(((utf >> 12) & 0x3F) | 0x80);
97118 buf[outpos++] = (char)(((utf >> 6) & 0x3F) | 0x80);
97119 buf[outpos++] = (char)(((utf >> 0) & 0x3F) | 0x80);
97120 } else {
97121 return CJ5_ERROR_INVALID; // Not a utf8 string
97122 }
97123 break;
97124 }
97125 default:
97126 return CJ5_ERROR_INVALID;
97127 }
97128 continue;
97129 }
97130
97131 // Unprintable ascii characters must be escaped. JSON5 allows nested
97132 // quotes if the quote character is not the same as the surrounding
97133 // quote character, e.g. 'this is my "quote"'. This logic is in the
97134 // token parsing code and not in this "string extraction" method.
97135 if(c < ' ' || c == 127)
97136 return CJ5_ERROR_INVALID;
97137
97138 // Ascii character or utf8 byte
97139 buf[outpos++] = (char)c;
97140 }
97141
97142 // Terminate with \0
97143 buf[outpos] = 0;
97144
97145 // Set the output length
97146 if(buflen)
97147 *buflen = outpos;
97148 return CJ5_ERROR_NONE;
97149}
97150
97151void
97152cj5_skip(const cj5_result *r, unsigned int *tok_index) {
97153 unsigned int idx = *tok_index;
97154 unsigned int end = r->tokens[idx].end;
97155 do { idx++; } while(idx < r->num_tokens &&
97156 r->tokens[idx].start < end);
97157 *tok_index = idx;
97158}
97159
97160cj5_error_code
97161cj5_find(const cj5_result *r, unsigned int *tok_index,
97162 const char *key) {
97163 // It has to be an object
97164 unsigned int idx = *tok_index;
97165 if(r->tokens[idx].type != CJ5_TOKEN_OBJECT)
97166 return CJ5_ERROR_INVALID;
97167 unsigned int size = r->tokens[idx].size;
97168
97169 // Skip to the first key
97170 idx++;
97171
97172 // Size is number of keys + number of values
97173 for(unsigned int i = 0; i < size; i += 2) {
97174 // Key has to be a string
97175 if(r->tokens[idx].type != CJ5_TOKEN_STRING)
97176 return CJ5_ERROR_INVALID;
97177
97178 // Return the index to the value if the key matches
97179 const char *keystart = &r->json5[r->tokens[idx].start];
97180 size_t keysize = r->tokens[idx].end - r->tokens[idx].start + 1;
97181 if(strncmp(s1: key, s2: keystart, n: keysize) == 0) {
97182 *tok_index = idx + 1;
97183 return CJ5_ERROR_NONE;
97184 }
97185
97186 // Skip over the value
97187 idx++;
97188 cj5_skip(r, tok_index: &idx);
97189 }
97190 return CJ5_ERROR_NOTFOUND;
97191}
97192
97193/**** amalgamated original file "/deps/parse_num.c" ****/
97194
97195/* Originally released by the musl project (http://www.musl-libc.org/) under the
97196 * MIT license. Taken and adapted from the file src/stdlib/atoi.c
97197 *
97198 * Permission is hereby granted, free of charge, to any person obtaining a copy
97199 * of this software and associated documentation files (the "Software"), to deal
97200 * in the Software without restriction, including without limitation the rights
97201 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
97202 * copies of the Software, and to permit persons to whom the Software is
97203 * furnished to do so, subject to the following conditions:
97204 *
97205 * The above copyright notice and this permission notice shall be included in
97206 * all copies or substantial portions of the Software.
97207 *
97208 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
97209 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
97210 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
97211 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
97212 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
97213 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
97214 * THE SOFTWARE.
97215 */
97216
97217
97218#include <string.h>
97219#include <stdlib.h>
97220#include <errno.h>
97221
97222size_t
97223parseUInt64(const char *str, size_t size, uint64_t *result) {
97224 size_t i = 0;
97225 uint64_t n = 0, prev = 0;
97226
97227 /* Hex */
97228 if(size > 2 && str[0] == '0' && (str[1] | 32) == 'x') {
97229 i = 2;
97230 for(; i < size; i++) {
97231 uint8_t c = (uint8_t)str[i] | 32;
97232 if(c >= '0' && c <= '9')
97233 c = (uint8_t)(c - '0');
97234 else if(c >= 'a' && c <='f')
97235 c = (uint8_t)(c - 'a' + 10);
97236 else if(c >= 'A' && c <='F')
97237 c = (uint8_t)(c - 'A' + 10);
97238 else
97239 break;
97240 n = (n << 4) | (c & 0xF);
97241 if(n < prev) /* Check for overflow */
97242 return 0;
97243 prev = n;
97244 }
97245 *result = n;
97246 return (i > 2) ? i : 0; /* 2 -> No digit was parsed */
97247 }
97248
97249 /* Decimal */
97250 for(; i < size; i++) {
97251 if(str[i] < '0' || str[i] > '9')
97252 break;
97253 /* Fast multiplication: n*10 == (n*8) + (n*2) */
97254 n = (n << 3) + (n << 1) + (uint8_t)(str[i] - '0');
97255 if(n < prev) /* Check for overflow */
97256 return 0;
97257 prev = n;
97258 }
97259 *result = n;
97260 return i;
97261}
97262
97263size_t
97264parseInt64(const char *str, size_t size, int64_t *result) {
97265 /* Negative value? */
97266 size_t i = 0;
97267 bool neg = false;
97268 if(*str == '-' || *str == '+') {
97269 neg = (*str == '-');
97270 i++;
97271 }
97272
97273 /* Parse as unsigned */
97274 uint64_t n = 0;
97275 size_t len = parseUInt64(str: &str[i], size: size - i, result: &n);
97276 if(len == 0)
97277 return 0;
97278
97279 /* Check for overflow, adjust and return */
97280 if(!neg) {
97281 if(n > 9223372036854775807UL)
97282 return 0;
97283 *result = (int64_t)n;
97284 } else {
97285 if(n > 9223372036854775808UL)
97286 return 0;
97287 *result = -(int64_t)n;
97288 }
97289 return len + i;
97290}
97291
97292size_t parseDouble(const char *str, size_t size, double *result) {
97293 char buf[2000];
97294 if(size >= 2000)
97295 return 0;
97296 memcpy(dest: buf, src: str, n: size);
97297 buf[size] = 0;
97298 errno = 0;
97299 char *endptr;
97300 *result = strtod(nptr: str, endptr: &endptr);
97301 if(errno != 0 && errno != ERANGE)
97302 return 0;
97303 return (uintptr_t)endptr - (uintptr_t)str;
97304}
97305
97306/**** amalgamated original file "/src/ua_types_encoding_json.c" ****/
97307
97308/* This Source Code Form is subject to the terms of the Mozilla Public
97309 * License, v. 2.0. If a copy of the MPL was not distributed with this
97310 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
97311 *
97312 * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
97313 * Copyright 2018 (c) Fraunhofer IOSB (Author: Lukas Meling)
97314 */
97315
97316
97317#ifdef UA_ENABLE_JSON_ENCODING
97318
97319
97320#include <float.h>
97321#include <math.h>
97322
97323
97324#ifndef UA_ENABLE_PARSING
97325#error UA_ENABLE_PARSING required for JSON encoding
97326#endif
97327
97328#ifndef UA_ENABLE_TYPEDESCRIPTION
97329#error UA_ENABLE_TYPEDESCRIPTION required for JSON encoding
97330#endif
97331
97332/* vs2008 does not have INFINITY and NAN defined */
97333#ifndef INFINITY
97334# define INFINITY ((UA_Double)(DBL_MAX+DBL_MAX))
97335#endif
97336#ifndef NAN
97337# define NAN ((UA_Double)(INFINITY-INFINITY))
97338#endif
97339
97340#if defined(_MSC_VER)
97341# pragma warning(disable: 4756)
97342# pragma warning(disable: 4056)
97343#endif
97344
97345/* Have some slack at the end. E.g. for negative and very long years. */
97346#define UA_JSON_DATETIME_LENGTH 40
97347
97348/************/
97349/* Encoding */
97350/************/
97351
97352#define ENCODE_JSON(TYPE) static status \
97353 TYPE##_encodeJson(CtxJson *ctx, const UA_##TYPE *src, const UA_DataType *type)
97354
97355#define ENCODE_DIRECT_JSON(SRC, TYPE) \
97356 TYPE##_encodeJson(ctx, (const UA_##TYPE*)SRC, NULL)
97357
97358static status UA_FUNC_ATTR_WARN_UNUSED_RESULT
97359writeChar(CtxJson *ctx, char c) {
97360 if(ctx->pos >= ctx->end)
97361 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97362 if(!ctx->calcOnly)
97363 *ctx->pos = (UA_Byte)c;
97364 ctx->pos++;
97365 return UA_STATUSCODE_GOOD;
97366}
97367
97368static status UA_FUNC_ATTR_WARN_UNUSED_RESULT
97369writeChars(CtxJson *ctx, const char *c, size_t len) {
97370 if(ctx->pos + len > ctx->end)
97371 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97372 if(!ctx->calcOnly)
97373 memcpy(dest: ctx->pos, src: c, n: len);
97374 ctx->pos += len;
97375 return UA_STATUSCODE_GOOD;
97376}
97377
97378#define WRITE_JSON_ELEMENT(ELEM) \
97379 UA_FUNC_ATTR_WARN_UNUSED_RESULT status \
97380 writeJson##ELEM(CtxJson *ctx)
97381
97382static WRITE_JSON_ELEMENT(Quote) {
97383 return writeChar(ctx, c: '\"');
97384}
97385
97386UA_StatusCode
97387writeJsonBeforeElement(CtxJson *ctx, UA_Boolean distinct) {
97388 UA_StatusCode res = UA_STATUSCODE_GOOD;
97389 /* Comma if needed */
97390 if(ctx->commaNeeded[ctx->depth])
97391 res |= writeChar(ctx, c: ',');
97392 if(ctx->prettyPrint) {
97393 if(distinct) {
97394 /* Newline and indent if needed */
97395 res |= writeChar(ctx, c: '\n');
97396 for(size_t i = 0; i < ctx->depth; i++)
97397 res |= writeChar(ctx, c: '\t');
97398 } else if(ctx->commaNeeded[ctx->depth]) {
97399 /* Space after the comma if no newline */
97400 res |= writeChar(ctx, c: ' ');
97401 }
97402 }
97403 return res;
97404}
97405
97406WRITE_JSON_ELEMENT(ObjStart) {
97407 /* increase depth, save: before first key-value no comma needed. */
97408 if(ctx->depth >= UA_JSON_ENCODING_MAX_RECURSION - 1)
97409 return UA_STATUSCODE_BADENCODINGERROR;
97410 ctx->depth++;
97411 ctx->commaNeeded[ctx->depth] = false;
97412 return writeChar(ctx, c: '{');
97413}
97414
97415WRITE_JSON_ELEMENT(ObjEnd) {
97416 if(ctx->depth == 0)
97417 return UA_STATUSCODE_BADENCODINGERROR;
97418
97419 UA_Boolean have_elem = ctx->commaNeeded[ctx->depth];
97420 ctx->depth--;
97421 ctx->commaNeeded[ctx->depth] = true;
97422
97423 UA_StatusCode res = UA_STATUSCODE_GOOD;
97424 if(ctx->prettyPrint && have_elem) {
97425 res |= writeChar(ctx, c: '\n');
97426 for(size_t i = 0; i < ctx->depth; i++)
97427 res |= writeChar(ctx, c: '\t');
97428 }
97429 return res | writeChar(ctx, c: '}');
97430}
97431
97432WRITE_JSON_ELEMENT(ArrStart) {
97433 /* increase depth, save: before first array entry no comma needed. */
97434 if(ctx->depth >= UA_JSON_ENCODING_MAX_RECURSION - 1)
97435 return UA_STATUSCODE_BADENCODINGERROR;
97436 ctx->depth++;
97437 ctx->commaNeeded[ctx->depth] = false;
97438 return writeChar(ctx, c: '[');
97439}
97440
97441WRITE_JSON_ELEMENT(ArrEnd) {
97442 if(ctx->depth == 0)
97443 return UA_STATUSCODE_BADENCODINGERROR;
97444 UA_Boolean have_elem = ctx->commaNeeded[ctx->depth];
97445 ctx->depth--;
97446 ctx->commaNeeded[ctx->depth] = true;
97447 UA_StatusCode res = UA_STATUSCODE_GOOD;
97448 if(ctx->prettyPrint && have_elem) {
97449 res |= writeChar(ctx, c: '\n');
97450 for(size_t i = 0; i < ctx->depth; i++)
97451 res |= writeChar(ctx, c: '\t');
97452 }
97453 return res | writeChar(ctx, c: ']');
97454}
97455
97456status
97457writeJsonArrElm(CtxJson *ctx, const void *value,
97458 const UA_DataType *type) {
97459 UA_Boolean distinct = (type->typeKind > UA_DATATYPEKIND_DOUBLE);
97460 status ret = writeJsonBeforeElement(ctx, distinct);
97461 ctx->commaNeeded[ctx->depth] = true;
97462 return ret | encodeJsonJumpTable[type->typeKind](ctx, value, type);
97463}
97464
97465status
97466writeJsonObjElm(CtxJson *ctx, const char *key,
97467 const void *value, const UA_DataType *type) {
97468 return writeJsonKey(ctx, key) | encodeJsonJumpTable[type->typeKind](ctx, value, type);
97469}
97470
97471/* Keys for JSON */
97472
97473/* LocalizedText */
97474static const char* UA_JSONKEY_LOCALE = "Locale";
97475static const char* UA_JSONKEY_TEXT = "Text";
97476
97477/* QualifiedName */
97478static const char* UA_JSONKEY_NAME = "Name";
97479static const char* UA_JSONKEY_URI = "Uri";
97480
97481/* NodeId */
97482static const char* UA_JSONKEY_ID = "Id";
97483static const char* UA_JSONKEY_IDTYPE = "IdType";
97484static const char* UA_JSONKEY_NAMESPACE = "Namespace";
97485
97486/* ExpandedNodeId */
97487static const char* UA_JSONKEY_SERVERURI = "ServerUri";
97488
97489/* Variant */
97490static const char* UA_JSONKEY_TYPE = "Type";
97491static const char* UA_JSONKEY_BODY = "Body";
97492static const char* UA_JSONKEY_DIMENSION = "Dimension";
97493
97494/* DataValue */
97495static const char* UA_JSONKEY_VALUE = "Value";
97496static const char* UA_JSONKEY_STATUS = "Status";
97497static const char* UA_JSONKEY_SOURCETIMESTAMP = "SourceTimestamp";
97498static const char* UA_JSONKEY_SOURCEPICOSECONDS = "SourcePicoseconds";
97499static const char* UA_JSONKEY_SERVERTIMESTAMP = "ServerTimestamp";
97500static const char* UA_JSONKEY_SERVERPICOSECONDS = "ServerPicoseconds";
97501
97502/* ExtensionObject */
97503static const char* UA_JSONKEY_ENCODING = "Encoding";
97504static const char* UA_JSONKEY_TYPEID = "TypeId";
97505
97506/* StatusCode */
97507static const char* UA_JSONKEY_CODE = "Code";
97508static const char* UA_JSONKEY_SYMBOL = "Symbol";
97509
97510/* DiagnosticInfo */
97511static const char* UA_JSONKEY_SYMBOLICID = "SymbolicId";
97512static const char* UA_JSONKEY_NAMESPACEURI = "NamespaceUri";
97513static const char* UA_JSONKEY_LOCALIZEDTEXT = "LocalizedText";
97514static const char* UA_JSONKEY_ADDITIONALINFO = "AdditionalInfo";
97515static const char* UA_JSONKEY_INNERSTATUSCODE = "InnerStatusCode";
97516static const char* UA_JSONKEY_INNERDIAGNOSTICINFO = "InnerDiagnosticInfo";
97517
97518/* Writes null terminated string to output buffer (current ctx->pos). Writes
97519 * comma in front of key if needed. Encapsulates key in quotes. */
97520status UA_FUNC_ATTR_WARN_UNUSED_RESULT
97521writeJsonKey(CtxJson *ctx, const char* key) {
97522 status ret = writeJsonBeforeElement(ctx, true);
97523 ctx->commaNeeded[ctx->depth] = true;
97524 if(!ctx->unquotedKeys)
97525 ret |= writeChar(ctx, c: '\"');
97526 ret |= writeChars(ctx, c: key, len: strlen(s: key));
97527 if(!ctx->unquotedKeys)
97528 ret |= writeChar(ctx, c: '\"');
97529 if(!ctx->unquotedKeys)
97530 ret |= writeChar(ctx, c: ':');
97531 if(ctx->prettyPrint)
97532 ret |= writeChar(ctx, c: ' ');
97533 return ret;
97534}
97535
97536static bool
97537isNull(const void *p, const UA_DataType *type) {
97538 if(UA_DataType_isNumeric(type) || type->typeKind == UA_DATATYPEKIND_BOOLEAN)
97539 return false;
97540 UA_STACKARRAY(char, buf, type->memSize);
97541 memset(s: buf, c: 0, n: type->memSize);
97542 return UA_equal(p1: buf, p2: p, type);
97543}
97544
97545/* Boolean */
97546ENCODE_JSON(Boolean) {
97547 if(*src == true)
97548 return writeChars(ctx, c: "true", len: 4);
97549 return writeChars(ctx, c: "false", len: 5);
97550}
97551
97552/* Byte */
97553ENCODE_JSON(Byte) {
97554 char buf[4];
97555 UA_UInt16 digits = itoaUnsigned(value: *src, buffer: buf, base: 10);
97556
97557 /* Ensure destination can hold the data- */
97558 if(ctx->pos + digits > ctx->end)
97559 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97560
97561 /* Copy digits to the output string/buffer. */
97562 if(!ctx->calcOnly)
97563 memcpy(dest: ctx->pos, src: buf, n: digits);
97564 ctx->pos += digits;
97565 return UA_STATUSCODE_GOOD;
97566}
97567
97568/* signed Byte */
97569ENCODE_JSON(SByte) {
97570 char buf[5];
97571 UA_UInt16 digits = itoaSigned(value: *src, buffer: buf);
97572 if(ctx->pos + digits > ctx->end)
97573 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97574 if(!ctx->calcOnly)
97575 memcpy(dest: ctx->pos, src: buf, n: digits);
97576 ctx->pos += digits;
97577 return UA_STATUSCODE_GOOD;
97578}
97579
97580/* UInt16 */
97581ENCODE_JSON(UInt16) {
97582 char buf[6];
97583 UA_UInt16 digits = itoaUnsigned(value: *src, buffer: buf, base: 10);
97584
97585 if(ctx->pos + digits > ctx->end)
97586 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97587
97588 if(!ctx->calcOnly)
97589 memcpy(dest: ctx->pos, src: buf, n: digits);
97590 ctx->pos += digits;
97591 return UA_STATUSCODE_GOOD;
97592}
97593
97594/* Int16 */
97595ENCODE_JSON(Int16) {
97596 char buf[7];
97597 UA_UInt16 digits = itoaSigned(value: *src, buffer: buf);
97598
97599 if(ctx->pos + digits > ctx->end)
97600 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97601
97602 if(!ctx->calcOnly)
97603 memcpy(dest: ctx->pos, src: buf, n: digits);
97604 ctx->pos += digits;
97605 return UA_STATUSCODE_GOOD;
97606}
97607
97608/* UInt32 */
97609ENCODE_JSON(UInt32) {
97610 char buf[11];
97611 UA_UInt16 digits = itoaUnsigned(value: *src, buffer: buf, base: 10);
97612
97613 if(ctx->pos + digits > ctx->end)
97614 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97615
97616 if(!ctx->calcOnly)
97617 memcpy(dest: ctx->pos, src: buf, n: digits);
97618 ctx->pos += digits;
97619 return UA_STATUSCODE_GOOD;
97620}
97621
97622/* Int32 */
97623ENCODE_JSON(Int32) {
97624 char buf[12];
97625 UA_UInt16 digits = itoaSigned(value: *src, buffer: buf);
97626
97627 if(ctx->pos + digits > ctx->end)
97628 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97629
97630 if(!ctx->calcOnly)
97631 memcpy(dest: ctx->pos, src: buf, n: digits);
97632 ctx->pos += digits;
97633 return UA_STATUSCODE_GOOD;
97634}
97635
97636/* UInt64 */
97637ENCODE_JSON(UInt64) {
97638 char buf[23];
97639 buf[0] = '\"';
97640 UA_UInt16 digits = itoaUnsigned(value: *src, buffer: buf + 1, base: 10);
97641 buf[digits + 1] = '\"';
97642 UA_UInt16 length = (UA_UInt16)(digits + 2);
97643
97644 if(ctx->pos + length > ctx->end)
97645 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97646
97647 if(!ctx->calcOnly)
97648 memcpy(dest: ctx->pos, src: buf, n: length);
97649 ctx->pos += length;
97650 return UA_STATUSCODE_GOOD;
97651}
97652
97653/* Int64 */
97654ENCODE_JSON(Int64) {
97655 char buf[23];
97656 buf[0] = '\"';
97657 UA_UInt16 digits = itoaSigned(value: *src, buffer: buf + 1);
97658 buf[digits + 1] = '\"';
97659 UA_UInt16 length = (UA_UInt16)(digits + 2);
97660
97661 if(ctx->pos + length > ctx->end)
97662 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97663
97664 if(!ctx->calcOnly)
97665 memcpy(dest: ctx->pos, src: buf, n: length);
97666 ctx->pos += length;
97667 return UA_STATUSCODE_GOOD;
97668}
97669
97670ENCODE_JSON(Float) {
97671 char buffer[32];
97672 size_t len;
97673 if(*src != *src) {
97674 strcpy(dest: buffer, src: "\"NaN\"");
97675 len = strlen(s: buffer);
97676 } else if(*src == INFINITY) {
97677 strcpy(dest: buffer, src: "\"Infinity\"");
97678 len = strlen(s: buffer);
97679 } else if(*src == -INFINITY) {
97680 strcpy(dest: buffer, src: "\"-Infinity\"");
97681 len = strlen(s: buffer);
97682 } else {
97683 len = dtoa(d: (UA_Double)*src, buffer);
97684 }
97685
97686 if(ctx->pos + len > ctx->end)
97687 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97688
97689 if(!ctx->calcOnly)
97690 memcpy(dest: ctx->pos, src: buffer, n: len);
97691 ctx->pos += len;
97692 return UA_STATUSCODE_GOOD;
97693}
97694
97695ENCODE_JSON(Double) {
97696 char buffer[32];
97697 size_t len;
97698 if(*src != *src) {
97699 strcpy(dest: buffer, src: "\"NaN\"");
97700 len = strlen(s: buffer);
97701 } else if(*src == INFINITY) {
97702 strcpy(dest: buffer, src: "\"Infinity\"");
97703 len = strlen(s: buffer);
97704 } else if(*src == -INFINITY) {
97705 strcpy(dest: buffer, src: "\"-Infinity\"");
97706 len = strlen(s: buffer);
97707 } else {
97708 len = dtoa(d: *src, buffer);
97709 }
97710
97711 if(ctx->pos + len > ctx->end)
97712 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97713
97714 if(!ctx->calcOnly)
97715 memcpy(dest: ctx->pos, src: buffer, n: len);
97716 ctx->pos += len;
97717 return UA_STATUSCODE_GOOD;
97718}
97719
97720static status
97721encodeJsonArray(CtxJson *ctx, const void *ptr, size_t length,
97722 const UA_DataType *type) {
97723 /* Null-arrays (length -1) are written as empty arrays '[]'.
97724 * TODO: Clarify the difference between length -1 and length 0 in JSON. */
97725 status ret = writeJsonArrStart(ctx);
97726 if(!ptr)
97727 return ret | writeJsonArrEnd(ctx);
97728
97729 uintptr_t uptr = (uintptr_t)ptr;
97730 encodeJsonSignature encodeType = encodeJsonJumpTable[type->typeKind];
97731 UA_Boolean distinct = (type->typeKind > UA_DATATYPEKIND_DOUBLE);
97732 for(size_t i = 0; i < length && ret == UA_STATUSCODE_GOOD; ++i) {
97733 ret |= writeJsonBeforeElement(ctx, distinct);
97734 if(isNull(p: (const void*)uptr, type))
97735 ret |= writeChars(ctx, c: "null", len: 4);
97736 else
97737 ret |= encodeType(ctx, (const void*)uptr, type);
97738 ctx->commaNeeded[ctx->depth] = true;
97739 uptr += type->memSize;
97740 }
97741 return ret | writeJsonArrEnd(ctx);
97742}
97743
97744static const uint32_t min_codepoints[5] = {0x00, 0x00, 0x80, 0x800, 0x10000};
97745static const u8 hexmap[16] =
97746 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
97747
97748/* Extract the next utf8 codepoint from the buffer. Return the next position in
97749 * the buffer or NULL upon an error. */
97750static const unsigned char *
97751extract_codepoint(const unsigned char *pos, size_t len, uint32_t *codepoint) {
97752 UA_assert(len > 0);
97753
97754 *codepoint = pos[0];
97755 if(UA_LIKELY(*codepoint < 0x80))
97756 return pos + 1; /* Normal ASCII */
97757
97758 if(UA_UNLIKELY(*codepoint <= 0xC1))
97759 return NULL; /* Continuation byte not allowed here */
97760
97761 unsigned char count;
97762 if(*codepoint <= 0xDF) {
97763 count = 2; /* 2-byte sequence */
97764 *codepoint &= 0x1F;
97765 } else if(*codepoint <= 0xEF) {
97766 count = 3; /* 3-byte sequence */
97767 *codepoint &= 0xF;
97768 } else if(*codepoint <= 0xF4) {
97769 count = 4; /* 4-byte sequence */
97770 *codepoint &= 0x7;
97771 } else {
97772 return NULL; /* invalid utf8 */
97773 }
97774
97775 if(UA_UNLIKELY(count > len))
97776 return NULL; /* Not enough bytes left */
97777
97778 for(unsigned char i = 1; i < count; i++) {
97779 unsigned char byte = pos[i];
97780 if(UA_UNLIKELY(byte < 0x80 || byte > 0xBF))
97781 return NULL; /* Not a continuation byte */
97782 *codepoint = (*codepoint << 6) + (byte & 0x3F);
97783 }
97784
97785 /* Not in Unicode range or too small for the encoding length */
97786 if(UA_UNLIKELY(*codepoint > 0x10FFFF || *codepoint < min_codepoints[count]))
97787 return NULL;
97788
97789 return pos + count; /* Return the new position in the pos */
97790}
97791
97792ENCODE_JSON(String) {
97793 if(!src->data)
97794 return writeChars(ctx, c: "null", len: 4);
97795
97796 if(src->length == 0)
97797 return writeJsonQuote(ctx) | writeJsonQuote(ctx);
97798
97799 UA_StatusCode ret = writeJsonQuote(ctx);
97800
97801 const unsigned char *str = src->data;
97802 const unsigned char *pos = str;
97803 const unsigned char *end = str;
97804 const unsigned char *lim = str + src->length;
97805 uint32_t codepoint = 0;
97806 while(1) {
97807 /* Iterate over codepoints in the utf8 encoding. Until the first
97808 * character that needs to be escaped. */
97809 while(end < lim) {
97810 end = extract_codepoint(pos, len: (size_t)(lim - pos), codepoint: &codepoint);
97811 if(!end) {
97812 /* A malformed utf8 character. Print anyway and let the
97813 * receiving side choose how to handle it. */
97814 pos++;
97815 end = pos;
97816 continue;
97817 }
97818
97819 /* Escape unprintable ASCII and escape characters */
97820 if(codepoint < ' ' || codepoint == 127 ||
97821 codepoint == '\\' || codepoint == '\"')
97822 break;
97823
97824 pos = end;
97825 }
97826
97827 /* Write out the characters that don't need escaping */
97828 if(pos != str) {
97829 if(ctx->pos + (pos - str) > ctx->end)
97830 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97831 if(!ctx->calcOnly)
97832 memcpy(dest: ctx->pos, src: str, n: (size_t)(pos - str));
97833 ctx->pos += pos - str;
97834 }
97835
97836 /* Reached the end of the utf8 encoding */
97837 if(end == pos)
97838 break;
97839
97840 /* Handle an escaped character */
97841 size_t length = 2;
97842 u8 seq[13];
97843 const char *text;
97844
97845 switch(codepoint) {
97846 case '\\': text = "\\\\"; break;
97847 case '\"': text = "\\\""; break;
97848 case '\b': text = "\\b"; break;
97849 case '\f': text = "\\f"; break;
97850 case '\n': text = "\\n"; break;
97851 case '\r': text = "\\r"; break;
97852 case '\t': text = "\\t"; break;
97853 default:
97854 text = (char*)seq;
97855 if(codepoint < 0x10000) {
97856 /* codepoint is in BMP */
97857 seq[0] = '\\';
97858 seq[1] = 'u';
97859 UA_Byte b1 = (UA_Byte)(codepoint >> 8u);
97860 UA_Byte b2 = (UA_Byte)(codepoint >> 0u);
97861 seq[2] = hexmap[(b1 & 0xF0u) >> 4u];
97862 seq[3] = hexmap[b1 & 0x0Fu];
97863 seq[4] = hexmap[(b2 & 0xF0u) >> 4u];
97864 seq[5] = hexmap[b2 & 0x0Fu];
97865 length = 6;
97866 } else {
97867 /* not in BMP -> construct a UTF-16 surrogate pair */
97868 codepoint -= 0x10000;
97869 UA_UInt32 first = 0xD800u | ((codepoint & 0xffc00u) >> 10u);
97870 UA_UInt32 last = 0xDC00u | (codepoint & 0x003ffu);
97871 UA_Byte fb1 = (UA_Byte)(first >> 8u);
97872 UA_Byte fb2 = (UA_Byte)(first >> 0u);
97873 UA_Byte lb1 = (UA_Byte)(last >> 8u);
97874 UA_Byte lb2 = (UA_Byte)(last >> 0u);
97875 seq[0] = '\\';
97876 seq[1] = 'u';
97877 seq[2] = hexmap[(fb1 & 0xF0u) >> 4u];
97878 seq[3] = hexmap[fb1 & 0x0Fu];
97879 seq[4] = hexmap[(fb2 & 0xF0u) >> 4u];
97880 seq[5] = hexmap[fb2 & 0x0Fu];
97881 seq[6] = '\\';
97882 seq[7] = 'u';
97883 seq[8] = hexmap[(lb1 & 0xF0u) >> 4u];
97884 seq[9] = hexmap[lb1 & 0x0Fu];
97885 seq[10] = hexmap[(lb2 & 0xF0u) >> 4u];
97886 seq[11] = hexmap[lb2 & 0x0Fu];
97887 length = 12;
97888 }
97889 break;
97890 }
97891 if(ctx->pos + length > ctx->end)
97892 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97893 if(!ctx->calcOnly)
97894 memcpy(dest: ctx->pos, src: text, n: length);
97895 ctx->pos += length;
97896 str = pos = end;
97897 }
97898
97899 return ret | writeJsonQuote(ctx);
97900}
97901
97902ENCODE_JSON(ByteString) {
97903 if(!src->data)
97904 return writeChars(ctx, c: "null", len: 4);
97905
97906 if(src->length == 0) {
97907 status retval = writeJsonQuote(ctx);
97908 retval |= writeJsonQuote(ctx);
97909 return retval;
97910 }
97911
97912 status ret = writeJsonQuote(ctx);
97913 size_t flen = 0;
97914 unsigned char *ba64 = UA_base64(src: src->data, len: src->length, out_len: &flen);
97915
97916 /* Not converted, no mem */
97917 if(!ba64)
97918 return UA_STATUSCODE_BADENCODINGERROR;
97919
97920 if(ctx->pos + flen > ctx->end) {
97921 UA_free(ptr: ba64);
97922 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97923 }
97924
97925 /* Copy flen bytes to output stream. */
97926 if(!ctx->calcOnly)
97927 memcpy(dest: ctx->pos, src: ba64, n: flen);
97928 ctx->pos += flen;
97929
97930 /* Base64 result no longer needed */
97931 UA_free(ptr: ba64);
97932
97933 return ret | writeJsonQuote(ctx);
97934}
97935
97936/* Guid */
97937ENCODE_JSON(Guid) {
97938 if(ctx->pos + 38 > ctx->end) /* 36 + 2 (") */
97939 return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
97940 status ret = writeJsonQuote(ctx);
97941 if(!ctx->calcOnly)
97942 UA_Guid_to_hex(guid: src, out: ctx->pos, false);
97943 ctx->pos += 36;
97944 return ret | writeJsonQuote(ctx);
97945}
97946
97947static u8
97948printNumber(i32 n, char *pos, u8 min_digits) {
97949 char digits[10];
97950 u8 len = 0;
97951 /* Handle negative values */
97952 if(n < 0) {
97953 pos[len++] = '-';
97954 n = -n;
97955 }
97956
97957 /* Extract the digits */
97958 u8 i = 0;
97959 for(; i < min_digits || n > 0; i++) {
97960 digits[i] = (char)((n % 10) + '0');
97961 n /= 10;
97962 }
97963
97964 /* Print in reverse order and return */
97965 for(; i > 0; i--)
97966 pos[len++] = digits[i-1];
97967 return len;
97968}
97969
97970ENCODE_JSON(DateTime) {
97971 UA_DateTimeStruct tSt = UA_DateTime_toStruct(t: *src);
97972
97973 /* Format: -yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS'Z' is used. max 31 bytes.
97974 * Note the optional minus for negative years. */
97975 char buffer[UA_JSON_DATETIME_LENGTH];
97976 char *pos = buffer;
97977 pos += printNumber(n: tSt.year, pos, min_digits: 4);
97978 *(pos++) = '-';
97979 pos += printNumber(n: tSt.month, pos, min_digits: 2);
97980 *(pos++) = '-';
97981 pos += printNumber(n: tSt.day, pos, min_digits: 2);
97982 *(pos++) = 'T';
97983 pos += printNumber(n: tSt.hour, pos, min_digits: 2);
97984 *(pos++) = ':';
97985 pos += printNumber(n: tSt.min, pos, min_digits: 2);
97986 *(pos++) = ':';
97987 pos += printNumber(n: tSt.sec, pos, min_digits: 2);
97988 *(pos++) = '.';
97989 pos += printNumber(n: tSt.milliSec, pos, min_digits: 3);
97990 pos += printNumber(n: tSt.microSec, pos, min_digits: 3);
97991 pos += printNumber(n: tSt.nanoSec, pos, min_digits: 3);
97992
97993 UA_assert(pos <= &buffer[UA_JSON_DATETIME_LENGTH]);
97994
97995 /* Remove trailing zeros */
97996 pos--;
97997 while(*pos == '0')
97998 pos--;
97999 if(*pos == '.')
98000 pos--;
98001
98002 *(++pos) = 'Z';
98003 UA_String str = {((uintptr_t)pos - (uintptr_t)buffer)+1, (UA_Byte*)buffer};
98004 return ENCODE_DIRECT_JSON(&str, String);
98005}
98006
98007/* NodeId */
98008static status
98009NodeId_encodeJsonInternal(CtxJson *ctx, UA_NodeId const *src) {
98010 status ret = UA_STATUSCODE_GOOD;
98011 switch(src->identifierType) {
98012 case UA_NODEIDTYPE_NUMERIC:
98013 ret |= writeJsonKey(ctx, key: UA_JSONKEY_ID);
98014 ret |= ENCODE_DIRECT_JSON(&src->identifier.numeric, UInt32);
98015 break;
98016 case UA_NODEIDTYPE_STRING:
98017 ret |= writeJsonKey(ctx, key: UA_JSONKEY_IDTYPE);
98018 ret |= writeChar(ctx, c: '1');
98019 ret |= writeJsonKey(ctx, key: UA_JSONKEY_ID);
98020 ret |= ENCODE_DIRECT_JSON(&src->identifier.string, String);
98021 break;
98022 case UA_NODEIDTYPE_GUID:
98023 ret |= writeJsonKey(ctx, key: UA_JSONKEY_IDTYPE);
98024 ret |= writeChar(ctx, c: '2');
98025 ret |= writeJsonKey(ctx, key: UA_JSONKEY_ID); /* Id */
98026 ret |= ENCODE_DIRECT_JSON(&src->identifier.guid, Guid);
98027 break;
98028 case UA_NODEIDTYPE_BYTESTRING:
98029 ret |= writeJsonKey(ctx, key: UA_JSONKEY_IDTYPE);
98030 ret |= writeChar(ctx, c: '3');
98031 ret |= writeJsonKey(ctx, key: UA_JSONKEY_ID); /* Id */
98032 ret |= ENCODE_DIRECT_JSON(&src->identifier.byteString, ByteString);
98033 break;
98034 default:
98035 return UA_STATUSCODE_BADINTERNALERROR;
98036 }
98037 return ret;
98038}
98039
98040ENCODE_JSON(NodeId) {
98041 /* Encode as string (non-standard). Encode with the standard utf8 escaping.
98042 * As the NodeId can contain quote characters, etc. */
98043 UA_StatusCode ret = UA_STATUSCODE_GOOD;
98044 if(ctx->stringNodeIds) {
98045 UA_String out = UA_STRING_NULL;
98046 ret |= UA_NodeId_print(id: src, output: &out);
98047 ret |= encodeJsonJumpTable[UA_DATATYPEKIND_STRING](ctx, &out, NULL);
98048 UA_String_clear(p: &out);
98049 return ret;
98050 }
98051
98052 /* Encode as object */
98053 ret |= writeJsonObjStart(ctx);
98054 ret |= NodeId_encodeJsonInternal(ctx, src);
98055 if(ctx->useReversible) {
98056 if(src->namespaceIndex > 0) {
98057 ret |= writeJsonKey(ctx, key: UA_JSONKEY_NAMESPACE);
98058 ret |= ENCODE_DIRECT_JSON(&src->namespaceIndex, UInt16);
98059 }
98060 } else {
98061 /* For the non-reversible encoding, the field is the NamespaceUri
98062 * associated with the NamespaceIndex, encoded as a JSON string.
98063 * A NamespaceIndex of 1 is always encoded as a JSON number. */
98064 if(src->namespaceIndex == 1) {
98065 ret |= writeJsonKey(ctx, key: UA_JSONKEY_NAMESPACE);
98066 ret |= ENCODE_DIRECT_JSON(&src->namespaceIndex, UInt16);
98067 } else {
98068 ret |= writeJsonKey(ctx, key: UA_JSONKEY_NAMESPACE);
98069
98070 /* Check if Namespace given and in range */
98071 if(src->namespaceIndex < ctx->namespacesSize && ctx->namespaces != NULL) {
98072 UA_String namespaceEntry = ctx->namespaces[src->namespaceIndex];
98073 ret |= ENCODE_DIRECT_JSON(&namespaceEntry, String);
98074 } else {
98075 return UA_STATUSCODE_BADNOTFOUND;
98076 }
98077 }
98078 }
98079
98080 return ret | writeJsonObjEnd(ctx);
98081}
98082
98083/* ExpandedNodeId */
98084ENCODE_JSON(ExpandedNodeId) {
98085 /* Encode as string (non-standard). Encode with utf8 escaping as the NodeId
98086 * can contain quote characters, etc. */
98087 UA_StatusCode ret = UA_STATUSCODE_GOOD;
98088 if(ctx->stringNodeIds) {
98089 UA_String out = UA_STRING_NULL;
98090 ret |= UA_ExpandedNodeId_print(eid: src, output: &out);
98091 ret |= encodeJsonJumpTable[UA_DATATYPEKIND_STRING](ctx, &out, NULL);
98092 UA_String_clear(p: &out);
98093 return ret;
98094 }
98095
98096 /* Encode as object */
98097 ret |= writeJsonObjStart(ctx);
98098
98099 /* Encode the identifier portion */
98100 ret |= NodeId_encodeJsonInternal(ctx, src: &src->nodeId);
98101
98102 if(ctx->useReversible) {
98103 /* Reversible Case */
98104
98105 if(src->namespaceUri.data) {
98106 /* If the NamespaceUri is specified it is encoded as a JSON string
98107 * in this field */
98108 ret |= writeJsonKey(ctx, key: UA_JSONKEY_NAMESPACE);
98109 ret |= ENCODE_DIRECT_JSON(&src->namespaceUri, String);
98110 } else if(src->nodeId.namespaceIndex > 0) {
98111 /* If the NamespaceUri is not specified, the NamespaceIndex is
98112 * encoded. Encoded as a JSON number for the reversible encoding.
98113 * Omitted if the NamespaceIndex equals 0. */
98114 ret |= writeJsonKey(ctx, key: UA_JSONKEY_NAMESPACE);
98115 ret |= ENCODE_DIRECT_JSON(&src->nodeId.namespaceIndex, UInt16);
98116 }
98117
98118 /* Encode the serverIndex/Url. As a JSON number for the reversible
98119 * encoding. Omitted if the ServerIndex equals 0. */
98120 if(src->serverIndex > 0) {
98121 ret |= writeJsonKey(ctx, key: UA_JSONKEY_SERVERURI);
98122 ret |= ENCODE_DIRECT_JSON(&src->serverIndex, UInt32);
98123 }
98124 } else {
98125 /* Non-Reversible Case */
98126
98127 /* If the NamespaceUri is not specified, the NamespaceIndex is encoded
98128 * with these rules: For the non-reversible encoding the field is the
98129 * NamespaceUri associated with the NamespaceIndex encoded as a JSON
98130 * string. A NamespaceIndex of 1 is always encoded as a JSON number. */
98131
98132 if(src->namespaceUri.data) {
98133 ret |= writeJsonKey(ctx, key: UA_JSONKEY_NAMESPACE);
98134 ret |= ENCODE_DIRECT_JSON(&src->namespaceUri, String);
98135 } else {
98136 if(src->nodeId.namespaceIndex == 1) {
98137 ret |= writeJsonKey(ctx, key: UA_JSONKEY_NAMESPACE);
98138 ret |= ENCODE_DIRECT_JSON(&src->nodeId.namespaceIndex, UInt16);
98139 } else {
98140 /* Check if Namespace given and in range */
98141 if(src->nodeId.namespaceIndex >= ctx->namespacesSize || !ctx->namespaces)
98142 return UA_STATUSCODE_BADNOTFOUND;
98143 UA_String namespaceEntry = ctx->namespaces[src->nodeId.namespaceIndex];
98144 ret |= writeJsonKey(ctx, key: UA_JSONKEY_NAMESPACE);
98145 ret |= ENCODE_DIRECT_JSON(&namespaceEntry, String);
98146 }
98147 }
98148
98149 /* For the non-reversible encoding, this field is the ServerUri
98150 * associated with the ServerIndex portion of the ExpandedNodeId,
98151 * encoded as a JSON string. */
98152
98153 /* Check if server given and in range */
98154 if(src->serverIndex >= ctx->serverUrisSize || !ctx->serverUris)
98155 return UA_STATUSCODE_BADNOTFOUND;
98156
98157 UA_String serverUriEntry = ctx->serverUris[src->serverIndex];
98158 ret |= writeJsonKey(ctx, key: UA_JSONKEY_SERVERURI);
98159 ret |= ENCODE_DIRECT_JSON(&serverUriEntry, String);
98160 }
98161
98162 return ret | writeJsonObjEnd(ctx);
98163}
98164
98165/* LocalizedText */
98166ENCODE_JSON(LocalizedText) {
98167 if(ctx->useReversible) {
98168 status ret = writeJsonObjStart(ctx);
98169 ret |= writeJsonKey(ctx, key: UA_JSONKEY_LOCALE);
98170 ret |= ENCODE_DIRECT_JSON(&src->locale, String);
98171 ret |= writeJsonKey(ctx, key: UA_JSONKEY_TEXT);
98172 ret |= ENCODE_DIRECT_JSON(&src->text, String);
98173 return ret | writeJsonObjEnd(ctx);
98174 }
98175
98176 /* For the non-reversible form, LocalizedText value shall be encoded as a
98177 * JSON string containing the Text component.*/
98178 return ENCODE_DIRECT_JSON(&src->text, String);
98179}
98180
98181ENCODE_JSON(QualifiedName) {
98182 status ret = writeJsonObjStart(ctx);
98183 ret |= writeJsonKey(ctx, key: UA_JSONKEY_NAME);
98184 ret |= ENCODE_DIRECT_JSON(&src->name, String);
98185
98186 if(ctx->useReversible) {
98187 if(src->namespaceIndex != 0) {
98188 ret |= writeJsonKey(ctx, key: UA_JSONKEY_URI);
98189 ret |= ENCODE_DIRECT_JSON(&src->namespaceIndex, UInt16);
98190 }
98191 } else {
98192 /* For the non-reversible form, the NamespaceUri associated with the
98193 * NamespaceIndex portion of the QualifiedName is encoded as JSON string
98194 * unless the NamespaceIndex is 1 or if NamespaceUri is unknown. In
98195 * these cases, the NamespaceIndex is encoded as a JSON number. */
98196 if(src->namespaceIndex == 1) {
98197 ret |= writeJsonKey(ctx, key: UA_JSONKEY_URI);
98198 ret |= ENCODE_DIRECT_JSON(&src->namespaceIndex, UInt16);
98199 } else {
98200 ret |= writeJsonKey(ctx, key: UA_JSONKEY_URI);
98201
98202 /* Check if Namespace given and in range */
98203 if(src->namespaceIndex < ctx->namespacesSize && ctx->namespaces != NULL) {
98204 UA_String namespaceEntry = ctx->namespaces[src->namespaceIndex];
98205 ret |= ENCODE_DIRECT_JSON(&namespaceEntry, String);
98206 } else {
98207 /* If not encode as number */
98208 ret |= ENCODE_DIRECT_JSON(&src->namespaceIndex, UInt16);
98209 }
98210 }
98211 }
98212
98213 return ret | writeJsonObjEnd(ctx);
98214}
98215
98216ENCODE_JSON(StatusCode) {
98217 if(ctx->useReversible)
98218 return ENCODE_DIRECT_JSON(src, UInt32);
98219
98220 const char *codename = UA_StatusCode_name(code: *src);
98221 UA_String statusDescription = UA_STRING(chars: (char*)(uintptr_t)codename);
98222
98223 status ret = UA_STATUSCODE_GOOD;
98224 ret |= writeJsonObjStart(ctx);
98225 ret |= writeJsonKey(ctx, key: UA_JSONKEY_CODE);
98226 ret |= ENCODE_DIRECT_JSON(src, UInt32);
98227 ret |= writeJsonKey(ctx, key: UA_JSONKEY_SYMBOL);
98228 ret |= ENCODE_DIRECT_JSON(&statusDescription, String);
98229 ret |= writeJsonObjEnd(ctx);
98230 return ret;
98231}
98232
98233/* ExtensionObject */
98234ENCODE_JSON(ExtensionObject) {
98235 if(src->encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY)
98236 return writeChars(ctx, c: "null", len: 4);
98237
98238 /* Must have a type set if data is decoded */
98239 if(src->encoding >= UA_EXTENSIONOBJECT_DECODED && !src->content.decoded.type)
98240 return UA_STATUSCODE_BADENCODINGERROR;
98241
98242 status ret = writeJsonObjStart(ctx);
98243
98244 /* Reversible encoding */
98245 if(ctx->useReversible) {
98246 /* Write the type NodeId */
98247 ret |= writeJsonKey(ctx, key: UA_JSONKEY_TYPEID);
98248 if(src->encoding == UA_EXTENSIONOBJECT_ENCODED_BYTESTRING ||
98249 src->encoding == UA_EXTENSIONOBJECT_ENCODED_XML)
98250 ret |= ENCODE_DIRECT_JSON(&src->content.encoded.typeId, NodeId);
98251 else
98252 ret |= ENCODE_DIRECT_JSON(&src->content.decoded.type->typeId, NodeId);
98253
98254 /* Write the encoding */
98255 if(src->encoding == UA_EXTENSIONOBJECT_ENCODED_BYTESTRING) {
98256 ret |= writeJsonKey(ctx, key: UA_JSONKEY_ENCODING);
98257 ret |= writeChar(ctx, c: '1');
98258 } else if(src->encoding == UA_EXTENSIONOBJECT_ENCODED_XML) {
98259 ret |= writeJsonKey(ctx, key: UA_JSONKEY_ENCODING);
98260 ret |= writeChar(ctx, c: '2');
98261 }
98262 }
98263
98264 /* Write the body */
98265 ret |= writeJsonKey(ctx, key: UA_JSONKEY_BODY);
98266 if(src->encoding == UA_EXTENSIONOBJECT_ENCODED_BYTESTRING ||
98267 src->encoding == UA_EXTENSIONOBJECT_ENCODED_XML) {
98268 ret |= ENCODE_DIRECT_JSON(&src->content.encoded.body, String);
98269 } else {
98270 const UA_DataType *t = src->content.decoded.type;
98271 ret |= encodeJsonJumpTable[t->typeKind]
98272 (ctx, src->content.decoded.data, t);
98273 }
98274
98275 return ret | writeJsonObjEnd(ctx);
98276}
98277
98278/* Non-builtin types get wrapped in an ExtensionObject */
98279static status
98280encodeScalarJsonWrapExtensionObject(CtxJson *ctx, const UA_Variant *src) {
98281 const UA_Boolean isBuiltin = (src->type->typeKind <= UA_DATATYPEKIND_DIAGNOSTICINFO);
98282 const void *ptr = src->data;
98283 const UA_DataType *type = src->type;
98284
98285 /* Set up a temporary ExtensionObject to wrap the data */
98286 UA_ExtensionObject eo;
98287 if(!isBuiltin) {
98288 UA_ExtensionObject_init(p: &eo);
98289 eo.encoding = UA_EXTENSIONOBJECT_DECODED;
98290 eo.content.decoded.type = src->type;
98291 eo.content.decoded.data = src->data;
98292 ptr = &eo;
98293 type = &UA_TYPES[UA_TYPES_EXTENSIONOBJECT];
98294 }
98295
98296 return encodeJsonJumpTable[type->typeKind](ctx, ptr, type);
98297}
98298
98299/* Non-builtin types get wrapped in an ExtensionObject */
98300static status
98301encodeArrayJsonWrapExtensionObject(CtxJson *ctx, const void *data,
98302 size_t size, const UA_DataType *type) {
98303 if(size > UA_INT32_MAX)
98304 return UA_STATUSCODE_BADENCODINGERROR;
98305
98306 status ret = writeJsonArrStart(ctx);
98307
98308 u16 memSize = type->memSize;
98309 const UA_Boolean isBuiltin = (type->typeKind <= UA_DATATYPEKIND_DIAGNOSTICINFO);
98310 if(isBuiltin) {
98311 uintptr_t ptr = (uintptr_t)data;
98312 for(size_t i = 0; i < size && ret == UA_STATUSCODE_GOOD; ++i) {
98313 ret |= writeJsonArrElm(ctx, value: (const void*)ptr, type);
98314 ptr += memSize;
98315 }
98316 } else {
98317 /* Set up a temporary ExtensionObject to wrap the data */
98318 UA_ExtensionObject eo;
98319 UA_ExtensionObject_init(p: &eo);
98320 eo.encoding = UA_EXTENSIONOBJECT_DECODED;
98321 eo.content.decoded.type = type;
98322 eo.content.decoded.data = (void*)(uintptr_t)data;
98323 for(size_t i = 0; i < size && ret == UA_STATUSCODE_GOOD; ++i) {
98324 ret |= writeJsonArrElm(ctx, value: &eo, type: &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]);
98325 eo.content.decoded.data = (void*)
98326 ((uintptr_t)eo.content.decoded.data + memSize);
98327 }
98328 }
98329
98330 return ret | writeJsonArrEnd(ctx);
98331}
98332
98333static status
98334addMultiArrayContentJSON(CtxJson *ctx, void* array, const UA_DataType *type,
98335 size_t *index, UA_UInt32 *arrayDimensions, size_t dimensionIndex,
98336 size_t dimensionSize) {
98337 /* Stop recursion: The inner arrays are written */
98338 status ret;
98339 if(dimensionIndex == (dimensionSize - 1)) {
98340 u8 *ptr = ((u8 *)array) + (type->memSize * *index);
98341 u32 size = arrayDimensions[dimensionIndex];
98342 (*index) += arrayDimensions[dimensionIndex];
98343 return encodeArrayJsonWrapExtensionObject(ctx, data: ptr, size, type);
98344 }
98345
98346 /* Recurse to the next dimension */
98347 ret = writeJsonArrStart(ctx);
98348 for(size_t i = 0; i < arrayDimensions[dimensionIndex]; i++) {
98349 ret |= writeJsonBeforeElement(ctx, true);
98350 ret |= addMultiArrayContentJSON(ctx, array, type, index, arrayDimensions,
98351 dimensionIndex: dimensionIndex + 1, dimensionSize);
98352 ctx->commaNeeded[ctx->depth] = true;
98353 }
98354 return ret | writeJsonArrEnd(ctx);
98355}
98356
98357ENCODE_JSON(Variant) {
98358 /* If type is 0 (NULL) the Variant contains a NULL value and the containing
98359 * JSON object shall be omitted or replaced by the JSON literal ‘null’ (when
98360 * an element of a JSON array). */
98361 if(!src->type)
98362 return writeJsonObjStart(ctx) | writeJsonObjEnd(ctx);
98363
98364 /* Set the content type in the encoding mask */
98365 const UA_Boolean isBuiltin = (src->type->typeKind <= UA_DATATYPEKIND_DIAGNOSTICINFO);
98366
98367 /* Set the array type in the encoding mask */
98368 const bool isArray = src->arrayLength > 0 || src->data <= UA_EMPTY_ARRAY_SENTINEL;
98369 const bool hasDimensions = isArray && src->arrayDimensionsSize > 0;
98370
98371 /* We cannot directly encode a variant inside a variant (but arrays of
98372 * variant are possible) */
98373 UA_Boolean wrapEO = !isBuiltin;
98374 if(src->type == &UA_TYPES[UA_TYPES_VARIANT] && !isArray)
98375 wrapEO = true;
98376
98377 status ret = writeJsonObjStart(ctx);
98378
98379 /* Write the type NodeId */
98380 if(ctx->useReversible) {
98381 UA_UInt32 typeId = src->type->typeId.identifier.numeric;
98382 if(wrapEO)
98383 typeId = UA_TYPES[UA_TYPES_EXTENSIONOBJECT].typeId.identifier.numeric;
98384 ret |= writeJsonKey(ctx, key: UA_JSONKEY_TYPE);
98385 ret |= ENCODE_DIRECT_JSON(&typeId, UInt32);
98386 }
98387
98388 /* Write the Variant body */
98389 ret |= writeJsonKey(ctx, key: UA_JSONKEY_BODY);
98390
98391 if(!isArray) {
98392 encodeScalarJsonWrapExtensionObject(ctx, src);
98393 } else {
98394 if(ctx->useReversible || !hasDimensions) {
98395 ret |= encodeArrayJsonWrapExtensionObject(ctx, data: src->data,
98396 size: src->arrayLength, type: src->type);
98397 if(hasDimensions) {
98398 ret |= writeJsonKey(ctx, key: UA_JSONKEY_DIMENSION);
98399 ret |= encodeJsonArray(ctx, ptr: src->arrayDimensions, length: src->arrayDimensionsSize,
98400 type: &UA_TYPES[UA_TYPES_UINT32]);
98401 }
98402 } else {
98403 /* Special case of non-reversible array with dimensions */
98404 size_t index = 0;
98405 ret |= addMultiArrayContentJSON(ctx, array: src->data, type: src->type, index: &index,
98406 arrayDimensions: src->arrayDimensions, dimensionIndex: 0,
98407 dimensionSize: src->arrayDimensionsSize);
98408 }
98409 }
98410
98411 return ret | writeJsonObjEnd(ctx);
98412}
98413
98414/* DataValue */
98415ENCODE_JSON(DataValue) {
98416 UA_Boolean hasValue = src->hasValue;
98417 UA_Boolean hasStatus = src->hasStatus;
98418 UA_Boolean hasSourceTimestamp = src->hasSourceTimestamp;
98419 UA_Boolean hasSourcePicoseconds = src->hasSourcePicoseconds;
98420 UA_Boolean hasServerTimestamp = src->hasServerTimestamp;
98421 UA_Boolean hasServerPicoseconds = src->hasServerPicoseconds;
98422
98423 status ret = writeJsonObjStart(ctx);
98424
98425 if(hasValue) {
98426 ret |= writeJsonKey(ctx, key: UA_JSONKEY_VALUE);
98427 ret |= ENCODE_DIRECT_JSON(&src->value, Variant);
98428 }
98429
98430 if(hasStatus) {
98431 ret |= writeJsonKey(ctx, key: UA_JSONKEY_STATUS);
98432 ret |= ENCODE_DIRECT_JSON(&src->status, StatusCode);
98433 }
98434
98435 if(hasSourceTimestamp) {
98436 ret |= writeJsonKey(ctx, key: UA_JSONKEY_SOURCETIMESTAMP);
98437 ret |= ENCODE_DIRECT_JSON(&src->sourceTimestamp, DateTime);
98438 }
98439
98440 if(hasSourcePicoseconds) {
98441 ret |= writeJsonKey(ctx, key: UA_JSONKEY_SOURCEPICOSECONDS);
98442 ret |= ENCODE_DIRECT_JSON(&src->sourcePicoseconds, UInt16);
98443 }
98444
98445 if(hasServerTimestamp) {
98446 ret |= writeJsonKey(ctx, key: UA_JSONKEY_SERVERTIMESTAMP);
98447 ret |= ENCODE_DIRECT_JSON(&src->serverTimestamp, DateTime);
98448 }
98449
98450 if(hasServerPicoseconds) {
98451 ret |= writeJsonKey(ctx, key: UA_JSONKEY_SERVERPICOSECONDS);
98452 ret |= ENCODE_DIRECT_JSON(&src->serverPicoseconds, UInt16);
98453 }
98454
98455 return ret | writeJsonObjEnd(ctx);
98456}
98457
98458/* DiagnosticInfo */
98459ENCODE_JSON(DiagnosticInfo) {
98460 status ret = writeJsonObjStart(ctx);
98461
98462 if(src->hasSymbolicId) {
98463 ret |= writeJsonKey(ctx, key: UA_JSONKEY_SYMBOLICID);
98464 ret |= ENCODE_DIRECT_JSON(&src->symbolicId, Int32);
98465 }
98466
98467 if(src->hasNamespaceUri) {
98468 ret |= writeJsonKey(ctx, key: UA_JSONKEY_NAMESPACEURI);
98469 ret |= ENCODE_DIRECT_JSON(&src->namespaceUri, Int32);
98470 }
98471
98472 if(src->hasLocalizedText) {
98473 ret |= writeJsonKey(ctx, key: UA_JSONKEY_LOCALIZEDTEXT);
98474 ret |= ENCODE_DIRECT_JSON(&src->localizedText, Int32);
98475 }
98476
98477 if(src->hasLocale) {
98478 ret |= writeJsonKey(ctx, key: UA_JSONKEY_LOCALE);
98479 ret |= ENCODE_DIRECT_JSON(&src->locale, Int32);
98480 }
98481
98482 if(src->hasAdditionalInfo) {
98483 ret |= writeJsonKey(ctx, key: UA_JSONKEY_ADDITIONALINFO);
98484 ret |= ENCODE_DIRECT_JSON(&src->additionalInfo, String);
98485 }
98486
98487 if(src->hasInnerStatusCode) {
98488 ret |= writeJsonKey(ctx, key: UA_JSONKEY_INNERSTATUSCODE);
98489 ret |= ENCODE_DIRECT_JSON(&src->innerStatusCode, StatusCode);
98490 }
98491
98492 if(src->hasInnerDiagnosticInfo && src->innerDiagnosticInfo) {
98493 ret |= writeJsonKey(ctx, key: UA_JSONKEY_INNERDIAGNOSTICINFO);
98494 ret |= encodeJsonJumpTable[UA_DATATYPEKIND_DIAGNOSTICINFO]
98495 (ctx, src->innerDiagnosticInfo, NULL);
98496 }
98497
98498 return ret | writeJsonObjEnd(ctx);
98499}
98500
98501static status
98502encodeJsonStructure(CtxJson *ctx, const void *src, const UA_DataType *type) {
98503 status ret = writeJsonObjStart(ctx);
98504 if(ret != UA_STATUSCODE_GOOD)
98505 return ret;
98506
98507 uintptr_t ptr = (uintptr_t) src;
98508 u8 membersSize = type->membersSize;
98509 for(size_t i = 0; i < membersSize && ret == UA_STATUSCODE_GOOD; ++i) {
98510 const UA_DataTypeMember *m = &type->members[i];
98511 const UA_DataType *mt = m->memberType;
98512
98513 if(m->memberName != NULL && *m->memberName != 0)
98514 ret |= writeJsonKey(ctx, key: m->memberName);
98515
98516 if(!m->isArray) {
98517 ptr += m->padding;
98518 size_t memSize = mt->memSize;
98519 ret |= encodeJsonJumpTable[mt->typeKind](ctx, (const void*) ptr, mt);
98520 ptr += memSize;
98521 } else {
98522 ptr += m->padding;
98523 const size_t length = *((const size_t*) ptr);
98524 ptr += sizeof (size_t);
98525 ret |= encodeJsonArray(ctx, ptr: *(void * const *)ptr, length, type: mt);
98526 ptr += sizeof (void*);
98527 }
98528 }
98529
98530 return ret | writeJsonObjEnd(ctx);
98531}
98532
98533static status
98534encodeJsonNotImplemented(const void *src, const UA_DataType *type, CtxJson *ctx) {
98535 (void) src, (void) type, (void)ctx;
98536 return UA_STATUSCODE_BADNOTIMPLEMENTED;
98537}
98538
98539const encodeJsonSignature encodeJsonJumpTable[UA_DATATYPEKINDS] = {
98540 (encodeJsonSignature)Boolean_encodeJson,
98541 (encodeJsonSignature)SByte_encodeJson, /* SByte */
98542 (encodeJsonSignature)Byte_encodeJson,
98543 (encodeJsonSignature)Int16_encodeJson, /* Int16 */
98544 (encodeJsonSignature)UInt16_encodeJson,
98545 (encodeJsonSignature)Int32_encodeJson, /* Int32 */
98546 (encodeJsonSignature)UInt32_encodeJson,
98547 (encodeJsonSignature)Int64_encodeJson, /* Int64 */
98548 (encodeJsonSignature)UInt64_encodeJson,
98549 (encodeJsonSignature)Float_encodeJson,
98550 (encodeJsonSignature)Double_encodeJson,
98551 (encodeJsonSignature)String_encodeJson,
98552 (encodeJsonSignature)DateTime_encodeJson, /* DateTime */
98553 (encodeJsonSignature)Guid_encodeJson,
98554 (encodeJsonSignature)ByteString_encodeJson, /* ByteString */
98555 (encodeJsonSignature)String_encodeJson, /* XmlElement */
98556 (encodeJsonSignature)NodeId_encodeJson,
98557 (encodeJsonSignature)ExpandedNodeId_encodeJson,
98558 (encodeJsonSignature)StatusCode_encodeJson, /* StatusCode */
98559 (encodeJsonSignature)QualifiedName_encodeJson, /* QualifiedName */
98560 (encodeJsonSignature)LocalizedText_encodeJson,
98561 (encodeJsonSignature)ExtensionObject_encodeJson,
98562 (encodeJsonSignature)DataValue_encodeJson,
98563 (encodeJsonSignature)Variant_encodeJson,
98564 (encodeJsonSignature)DiagnosticInfo_encodeJson,
98565 (encodeJsonSignature)encodeJsonNotImplemented, /* Decimal */
98566 (encodeJsonSignature)Int32_encodeJson, /* Enum */
98567 (encodeJsonSignature)encodeJsonStructure,
98568 (encodeJsonSignature)encodeJsonNotImplemented, /* Structure with optional fields */
98569 (encodeJsonSignature)encodeJsonNotImplemented, /* Union */
98570 (encodeJsonSignature)encodeJsonNotImplemented /* BitfieldCluster */
98571};
98572
98573UA_StatusCode
98574UA_encodeJson(const void *src, const UA_DataType *type, UA_ByteString *outBuf,
98575 const UA_EncodeJsonOptions *options) {
98576 if(!src || !type)
98577 return UA_STATUSCODE_BADINTERNALERROR;
98578
98579 /* Allocate buffer */
98580 UA_Boolean allocated = false;
98581 status res = UA_STATUSCODE_GOOD;
98582 if(outBuf->length == 0) {
98583 size_t len = UA_calcSizeJson(src, type, options);
98584 res = UA_ByteString_allocBuffer(bs: outBuf, length: len);
98585 if(res != UA_STATUSCODE_GOOD)
98586 return res;
98587 allocated = true;
98588 }
98589
98590 /* Set up the context */
98591 CtxJson ctx;
98592 memset(s: &ctx, c: 0, n: sizeof(ctx));
98593 ctx.pos = outBuf->data;
98594 ctx.end = &outBuf->data[outBuf->length];
98595 ctx.depth = 0;
98596 ctx.calcOnly = false;
98597 ctx.useReversible = true; /* default */
98598 if(options) {
98599 ctx.namespaces = options->namespaces;
98600 ctx.namespacesSize = options->namespacesSize;
98601 ctx.serverUris = options->serverUris;
98602 ctx.serverUrisSize = options->serverUrisSize;
98603 ctx.useReversible = options->useReversible;
98604 ctx.prettyPrint = options->prettyPrint;
98605 ctx.unquotedKeys = options->unquotedKeys;
98606 ctx.stringNodeIds = options->stringNodeIds;
98607 }
98608
98609 /* Encode */
98610 res = encodeJsonJumpTable[type->typeKind](&ctx, src, type);
98611
98612 /* Clean up */
98613 if(res == UA_STATUSCODE_GOOD)
98614 outBuf->length = (size_t)((uintptr_t)ctx.pos - (uintptr_t)outBuf->data);
98615 else if(allocated)
98616 UA_ByteString_clear(p: outBuf);
98617 return res;
98618}
98619
98620UA_StatusCode
98621UA_print(const void *p, const UA_DataType *type, UA_String *output) {
98622 if(!p || !type || !output)
98623 return UA_STATUSCODE_BADINTERNALERROR;
98624
98625 UA_EncodeJsonOptions options;
98626 memset(s: &options, c: 0, n: sizeof(UA_EncodeJsonOptions));
98627 options.useReversible = true;
98628 options.prettyPrint = true;
98629 options.unquotedKeys = true;
98630 options.stringNodeIds = true;
98631 return UA_encodeJson(src: p, type, outBuf: output, options: &options);
98632}
98633
98634/************/
98635/* CalcSize */
98636/************/
98637
98638size_t
98639UA_calcSizeJson(const void *src, const UA_DataType *type,
98640 const UA_EncodeJsonOptions *options) {
98641 if(!src || !type)
98642 return UA_STATUSCODE_BADINTERNALERROR;
98643
98644 /* Set up the context */
98645 CtxJson ctx;
98646 memset(s: &ctx, c: 0, n: sizeof(ctx));
98647 ctx.pos = NULL;
98648 ctx.end = (const UA_Byte*)(uintptr_t)SIZE_MAX;
98649 ctx.depth = 0;
98650 ctx.useReversible = true; /* default */
98651 if(options) {
98652 ctx.namespaces = options->namespaces;
98653 ctx.namespacesSize = options->namespacesSize;
98654 ctx.serverUris = options->serverUris;
98655 ctx.serverUrisSize = options->serverUrisSize;
98656 ctx.useReversible = options->useReversible;
98657 ctx.prettyPrint = options->prettyPrint;
98658 ctx.unquotedKeys = options->unquotedKeys;
98659 ctx.stringNodeIds = options->stringNodeIds;
98660 }
98661
98662 ctx.calcOnly = true;
98663
98664 /* Encode */
98665 status ret = encodeJsonJumpTable[type->typeKind](&ctx, src, type);
98666 if(ret != UA_STATUSCODE_GOOD)
98667 return 0;
98668 return (size_t)ctx.pos;
98669}
98670
98671/**********/
98672/* Decode */
98673/**********/
98674
98675#define GET_TOKEN \
98676 size_t tokenSize = getTokenLength(&ctx->tokens[ctx->index]); \
98677 const char* tokenData = &ctx->json5[ctx->tokens[ctx->index].start]; \
98678 do {} while(0)
98679
98680#define CHECK_TOKEN_BOUNDS do { \
98681 if(ctx->index >= ctx->tokensSize) \
98682 return UA_STATUSCODE_BADDECODINGERROR; \
98683 } while(0)
98684
98685#define CHECK_NUMBER do { \
98686 if(currentTokenType(ctx) != CJ5_TOKEN_NUMBER) { \
98687 return UA_STATUSCODE_BADDECODINGERROR; \
98688 }} while(0)
98689
98690#define CHECK_BOOL do { \
98691 if(currentTokenType(ctx) != CJ5_TOKEN_BOOL) { \
98692 return UA_STATUSCODE_BADDECODINGERROR; \
98693 }} while(0)
98694
98695#define CHECK_STRING do { \
98696 if(currentTokenType(ctx) != CJ5_TOKEN_STRING) { \
98697 return UA_STATUSCODE_BADDECODINGERROR; \
98698 }} while(0)
98699
98700#define CHECK_OBJECT do { \
98701 if(currentTokenType(ctx) != CJ5_TOKEN_OBJECT) { \
98702 return UA_STATUSCODE_BADDECODINGERROR; \
98703 }} while(0)
98704
98705#define CHECK_NULL_SKIP do { \
98706 if(currentTokenType(ctx) == CJ5_TOKEN_NULL) { \
98707 ctx->index++; \
98708 return UA_STATUSCODE_GOOD; \
98709 }} while(0)
98710
98711/* Forward declarations*/
98712#define DECODE_JSON(TYPE) static status \
98713 TYPE##_decodeJson(ParseCtx *ctx, UA_##TYPE *dst, \
98714 const UA_DataType *type)
98715
98716/* If ctx->index points to the beginning of an object, move the index to the
98717 * next token after this object. Attention! The index can be moved after the
98718 * last parsed token. So the array length has to be checked afterwards. */
98719static void
98720skipObject(ParseCtx *ctx) {
98721 unsigned int end = ctx->tokens[ctx->index].end;
98722 do {
98723 ctx->index++;
98724 } while(ctx->index < ctx->tokensSize &&
98725 ctx->tokens[ctx->index].start < end);
98726}
98727
98728static status
98729Array_decodeJson(ParseCtx *ctx, void **dst, const UA_DataType *type);
98730
98731static status
98732Variant_decodeJsonUnwrapExtensionObject(ParseCtx *ctx, void *p, const UA_DataType *type);
98733
98734static UA_SByte
98735jsoneq(const char *json, const cj5_token *tok, const char *searchKey) {
98736 /* TODO: necessary?
98737 if(json == NULL
98738 || tok == NULL
98739 || searchKey == NULL) {
98740 return -1;
98741 } */
98742
98743 size_t len = getTokenLength(t: tok);
98744 if(tok->type == CJ5_TOKEN_STRING &&
98745 strlen(s: searchKey) == len &&
98746 strncmp(s1: json + tok->start, s2: (const char*)searchKey, n: len) == 0)
98747 return 0;
98748
98749 return -1;
98750}
98751
98752DECODE_JSON(Boolean) {
98753 CHECK_TOKEN_BOUNDS;
98754 CHECK_BOOL;
98755 GET_TOKEN;
98756
98757 if(tokenSize == 4 &&
98758 tokenData[0] == 't' && tokenData[1] == 'r' &&
98759 tokenData[2] == 'u' && tokenData[3] == 'e') {
98760 *dst = true;
98761 } else if(tokenSize == 5 &&
98762 tokenData[0] == 'f' && tokenData[1] == 'a' &&
98763 tokenData[2] == 'l' && tokenData[3] == 's' &&
98764 tokenData[4] == 'e') {
98765 *dst = false;
98766 } else {
98767 return UA_STATUSCODE_BADDECODINGERROR;
98768 }
98769
98770 ctx->index++;
98771 return UA_STATUSCODE_GOOD;
98772}
98773
98774static UA_StatusCode
98775parseUnsignedInteger(const char *tokenData, size_t tokenSize, UA_UInt64 *dst) {
98776 size_t len = parseUInt64(str: tokenData, size: tokenSize, result: dst);
98777 if(len == 0)
98778 return UA_STATUSCODE_BADDECODINGERROR;
98779
98780 /* There must only be whitespace between the end of the parsed number and
98781 * the end of the token */
98782 for(size_t i = len; i < tokenSize; i++) {
98783 if(tokenData[i] != ' ' && tokenData[i] -'\t' >= 5)
98784 return UA_STATUSCODE_BADDECODINGERROR;
98785 }
98786
98787 return UA_STATUSCODE_GOOD;
98788}
98789
98790static UA_StatusCode
98791parseSignedInteger(const char *tokenData, size_t tokenSize, UA_Int64 *dst) {
98792 size_t len = parseInt64(str: tokenData, size: tokenSize, result: dst);
98793 if(len == 0)
98794 return UA_STATUSCODE_BADDECODINGERROR;
98795
98796 /* There must only be whitespace between the end of the parsed number and
98797 * the end of the token */
98798 for(size_t i = len; i < tokenSize; i++) {
98799 if(tokenData[i] != ' ' && tokenData[i] -'\t' >= 5)
98800 return UA_STATUSCODE_BADDECODINGERROR;
98801 }
98802
98803 return UA_STATUSCODE_GOOD;
98804}
98805
98806DECODE_JSON(Byte) {
98807 CHECK_TOKEN_BOUNDS;
98808 CHECK_NUMBER;
98809 GET_TOKEN;
98810
98811 UA_UInt64 out = 0;
98812 UA_StatusCode s = parseUnsignedInteger(tokenData, tokenSize, dst: &out);
98813 if(s != UA_STATUSCODE_GOOD || out > UA_BYTE_MAX)
98814 return UA_STATUSCODE_BADDECODINGERROR;
98815 *dst = (UA_Byte)out;
98816 ctx->index++;
98817 return UA_STATUSCODE_GOOD;
98818}
98819
98820DECODE_JSON(UInt16) {
98821 CHECK_TOKEN_BOUNDS;
98822 CHECK_NUMBER;
98823 GET_TOKEN;
98824
98825 UA_UInt64 out = 0;
98826 UA_StatusCode s = parseUnsignedInteger(tokenData, tokenSize, dst: &out);
98827 if(s != UA_STATUSCODE_GOOD || out > UA_UINT16_MAX)
98828 return UA_STATUSCODE_BADDECODINGERROR;
98829 *dst = (UA_UInt16)out;
98830 ctx->index++;
98831 return UA_STATUSCODE_GOOD;
98832}
98833
98834DECODE_JSON(UInt32) {
98835 CHECK_TOKEN_BOUNDS;
98836 CHECK_NUMBER;
98837 GET_TOKEN;
98838
98839 UA_UInt64 out = 0;
98840 UA_StatusCode s = parseUnsignedInteger(tokenData, tokenSize, dst: &out);
98841 if(s != UA_STATUSCODE_GOOD || out > UA_UINT32_MAX)
98842 return UA_STATUSCODE_BADDECODINGERROR;
98843 *dst = (UA_UInt32)out;
98844 ctx->index++;
98845 return UA_STATUSCODE_GOOD;
98846}
98847
98848DECODE_JSON(UInt64) {
98849 CHECK_TOKEN_BOUNDS;
98850 GET_TOKEN;
98851
98852 UA_StatusCode s = parseUnsignedInteger(tokenData, tokenSize, dst);
98853 if(s != UA_STATUSCODE_GOOD)
98854 return UA_STATUSCODE_BADDECODINGERROR;
98855 ctx->index++;
98856 return UA_STATUSCODE_GOOD;
98857}
98858
98859DECODE_JSON(SByte) {
98860 CHECK_TOKEN_BOUNDS;
98861 CHECK_NUMBER;
98862 GET_TOKEN;
98863
98864 UA_Int64 out = 0;
98865 UA_StatusCode s = parseSignedInteger(tokenData, tokenSize, dst: &out);
98866 if(s != UA_STATUSCODE_GOOD || out < UA_SBYTE_MIN || out > UA_SBYTE_MAX)
98867 return UA_STATUSCODE_BADDECODINGERROR;
98868 *dst = (UA_SByte)out;
98869 ctx->index++;
98870 return UA_STATUSCODE_GOOD;
98871}
98872
98873DECODE_JSON(Int16) {
98874 CHECK_TOKEN_BOUNDS;
98875 CHECK_NUMBER;
98876 GET_TOKEN;
98877
98878 UA_Int64 out = 0;
98879 UA_StatusCode s = parseSignedInteger(tokenData, tokenSize, dst: &out);
98880 if(s != UA_STATUSCODE_GOOD || out < UA_INT16_MIN || out > UA_INT16_MAX)
98881 return UA_STATUSCODE_BADDECODINGERROR;
98882 *dst = (UA_Int16)out;
98883 ctx->index++;
98884 return UA_STATUSCODE_GOOD;
98885}
98886
98887DECODE_JSON(Int32) {
98888 CHECK_TOKEN_BOUNDS;
98889 CHECK_NUMBER;
98890 GET_TOKEN;
98891
98892 UA_Int64 out = 0;
98893 UA_StatusCode s = parseSignedInteger(tokenData, tokenSize, dst: &out);
98894 if(s != UA_STATUSCODE_GOOD || out < UA_INT32_MIN || out > UA_INT32_MAX)
98895 return UA_STATUSCODE_BADDECODINGERROR;
98896 *dst = (UA_Int32)out;
98897 ctx->index++;
98898 return UA_STATUSCODE_GOOD;
98899}
98900
98901DECODE_JSON(Int64) {
98902 CHECK_TOKEN_BOUNDS;
98903 GET_TOKEN;
98904
98905 UA_StatusCode s = parseSignedInteger(tokenData, tokenSize, dst);
98906 if(s != UA_STATUSCODE_GOOD)
98907 return UA_STATUSCODE_BADDECODINGERROR;
98908 ctx->index++;
98909 return UA_STATUSCODE_GOOD;
98910}
98911
98912/* Either a STRING or NUMBER token */
98913DECODE_JSON(Double) {
98914 CHECK_TOKEN_BOUNDS;
98915 GET_TOKEN;
98916
98917 /* https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/
98918 * Maximum digit counts for select IEEE floating-point formats: 1074
98919 * Sanity check.
98920 */
98921 if(tokenSize > 2000)
98922 return UA_STATUSCODE_BADDECODINGERROR;
98923
98924 cj5_token_type tokenType = currentTokenType(ctx);
98925
98926 /* It could be a String with Nan, Infinity */
98927 if(tokenType == CJ5_TOKEN_STRING) {
98928 ctx->index++;
98929
98930 if(tokenSize == 8 && memcmp(s1: tokenData, s2: "Infinity", n: 8) == 0) {
98931 *dst = INFINITY;
98932 return UA_STATUSCODE_GOOD;
98933 }
98934
98935 if(tokenSize == 9 && memcmp(s1: tokenData, s2: "-Infinity", n: 9) == 0) {
98936 /* workaround an MSVC 2013 issue */
98937 *dst = -INFINITY;
98938 return UA_STATUSCODE_GOOD;
98939 }
98940
98941 if(tokenSize == 3 && memcmp(s1: tokenData, s2: "NaN", n: 3) == 0) {
98942 *dst = NAN;
98943 return UA_STATUSCODE_GOOD;
98944 }
98945
98946 if(tokenSize == 4 && memcmp(s1: tokenData, s2: "-NaN", n: 4) == 0) {
98947 *dst = NAN;
98948 return UA_STATUSCODE_GOOD;
98949 }
98950
98951 return UA_STATUSCODE_BADDECODINGERROR;
98952 }
98953
98954 if(tokenType != CJ5_TOKEN_NUMBER)
98955 return UA_STATUSCODE_BADDECODINGERROR;
98956
98957 size_t len = parseDouble(str: tokenData, size: tokenSize, result: dst);
98958 if(len == 0)
98959 return UA_STATUSCODE_BADDECODINGERROR;
98960
98961 /* There must only be whitespace between the end of the parsed number and
98962 * the end of the token */
98963 for(size_t i = len; i < tokenSize; i++) {
98964 if(tokenData[i] != ' ' && tokenData[i] -'\t' >= 5)
98965 return UA_STATUSCODE_BADDECODINGERROR;
98966 }
98967
98968 ctx->index++;
98969 return UA_STATUSCODE_GOOD;
98970}
98971
98972DECODE_JSON(Float) {
98973 UA_Double v = 0.0;
98974 UA_StatusCode res = Double_decodeJson(ctx, dst: &v, NULL);
98975 *dst = (UA_Float)v;
98976 return res;
98977}
98978
98979DECODE_JSON(Guid) {
98980 CHECK_TOKEN_BOUNDS;
98981 CHECK_STRING;
98982 GET_TOKEN;
98983
98984 /* Use the existing parsing routine if available */
98985 UA_String str = {tokenSize, (UA_Byte*)(uintptr_t)tokenData};
98986 ctx->index++;
98987 return UA_Guid_parse(guid: dst, str);
98988}
98989
98990DECODE_JSON(String) {
98991 CHECK_TOKEN_BOUNDS;
98992 CHECK_STRING;
98993 GET_TOKEN;
98994 (void)tokenData;
98995
98996 /* Empty string? */
98997 if(tokenSize == 0) {
98998 dst->data = (UA_Byte*)UA_EMPTY_ARRAY_SENTINEL;
98999 dst->length = 0;
99000 ctx->index++;
99001 return UA_STATUSCODE_GOOD;
99002 }
99003
99004 /* The decoded utf8 is at most of the same length as the source string */
99005 char *outBuf = (char*)UA_malloc(size: tokenSize+1);
99006 if(!outBuf)
99007 return UA_STATUSCODE_BADOUTOFMEMORY;
99008
99009 /* Decode the string */
99010 cj5_result r;
99011 r.tokens = ctx->tokens;
99012 r.num_tokens = (unsigned int)ctx->tokensSize;
99013 r.json5 = ctx->json5;
99014 unsigned int len = 0;
99015 cj5_error_code err = cj5_get_str(r: &r, tok_index: (unsigned int)ctx->index, buf: outBuf, buflen: &len);
99016 if(err != CJ5_ERROR_NONE) {
99017 UA_free(ptr: outBuf);
99018 return UA_STATUSCODE_BADDECODINGERROR;
99019 }
99020
99021 /* Set the output */
99022 dst->length = len;
99023 if(dst->length > 0) {
99024 dst->data = (UA_Byte*)outBuf;
99025 } else {
99026 dst->data = (UA_Byte*)UA_EMPTY_ARRAY_SENTINEL;
99027 UA_free(ptr: outBuf);
99028 }
99029
99030 ctx->index++;
99031 return UA_STATUSCODE_GOOD;
99032}
99033
99034DECODE_JSON(ByteString) {
99035 CHECK_TOKEN_BOUNDS;
99036 CHECK_STRING;
99037 GET_TOKEN;
99038
99039 /* Empty bytestring? */
99040 if(tokenSize == 0) {
99041 dst->data = (UA_Byte*)UA_EMPTY_ARRAY_SENTINEL;
99042 dst->length = 0;
99043 } else {
99044 size_t flen = 0;
99045 unsigned char* unB64 =
99046 UA_unbase64(src: (const unsigned char*)tokenData, len: tokenSize, out_len: &flen);
99047 if(unB64 == 0)
99048 return UA_STATUSCODE_BADDECODINGERROR;
99049 dst->data = (u8*)unB64;
99050 dst->length = flen;
99051 }
99052
99053 ctx->index++;
99054 return UA_STATUSCODE_GOOD;
99055}
99056
99057DECODE_JSON(LocalizedText) {
99058 CHECK_OBJECT;
99059
99060 DecodeEntry entries[2] = {
99061 {UA_JSONKEY_LOCALE, &dst->locale, NULL, false, &UA_TYPES[UA_TYPES_STRING]},
99062 {UA_JSONKEY_TEXT, &dst->text, NULL, false, &UA_TYPES[UA_TYPES_STRING]}
99063 };
99064
99065 return decodeFields(ctx, entries, entryCount: 2);
99066}
99067
99068DECODE_JSON(QualifiedName) {
99069 CHECK_OBJECT;
99070
99071 DecodeEntry entries[2] = {
99072 {UA_JSONKEY_NAME, &dst->name, NULL, false, &UA_TYPES[UA_TYPES_STRING]},
99073 {UA_JSONKEY_URI, &dst->namespaceIndex, NULL, false, &UA_TYPES[UA_TYPES_UINT16]}
99074 };
99075
99076 return decodeFields(ctx, entries, entryCount: 2);
99077}
99078
99079UA_FUNC_ATTR_WARN_UNUSED_RESULT status
99080lookAheadForKey(ParseCtx *ctx, const char *key, size_t *resultIndex) {
99081 /* The current index must point to the beginning of an object.
99082 * This has to be ensured by the caller. */
99083 UA_assert(currentTokenType(ctx) == CJ5_TOKEN_OBJECT);
99084
99085 status ret = UA_STATUSCODE_BADNOTFOUND;
99086 size_t oldIndex = ctx->index; /* Save index for later restore */
99087 unsigned int end = ctx->tokens[ctx->index].end;
99088 ctx->index++; /* Move to the first key */
99089 while(ctx->index < ctx->tokensSize &&
99090 ctx->tokens[ctx->index].start < end) {
99091 /* Key must be a string */
99092 UA_assert(currentTokenType(ctx) == CJ5_TOKEN_STRING);
99093
99094 /* Move index to the value */
99095 ctx->index++;
99096
99097 /* Value for the key must exist */
99098 UA_assert(ctx->index < ctx->tokensSize);
99099
99100 /* Compare the key (previous index) */
99101 if(jsoneq(json: ctx->json5, tok: &ctx->tokens[ctx->index-1], searchKey: key) == 0) {
99102 *resultIndex = ctx->index; /* Point result to the current index */
99103 ret = UA_STATUSCODE_GOOD;
99104 break;
99105 }
99106
99107 skipObject(ctx); /* Jump over the value (can also be an array or object) */
99108 }
99109 ctx->index = oldIndex; /* Restore the old index */
99110 return ret;
99111}
99112
99113static status
99114prepareDecodeNodeIdJson(ParseCtx *ctx, UA_NodeId *dst,
99115 u8 *fieldCount, DecodeEntry *entries) {
99116 UA_assert(currentTokenType(ctx) == CJ5_TOKEN_OBJECT);
99117
99118 /* possible keys: Id, IdType, NamespaceIndex */
99119 /* Id must always be present */
99120 entries[*fieldCount].fieldName = UA_JSONKEY_ID;
99121 entries[*fieldCount].found = false;
99122 entries[*fieldCount].type = NULL;
99123 entries[*fieldCount].function = NULL;
99124
99125 /* IdType */
99126 size_t idIndex = 0;
99127 status ret = lookAheadForKey(ctx, key: UA_JSONKEY_IDTYPE, resultIndex: &idIndex);
99128 if(ret == UA_STATUSCODE_GOOD) {
99129 size_t size = getTokenLength(t: &ctx->tokens[idIndex]);
99130 if(size < 1)
99131 return UA_STATUSCODE_BADDECODINGERROR;
99132
99133 const char *idType = &ctx->json5[ctx->tokens[idIndex].start];
99134
99135 if(idType[0] == '2') {
99136 dst->identifierType = UA_NODEIDTYPE_GUID;
99137 entries[*fieldCount].fieldPointer = &dst->identifier.guid;
99138 entries[*fieldCount].type = &UA_TYPES[UA_TYPES_GUID];
99139 } else if(idType[0] == '1') {
99140 dst->identifierType = UA_NODEIDTYPE_STRING;
99141 entries[*fieldCount].fieldPointer = &dst->identifier.string;
99142 entries[*fieldCount].type = &UA_TYPES[UA_TYPES_STRING];
99143 } else if(idType[0] == '3') {
99144 dst->identifierType = UA_NODEIDTYPE_BYTESTRING;
99145 entries[*fieldCount].fieldPointer = &dst->identifier.byteString;
99146 entries[*fieldCount].type = &UA_TYPES[UA_TYPES_BYTESTRING];
99147 } else {
99148 return UA_STATUSCODE_BADDECODINGERROR;
99149 }
99150
99151 /* Id always present */
99152 (*fieldCount)++;
99153
99154 entries[*fieldCount].fieldName = UA_JSONKEY_IDTYPE;
99155 entries[*fieldCount].fieldPointer = NULL;
99156 entries[*fieldCount].function = NULL;
99157 entries[*fieldCount].found = false;
99158 entries[*fieldCount].type = NULL;
99159
99160 /* IdType */
99161 (*fieldCount)++;
99162 } else {
99163 dst->identifierType = UA_NODEIDTYPE_NUMERIC;
99164 entries[*fieldCount].fieldPointer = &dst->identifier.numeric;
99165 entries[*fieldCount].function = NULL;
99166 entries[*fieldCount].found = false;
99167 entries[*fieldCount].type = &UA_TYPES[UA_TYPES_UINT32];
99168 (*fieldCount)++;
99169 }
99170
99171 /* NodeId has a NamespaceIndex (the ExpandedNodeId specialization may
99172 * overwrite this) */
99173 entries[*fieldCount].fieldName = UA_JSONKEY_NAMESPACE;
99174 entries[*fieldCount].fieldPointer = &dst->namespaceIndex;
99175 entries[*fieldCount].function = NULL;
99176 entries[*fieldCount].found = false;
99177 entries[*fieldCount].type = &UA_TYPES[UA_TYPES_UINT16];
99178 (*fieldCount)++;
99179
99180 return UA_STATUSCODE_GOOD;
99181}
99182
99183DECODE_JSON(NodeId) {
99184 /* Non-standard decoding of NodeIds from the string representation */
99185 if(currentTokenType(ctx) == CJ5_TOKEN_STRING) {
99186 GET_TOKEN;
99187 UA_String str = {tokenSize, (UA_Byte*)(uintptr_t)tokenData};
99188 ctx->index++;
99189 return UA_NodeId_parse(id: dst, str);
99190 }
99191
99192 /* Object representation */
99193 CHECK_OBJECT;
99194
99195 u8 fieldCount = 0;
99196 DecodeEntry entries[3];
99197 status ret = prepareDecodeNodeIdJson(ctx, dst, fieldCount: &fieldCount, entries);
99198 if(ret != UA_STATUSCODE_GOOD)
99199 return ret;
99200 return decodeFields(ctx, entries, entryCount: fieldCount);
99201}
99202
99203static status
99204decodeExpandedNodeIdNamespace(ParseCtx *ctx, void *dst, const UA_DataType *type) {
99205 UA_ExpandedNodeId *en = (UA_ExpandedNodeId*)dst;
99206
99207 /* Parse as a number */
99208 size_t oldIndex = ctx->index;
99209 status ret = UInt16_decodeJson(ctx, dst: &en->nodeId.namespaceIndex, NULL);
99210 if(ret == UA_STATUSCODE_GOOD)
99211 return ret;
99212
99213 /* Parse as a string */
99214 ctx->index = oldIndex; /* Reset the index */
99215 ret = String_decodeJson(ctx, dst: &en->namespaceUri, NULL);
99216 if(ret != UA_STATUSCODE_GOOD)
99217 return ret;
99218
99219 /* Replace with the index if the URI is found. Otherwise keep the string. */
99220 for(size_t i = 0; i < ctx->namespacesSize; i++) {
99221 if(UA_String_equal(p1: &en->namespaceUri, p2: &ctx->namespaces[i])) {
99222 UA_String_clear(p: &en->namespaceUri);
99223 en->nodeId.namespaceIndex = (UA_UInt16)i;
99224 break;
99225 }
99226 }
99227
99228 return UA_STATUSCODE_GOOD;
99229}
99230
99231static status
99232decodeExpandedNodeIdServerUri(ParseCtx *ctx, void *dst, const UA_DataType *type) {
99233 UA_ExpandedNodeId *en = (UA_ExpandedNodeId*)dst;
99234
99235 /* Parse as a number */
99236 size_t oldIndex = ctx->index;
99237 status ret = UInt32_decodeJson(ctx, dst: &en->serverIndex, NULL);
99238 if(ret == UA_STATUSCODE_GOOD)
99239 return ret;
99240
99241 /* Parse as a string */
99242 UA_String uri = UA_STRING_NULL;
99243 ctx->index = oldIndex; /* Reset the index */
99244 ret = String_decodeJson(ctx, dst: &uri, NULL);
99245 if(ret != UA_STATUSCODE_GOOD)
99246 return ret;
99247
99248 /* Try to translate the URI into an index */
99249 ret = UA_STATUSCODE_BADDECODINGERROR;
99250 for(size_t i = 0; i < ctx->serverUrisSize; i++) {
99251 if(UA_String_equal(p1: &uri, p2: &ctx->serverUris[i])) {
99252 en->serverIndex = (UA_UInt32)i;
99253 ret = UA_STATUSCODE_GOOD;
99254 break;
99255 }
99256 }
99257
99258 UA_String_clear(p: &uri);
99259 return ret;
99260}
99261
99262DECODE_JSON(ExpandedNodeId) {
99263 /* Non-standard decoding of ExpandedNodeIds from the string representation */
99264 if(currentTokenType(ctx) == CJ5_TOKEN_STRING) {
99265 GET_TOKEN;
99266 UA_String str = {tokenSize, (UA_Byte*)(uintptr_t)tokenData};
99267 ctx->index++;
99268 return UA_ExpandedNodeId_parse(id: dst, str);
99269 }
99270
99271 /* Object representation */
99272 CHECK_OBJECT;
99273
99274 u8 fieldCount = 0;
99275 DecodeEntry entries[4];
99276 status ret = prepareDecodeNodeIdJson(ctx, dst: &dst->nodeId, fieldCount: &fieldCount, entries);
99277 if(ret != UA_STATUSCODE_GOOD)
99278 return ret;
99279
99280 /* Overwrite the namespace entry */
99281 fieldCount--;
99282 entries[fieldCount].fieldPointer = dst;
99283 entries[fieldCount].function = decodeExpandedNodeIdNamespace;
99284 entries[fieldCount].type = NULL;
99285 fieldCount++;
99286
99287 entries[fieldCount].fieldName = UA_JSONKEY_SERVERURI;
99288 entries[fieldCount].fieldPointer = dst;
99289 entries[fieldCount].function = decodeExpandedNodeIdServerUri;
99290 entries[fieldCount].found = false;
99291 entries[fieldCount].type = NULL;
99292 fieldCount++;
99293
99294 return decodeFields(ctx, entries, entryCount: fieldCount);
99295}
99296
99297DECODE_JSON(DateTime) {
99298 CHECK_TOKEN_BOUNDS;
99299 CHECK_STRING;
99300 GET_TOKEN;
99301
99302 /* The last character has to be 'Z'. We can omit some length checks later on
99303 * because we know the atoi functions stop before the 'Z'. */
99304 if(tokenSize == 0 || tokenData[tokenSize-1] != 'Z')
99305 return UA_STATUSCODE_BADDECODINGERROR;
99306
99307 struct musl_tm dts;
99308 memset(s: &dts, c: 0, n: sizeof(dts));
99309
99310 size_t pos = 0;
99311 size_t len;
99312
99313 /* Parse the year. The ISO standard asks for four digits. But we accept up
99314 * to five with an optional plus or minus in front due to the range of the
99315 * DateTime 64bit integer. But in that case we require the year and the
99316 * month to be separated by a '-'. Otherwise we cannot know where the month
99317 * starts. */
99318 if(tokenData[0] == '-' || tokenData[0] == '+')
99319 pos++;
99320 UA_Int64 year = 0;
99321 len = parseInt64(str: &tokenData[pos], size: 5, result: &year);
99322 pos += len;
99323 if(len != 4 && tokenData[pos] != '-')
99324 return UA_STATUSCODE_BADDECODINGERROR;
99325 if(tokenData[0] == '-')
99326 year = -year;
99327 dts.tm_year = (UA_Int16)year - 1900;
99328 if(tokenData[pos] == '-')
99329 pos++;
99330
99331 /* Parse the month */
99332 UA_UInt64 month = 0;
99333 len = parseUInt64(str: &tokenData[pos], size: 2, result: &month);
99334 pos += len;
99335 UA_CHECK(len == 2, return UA_STATUSCODE_BADDECODINGERROR);
99336 dts.tm_mon = (UA_UInt16)month - 1;
99337 if(tokenData[pos] == '-')
99338 pos++;
99339
99340 /* Parse the day and check the T between date and time */
99341 UA_UInt64 day = 0;
99342 len = parseUInt64(str: &tokenData[pos], size: 2, result: &day);
99343 pos += len;
99344 UA_CHECK(len == 2 || tokenData[pos] != 'T',
99345 return UA_STATUSCODE_BADDECODINGERROR);
99346 dts.tm_mday = (UA_UInt16)day;
99347 pos++;
99348
99349 /* Parse the hour */
99350 UA_UInt64 hour = 0;
99351 len = parseUInt64(str: &tokenData[pos], size: 2, result: &hour);
99352 pos += len;
99353 UA_CHECK(len == 2, return UA_STATUSCODE_BADDECODINGERROR);
99354 dts.tm_hour = (UA_UInt16)hour;
99355 if(tokenData[pos] == ':')
99356 pos++;
99357
99358 /* Parse the minute */
99359 UA_UInt64 min = 0;
99360 len = parseUInt64(str: &tokenData[pos], size: 2, result: &min);
99361 pos += len;
99362 UA_CHECK(len == 2, return UA_STATUSCODE_BADDECODINGERROR);
99363 dts.tm_min = (UA_UInt16)min;
99364 if(tokenData[pos] == ':')
99365 pos++;
99366
99367 /* Parse the second */
99368 UA_UInt64 sec = 0;
99369 len = parseUInt64(str: &tokenData[pos], size: 2, result: &sec);
99370 pos += len;
99371 UA_CHECK(len == 2, return UA_STATUSCODE_BADDECODINGERROR);
99372 dts.tm_sec = (UA_UInt16)sec;
99373
99374 /* Compute the seconds since the Unix epoch */
99375 long long sinceunix = musl_tm_to_secs(tm: &dts);
99376
99377 /* Are we within the range that can be represented? */
99378 long long sinceunix_min =
99379 (long long)(UA_INT64_MIN / UA_DATETIME_SEC) -
99380 (long long)(UA_DATETIME_UNIX_EPOCH / UA_DATETIME_SEC) -
99381 (long long)1; /* manual correction due to rounding */
99382 long long sinceunix_max = (long long)
99383 ((UA_INT64_MAX - UA_DATETIME_UNIX_EPOCH) / UA_DATETIME_SEC);
99384 if(sinceunix < sinceunix_min || sinceunix > sinceunix_max)
99385 return UA_STATUSCODE_BADDECODINGERROR;
99386
99387 /* Convert to DateTime. Add or subtract one extra second here to prevent
99388 * underflow/overflow. This is reverted once the fractional part has been
99389 * added. */
99390 sinceunix -= (sinceunix > 0) ? 1 : -1;
99391 UA_DateTime dt = (UA_DateTime)
99392 (sinceunix + (UA_DATETIME_UNIX_EPOCH / UA_DATETIME_SEC)) * UA_DATETIME_SEC;
99393
99394 /* Parse the fraction of the second if defined */
99395 if(tokenData[pos] == ',' || tokenData[pos] == '.') {
99396 pos++;
99397 double frac = 0.0;
99398 double denom = 0.1;
99399 while(pos < tokenSize &&
99400 tokenData[pos] >= '0' && tokenData[pos] <= '9') {
99401 frac += denom * (tokenData[pos] - '0');
99402 denom *= 0.1;
99403 pos++;
99404 }
99405 frac += 0.00000005; /* Correct rounding when converting to integer */
99406 dt += (UA_DateTime)(frac * UA_DATETIME_SEC);
99407 }
99408
99409 /* Remove the underflow/overflow protection (see above) */
99410 if(sinceunix > 0) {
99411 if(dt > UA_INT64_MAX - UA_DATETIME_SEC)
99412 return UA_STATUSCODE_BADDECODINGERROR;
99413 dt += UA_DATETIME_SEC;
99414 } else {
99415 if(dt < UA_INT64_MIN + UA_DATETIME_SEC)
99416 return UA_STATUSCODE_BADDECODINGERROR;
99417 dt -= UA_DATETIME_SEC;
99418 }
99419
99420 /* We must be at the end of the string (ending with 'Z' as checked above) */
99421 if(pos != tokenSize - 1)
99422 return UA_STATUSCODE_BADDECODINGERROR;
99423
99424 *dst = dt;
99425
99426 ctx->index++;
99427 return UA_STATUSCODE_GOOD;
99428}
99429
99430DECODE_JSON(StatusCode) {
99431 return UInt32_decodeJson(ctx, dst, NULL);
99432}
99433
99434static status
99435VariantDimension_decodeJson(ParseCtx *ctx, void *dst, const UA_DataType *type) {
99436 (void) type;
99437 const UA_DataType *dimType = &UA_TYPES[UA_TYPES_UINT32];
99438 return Array_decodeJson(ctx, dst: (void**)dst, type: dimType);
99439}
99440
99441/* Get type type encoded by the ExtensionObject at ctx->index.
99442 * Returns NULL if that fails (type unknown or otherwise). */
99443static const UA_DataType *
99444getExtensionObjectType(ParseCtx *ctx) {
99445 if(currentTokenType(ctx) != CJ5_TOKEN_OBJECT)
99446 return NULL;
99447
99448 /* Get the type NodeId index */
99449 size_t typeIdIndex = 0;
99450 UA_StatusCode ret = lookAheadForKey(ctx, key: UA_JSONKEY_TYPEID, resultIndex: &typeIdIndex);
99451 if(ret != UA_STATUSCODE_GOOD)
99452 return NULL;
99453
99454 size_t oldIndex = ctx->index;
99455 ctx->index = typeIdIndex;
99456
99457 /* Decode the type NodeId */
99458 UA_NodeId typeId;
99459 UA_NodeId_init(p: &typeId);
99460 ret = NodeId_decodeJson(ctx, dst: &typeId, type: &UA_TYPES[UA_TYPES_NODEID]);
99461 ctx->index = oldIndex;
99462 if(ret != UA_STATUSCODE_GOOD) {
99463 UA_NodeId_clear(p: &typeId); /* We don't have the global cleanup */
99464 return NULL;
99465 }
99466
99467 /* Lookup an return */
99468 const UA_DataType *type = UA_findDataTypeWithCustom(typeId: &typeId, customTypes: ctx->customTypes);
99469 UA_NodeId_clear(p: &typeId);
99470 return type;
99471}
99472
99473/* Check if all array members are ExtensionObjects of the same type. Return this
99474 * type or NULL. */
99475static const UA_DataType *
99476getArrayUnwrapType(ParseCtx *ctx, size_t arrayIndex) {
99477 UA_assert(ctx->tokens[arrayIndex].type == CJ5_TOKEN_ARRAY);
99478
99479 /* Save index to restore later */
99480 size_t oldIndex = ctx->index;
99481 ctx->index = arrayIndex;
99482
99483 /* Return early for empty arrays */
99484 size_t length = (size_t)ctx->tokens[ctx->index].size;
99485 if(length == 0) {
99486 ctx->index = oldIndex; /* Restore the index */
99487 return NULL;
99488 }
99489
99490 /* Go to first array member */
99491 ctx->index++;
99492
99493 /* Lookup the type for the first array member */
99494 UA_NodeId typeId;
99495 UA_NodeId_init(p: &typeId);
99496 const UA_DataType *typeOfBody = getExtensionObjectType(ctx);
99497 if(!typeOfBody) {
99498 ctx->index = oldIndex; /* Restore the index */
99499 return NULL;
99500 }
99501
99502 /* The content is a builtin type that could have been directly encoded in
99503 * the Variant, there was no need to wrap in an ExtensionObject. But this
99504 * means for us, that somebody made an extra effort to explicitly get an
99505 * ExtensionObject. So we keep it. As an added advantage we will generate
99506 * the same JSON again when encoding again. */
99507 UA_Boolean isBuiltin = (typeOfBody->typeKind <= UA_DATATYPEKIND_DIAGNOSTICINFO);
99508 if(isBuiltin) {
99509 ctx->index = oldIndex; /* Restore the index */
99510 return NULL;
99511 }
99512
99513 /* Get the typeId index for faster comparison below.
99514 * Cannot fail as getExtensionObjectType already looked this up. */
99515 size_t typeIdIndex = 0;
99516 UA_StatusCode ret = lookAheadForKey(ctx, key: UA_JSONKEY_TYPEID, resultIndex: &typeIdIndex);
99517 (void)ret;
99518 UA_assert(ret == UA_STATUSCODE_GOOD);
99519 const char* typeIdData = &ctx->json5[ctx->tokens[typeIdIndex].start];
99520 size_t typeIdSize = getTokenLength(t: &ctx->tokens[typeIdIndex]);
99521
99522 /* Loop over all members and check whether they can be unwrapped */
99523 for(size_t i = 0; i < length; i++) {
99524 /* Array element must be an object */
99525 if(currentTokenType(ctx) != CJ5_TOKEN_OBJECT) {
99526 ctx->index = oldIndex; /* Restore the index */
99527 return NULL;
99528 }
99529
99530 /* Check for non-JSON encoding */
99531 size_t encIndex = 0;
99532 ret = lookAheadForKey(ctx, key: UA_JSONKEY_ENCODING, resultIndex: &encIndex);
99533 if(ret == UA_STATUSCODE_GOOD) {
99534 ctx->index = oldIndex; /* Restore the index */
99535 return NULL;
99536 }
99537
99538 /* Get the type NodeId index */
99539 size_t memberTypeIdIndex = 0;
99540 ret = lookAheadForKey(ctx, key: UA_JSONKEY_TYPEID, resultIndex: &memberTypeIdIndex);
99541 if(ret != UA_STATUSCODE_GOOD) {
99542 ctx->index = oldIndex; /* Restore the index */
99543 return NULL;
99544 }
99545
99546 /* Is it the same type? Compare raw NodeId string */
99547 const char* memberTypeIdData = &ctx->json5[ctx->tokens[memberTypeIdIndex].start];
99548 size_t memberTypeIdSize = getTokenLength(t: &ctx->tokens[memberTypeIdIndex]);
99549 if(typeIdSize != memberTypeIdSize ||
99550 memcmp(s1: typeIdData, s2: memberTypeIdData, n: typeIdSize) != 0) {
99551 ctx->index = oldIndex; /* Restore the index */
99552 return NULL;
99553 }
99554
99555 /* Skip to the next array member */
99556 skipObject(ctx);
99557 }
99558
99559 ctx->index = oldIndex; /* Restore the index */
99560 return typeOfBody;
99561}
99562
99563static status
99564Array_decodeJsonUnwrapExtensionObject(ParseCtx *ctx, void **dst, const UA_DataType *type) {
99565 size_t *size_ptr = (size_t*) dst - 1; /* Save the length pointer of the array */
99566 size_t length = (size_t)ctx->tokens[ctx->index].size;
99567
99568 /* Known from the previous unwrapping-check */
99569 UA_assert(currentTokenType(ctx) == CJ5_TOKEN_ARRAY);
99570 UA_assert(length > 0);
99571
99572 ctx->index++; /* Go to first array member */
99573
99574 /* Allocate memory */
99575 *dst = UA_calloc(nmemb: length, size: type->memSize);
99576 if(*dst == NULL)
99577 return UA_STATUSCODE_BADOUTOFMEMORY;
99578
99579 /* Decode array members */
99580 uintptr_t ptr = (uintptr_t)*dst;
99581 for(size_t i = 0; i < length; i++) {
99582 UA_assert(ctx->tokens[ctx->index].type == CJ5_TOKEN_OBJECT);
99583
99584 /* Get the body field and decode it */
99585 DecodeEntry entries[3] = {
99586 {UA_JSONKEY_TYPEID, NULL, NULL, false, NULL},
99587 {UA_JSONKEY_BODY, (void*)ptr, NULL, false, type},
99588 {UA_JSONKEY_ENCODING, NULL, NULL, false, NULL}
99589 };
99590 status ret = decodeFields(ctx, entries, entryCount: 3); /* Also skips to the next object */
99591 if(ret != UA_STATUSCODE_GOOD) {
99592 UA_Array_delete(p: *dst, size: i+1, type);
99593 *dst = NULL;
99594 return ret;
99595 }
99596 ptr += type->memSize;
99597 }
99598
99599 *size_ptr = length; /* All good, set the size */
99600 return UA_STATUSCODE_GOOD;
99601}
99602
99603DECODE_JSON(Variant) {
99604 CHECK_NULL_SKIP; /* Treat null as an empty variant */
99605 CHECK_OBJECT;
99606
99607 /* First search for the variant type in the json object. */
99608 size_t typeIndex = 0;
99609 status ret = lookAheadForKey(ctx, key: UA_JSONKEY_TYPE, resultIndex: &typeIndex);
99610 if(ret != UA_STATUSCODE_GOOD) {
99611 skipObject(ctx);
99612 return UA_STATUSCODE_GOOD;
99613 }
99614
99615 /* Parse the type */
99616 if(ctx->tokens[typeIndex].type != CJ5_TOKEN_NUMBER)
99617 return UA_STATUSCODE_BADDECODINGERROR;
99618 UA_UInt64 idType = 0;
99619 size_t len = parseUInt64(str: &ctx->json5[ctx->tokens[typeIndex].start],
99620 size: getTokenLength(t: &ctx->tokens[typeIndex]), result: &idType);
99621 if(len == 0)
99622 return UA_STATUSCODE_BADDECODINGERROR;
99623
99624 /* A NULL Variant */
99625 if(idType == 0) {
99626 skipObject(ctx);
99627 return UA_STATUSCODE_GOOD;
99628 }
99629
99630 /* Set the type */
99631 UA_NodeId typeNodeId = UA_NODEID_NUMERIC(nsIndex: 0, identifier: (UA_UInt32)idType);
99632 dst->type = UA_findDataTypeWithCustom(typeId: &typeNodeId, customTypes: ctx->customTypes);
99633 if(!dst->type)
99634 return UA_STATUSCODE_BADDECODINGERROR;
99635
99636 /* Search for body */
99637 size_t bodyIndex = 0;
99638 ret = lookAheadForKey(ctx, key: UA_JSONKEY_BODY, resultIndex: &bodyIndex);
99639 if(ret != UA_STATUSCODE_GOOD)
99640 return UA_STATUSCODE_BADDECODINGERROR;
99641
99642 /* Value is an array? */
99643 UA_Boolean isArray = (ctx->tokens[bodyIndex].type == CJ5_TOKEN_ARRAY);
99644
99645 /* TODO: Handling of null-arrays (length -1) needs to be clarified
99646 *
99647 * if(tokenIsNull(ctx, bodyIndex)) {
99648 * isArray = true;
99649 * dst->arrayLength = 0;
99650 * } */
99651
99652 /* Has the variant dimension? */
99653 UA_Boolean hasDimension = false;
99654 size_t dimIndex = 0;
99655 ret = lookAheadForKey(ctx, key: UA_JSONKEY_DIMENSION, resultIndex: &dimIndex);
99656 if(ret == UA_STATUSCODE_GOOD)
99657 hasDimension = (ctx->tokens[dimIndex].size > 0);
99658
99659 /* No array but has dimension -> error */
99660 if(!isArray && hasDimension)
99661 return UA_STATUSCODE_BADDECODINGERROR;
99662
99663 /* Get the datatype of the content. The type must be a builtin data type.
99664 * All not-builtin types are wrapped in an ExtensionObject. */
99665 if(dst->type->typeKind > UA_DATATYPEKIND_DIAGNOSTICINFO)
99666 return UA_STATUSCODE_BADDECODINGERROR;
99667
99668 /* A variant cannot contain a variant. But it can contain an array of
99669 * variants */
99670 if(dst->type->typeKind == UA_DATATYPEKIND_VARIANT && !isArray)
99671 return UA_STATUSCODE_BADDECODINGERROR;
99672
99673 /* Decode an array */
99674 if(isArray) {
99675 DecodeEntry entries[3] = {
99676 {UA_JSONKEY_TYPE, NULL, NULL, false, NULL},
99677 {UA_JSONKEY_BODY, &dst->data, (decodeJsonSignature)Array_decodeJson, false, dst->type},
99678 {UA_JSONKEY_DIMENSION, &dst->arrayDimensions, VariantDimension_decodeJson, false, NULL}
99679 };
99680
99681 /* Try to unwrap ExtensionObjects in the array.
99682 * The members must all have the same type. */
99683 if(dst->type == &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]) {
99684 const UA_DataType *unwrapType = getArrayUnwrapType(ctx, arrayIndex: bodyIndex);
99685 if(unwrapType) {
99686 dst->type = unwrapType;
99687 entries[1].type = unwrapType;
99688 entries[1].function = (decodeJsonSignature)
99689 Array_decodeJsonUnwrapExtensionObject;
99690 }
99691 }
99692
99693 return decodeFields(ctx, entries, entryCount: (hasDimension) ? 3 : 2);
99694 }
99695
99696 /* Decode a value wrapped in an ExtensionObject */
99697 if(dst->type->typeKind == UA_DATATYPEKIND_EXTENSIONOBJECT) {
99698 DecodeEntry entries[2] = {
99699 {UA_JSONKEY_TYPE, NULL, NULL, false, NULL},
99700 {UA_JSONKEY_BODY, dst, Variant_decodeJsonUnwrapExtensionObject, false, NULL}
99701 };
99702 return decodeFields(ctx, entries, entryCount: 2);
99703 }
99704
99705 /* Allocate Memory for Body */
99706 dst->data = UA_new(type: dst->type);
99707 if(!dst->data)
99708 return UA_STATUSCODE_BADOUTOFMEMORY;
99709
99710 DecodeEntry entries[2] = {
99711 {.fieldName: UA_JSONKEY_TYPE, NULL, NULL, false, NULL},
99712 {UA_JSONKEY_BODY, dst->data, NULL, false, dst->type}
99713 };
99714 return decodeFields(ctx, entries, entryCount: 2);
99715}
99716
99717DECODE_JSON(DataValue) {
99718 CHECK_NULL_SKIP; /* Treat a null value as an empty DataValue */
99719 CHECK_OBJECT;
99720
99721 DecodeEntry entries[6] = {
99722 {UA_JSONKEY_VALUE, &dst->value, NULL, false, &UA_TYPES[UA_TYPES_VARIANT]},
99723 {UA_JSONKEY_STATUS, &dst->status, NULL, false, &UA_TYPES[UA_TYPES_STATUSCODE]},
99724 {UA_JSONKEY_SOURCETIMESTAMP, &dst->sourceTimestamp, NULL, false, &UA_TYPES[UA_TYPES_DATETIME]},
99725 {UA_JSONKEY_SOURCEPICOSECONDS, &dst->sourcePicoseconds, NULL, false, &UA_TYPES[UA_TYPES_UINT16]},
99726 {UA_JSONKEY_SERVERTIMESTAMP, &dst->serverTimestamp, NULL, false, &UA_TYPES[UA_TYPES_DATETIME]},
99727 {UA_JSONKEY_SERVERPICOSECONDS, &dst->serverPicoseconds, NULL, false, &UA_TYPES[UA_TYPES_UINT16]}
99728 };
99729
99730 status ret = decodeFields(ctx, entries, entryCount: 6);
99731 dst->hasValue = entries[0].found;
99732 dst->hasStatus = entries[1].found;
99733 dst->hasSourceTimestamp = entries[2].found;
99734 dst->hasSourcePicoseconds = entries[3].found;
99735 dst->hasServerTimestamp = entries[4].found;
99736 dst->hasServerPicoseconds = entries[5].found;
99737 return ret;
99738}
99739
99740/* Move the entire current token into the target bytestring */
99741static UA_StatusCode
99742tokenToByteString(ParseCtx *ctx, UA_ByteString *p, const UA_DataType *type) {
99743 GET_TOKEN;
99744 UA_StatusCode res = UA_ByteString_allocBuffer(bs: p, length: tokenSize);
99745 if(res != UA_STATUSCODE_GOOD)
99746 return res;
99747 memcpy(dest: p->data, src: tokenData, n: tokenSize);
99748 skipObject(ctx);
99749 return UA_STATUSCODE_GOOD;
99750}
99751
99752DECODE_JSON(ExtensionObject) {
99753 CHECK_NULL_SKIP; /* Treat a null value as an empty DataValue */
99754 CHECK_OBJECT;
99755
99756 /* Empty object -> Null ExtensionObject */
99757 if(ctx->tokens[ctx->index].size == 0) {
99758 ctx->index++; /* Skip the empty ExtensionObject */
99759 return UA_STATUSCODE_GOOD;
99760 }
99761
99762 /* Search for non-JSON encoding */
99763 UA_UInt64 encoding = 0;
99764 size_t encIndex = 0;
99765 status ret = lookAheadForKey(ctx, key: UA_JSONKEY_ENCODING, resultIndex: &encIndex);
99766 if(ret == UA_STATUSCODE_GOOD) {
99767 const char *extObjEncoding = &ctx->json5[ctx->tokens[encIndex].start];
99768 size_t len = parseUInt64(str: extObjEncoding, size: getTokenLength(t: &ctx->tokens[encIndex]),
99769 result: &encoding);
99770 if(len == 0)
99771 return UA_STATUSCODE_BADDECODINGERROR;
99772 }
99773
99774 /* Lookup the DataType for the ExtensionObject if the body can be decoded */
99775 const UA_DataType *typeOfBody = (encoding == 0) ? getExtensionObjectType(ctx) : NULL;
99776
99777 /* Keep the encoded body */
99778 if(!typeOfBody) {
99779 DecodeEntry entries[3] = {
99780 {UA_JSONKEY_ENCODING, NULL, NULL, false, NULL},
99781 {UA_JSONKEY_TYPEID, &dst->content.encoded.typeId, NULL, false, &UA_TYPES[UA_TYPES_NODEID]},
99782 {UA_JSONKEY_BODY, &dst->content.encoded.body, NULL, false, &UA_TYPES[UA_TYPES_STRING]}
99783 };
99784
99785 if(encoding == 0) {
99786 entries[2].function = (decodeJsonSignature)tokenToByteString;
99787 dst->encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING; /* ByteString in Json Body */
99788 } else if(encoding == 1) {
99789 dst->encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING; /* ByteString in Json Body */
99790 } else if(encoding == 2) {
99791 dst->encoding = UA_EXTENSIONOBJECT_ENCODED_XML; /* XmlElement in Json Body */
99792 } else {
99793 return UA_STATUSCODE_BADDECODINGERROR;
99794 }
99795 return decodeFields(ctx, entries, entryCount: 3);
99796 }
99797
99798 /* Allocate memory for the decoded data */
99799 dst->content.decoded.data = UA_new(type: typeOfBody);
99800 if(!dst->content.decoded.data)
99801 return UA_STATUSCODE_BADOUTOFMEMORY;
99802
99803 /* Set type */
99804 dst->content.decoded.type = typeOfBody;
99805 dst->encoding = UA_EXTENSIONOBJECT_DECODED;
99806
99807 /* Decode body */
99808 DecodeEntry entries[3] = {
99809 {UA_JSONKEY_ENCODING, NULL, NULL, false, NULL},
99810 {UA_JSONKEY_TYPEID, NULL, NULL, false, NULL},
99811 {UA_JSONKEY_BODY, dst->content.decoded.data, NULL, false, typeOfBody}
99812 };
99813 return decodeFields(ctx, entries, entryCount: 3);
99814}
99815
99816static status
99817Variant_decodeJsonUnwrapExtensionObject(ParseCtx *ctx, void *p, const UA_DataType *type) {
99818 (void) type;
99819 UA_Variant *dst = (UA_Variant*)p;
99820
99821 /* ExtensionObject with null body */
99822 if(currentTokenType(ctx) == CJ5_TOKEN_NULL) {
99823 dst->data = UA_ExtensionObject_new();
99824 dst->type = &UA_TYPES[UA_TYPES_EXTENSIONOBJECT];
99825 ctx->index++;
99826 return UA_STATUSCODE_GOOD;
99827 }
99828
99829 /* Decode the ExtensionObject */
99830 UA_ExtensionObject eo;
99831 UA_ExtensionObject_init(p: &eo);
99832 UA_StatusCode ret = ExtensionObject_decodeJson(ctx, dst: &eo, NULL);
99833 if(ret != UA_STATUSCODE_GOOD) {
99834 UA_ExtensionObject_clear(p: &eo); /* We don't have the global cleanup */
99835 return ret;
99836 }
99837
99838 /* The content is still encoded, cannot unwrap */
99839 if(eo.encoding != UA_EXTENSIONOBJECT_DECODED)
99840 goto use_eo;
99841
99842 /* The content is a builtin type that could have been directly encoded in
99843 * the Variant, there was no need to wrap in an ExtensionObject. But this
99844 * means for us, that somebody made an extra effort to explicitly get an
99845 * ExtensionObject. So we keep it. As an added advantage we will generate
99846 * the same JSON again when encoding again. */
99847 UA_Boolean isBuiltin =
99848 (eo.content.decoded.type->typeKind <= UA_DATATYPEKIND_DIAGNOSTICINFO);
99849 if(isBuiltin)
99850 goto use_eo;
99851
99852 /* Unwrap the ExtensionObject */
99853 dst->data = eo.content.decoded.data;
99854 dst->type = eo.content.decoded.type;
99855 return UA_STATUSCODE_GOOD;
99856
99857 use_eo:
99858 /* Don't unwrap */
99859 dst->data = UA_new(type: &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]);
99860 if(!dst->data) {
99861 UA_ExtensionObject_clear(p: &eo);
99862 return UA_STATUSCODE_BADOUTOFMEMORY;
99863 }
99864 dst->type = &UA_TYPES[UA_TYPES_EXTENSIONOBJECT];
99865 *(UA_ExtensionObject*)dst->data = eo;
99866 return UA_STATUSCODE_GOOD;
99867}
99868
99869status
99870DiagnosticInfoInner_decodeJson(ParseCtx* ctx, void* dst, const UA_DataType* type);
99871
99872DECODE_JSON(DiagnosticInfo) {
99873 CHECK_NULL_SKIP; /* Treat a null value as an empty DiagnosticInfo */
99874 CHECK_OBJECT;
99875
99876 DecodeEntry entries[7] = {
99877 {UA_JSONKEY_SYMBOLICID, &dst->symbolicId, NULL, false, &UA_TYPES[UA_TYPES_INT32]},
99878 {UA_JSONKEY_NAMESPACEURI, &dst->namespaceUri, NULL, false, &UA_TYPES[UA_TYPES_INT32]},
99879 {UA_JSONKEY_LOCALIZEDTEXT, &dst->localizedText, NULL, false, &UA_TYPES[UA_TYPES_INT32]},
99880 {UA_JSONKEY_LOCALE, &dst->locale, NULL, false, &UA_TYPES[UA_TYPES_INT32]},
99881 {UA_JSONKEY_ADDITIONALINFO, &dst->additionalInfo, NULL, false, &UA_TYPES[UA_TYPES_STRING]},
99882 {UA_JSONKEY_INNERSTATUSCODE, &dst->innerStatusCode, NULL, false, &UA_TYPES[UA_TYPES_STATUSCODE]},
99883 {UA_JSONKEY_INNERDIAGNOSTICINFO, &dst->innerDiagnosticInfo, DiagnosticInfoInner_decodeJson, false, NULL}
99884 };
99885 status ret = decodeFields(ctx, entries, entryCount: 7);
99886
99887 dst->hasSymbolicId = entries[0].found;
99888 dst->hasNamespaceUri = entries[1].found;
99889 dst->hasLocalizedText = entries[2].found;
99890 dst->hasLocale = entries[3].found;
99891 dst->hasAdditionalInfo = entries[4].found;
99892 dst->hasInnerStatusCode = entries[5].found;
99893 dst->hasInnerDiagnosticInfo = entries[6].found;
99894 return ret;
99895}
99896
99897status
99898DiagnosticInfoInner_decodeJson(ParseCtx* ctx, void* dst, const UA_DataType* type) {
99899 UA_DiagnosticInfo *inner = (UA_DiagnosticInfo*)
99900 UA_calloc(nmemb: 1, size: sizeof(UA_DiagnosticInfo));
99901 if(!inner)
99902 return UA_STATUSCODE_BADOUTOFMEMORY;
99903 UA_DiagnosticInfo **dst2 = (UA_DiagnosticInfo**)dst;
99904 *dst2 = inner; /* Copy new Pointer do dest */
99905 return DiagnosticInfo_decodeJson(ctx, dst: inner, type);
99906}
99907
99908status
99909decodeFields(ParseCtx *ctx, DecodeEntry *entries, size_t entryCount) {
99910 CHECK_TOKEN_BOUNDS;
99911 CHECK_NULL_SKIP; /* null is treated like an empty object */
99912
99913 if(ctx->depth >= UA_JSON_ENCODING_MAX_RECURSION - 1)
99914 return UA_STATUSCODE_BADENCODINGERROR;
99915
99916 /* Keys and values are counted separately */
99917 CHECK_OBJECT;
99918 UA_assert(ctx->tokens[ctx->index].size % 2 == 0);
99919 size_t keyCount = (size_t)(ctx->tokens[ctx->index].size) / 2;
99920
99921 ctx->index++; /* Go to first key - or jump after the empty object */
99922 ctx->depth++;
99923
99924 status ret = UA_STATUSCODE_GOOD;
99925 for(size_t key = 0; key < keyCount; key++) {
99926 /* Key must be a string */
99927 UA_assert(ctx->index < ctx->tokensSize);
99928 UA_assert(currentTokenType(ctx) == CJ5_TOKEN_STRING);
99929
99930 /* Search for the decoding entry matching the key. Start at the key
99931 * index to speed-up the case where they key-order is the same as the
99932 * entry-order. */
99933 DecodeEntry *entry = NULL;
99934 for(size_t i = key; i < key + entryCount; i++) {
99935 size_t ii = i;
99936 while(ii >= entryCount)
99937 ii -= entryCount;
99938
99939 /* Compare the key */
99940 if(jsoneq(json: ctx->json5, tok: &ctx->tokens[ctx->index],
99941 searchKey: entries[ii].fieldName) != 0)
99942 continue;
99943
99944 /* Key was already used -> duplicate, abort */
99945 if(entries[ii].found) {
99946 ctx->depth--;
99947 return UA_STATUSCODE_BADDECODINGERROR;
99948 }
99949
99950 /* Found the key */
99951 entries[ii].found = true;
99952 entry = &entries[ii];
99953 break;
99954 }
99955
99956 /* The key is unknown */
99957 if(!entry) {
99958 ret = UA_STATUSCODE_BADDECODINGERROR;
99959 break;
99960 }
99961
99962 /* Go from key to value */
99963 ctx->index++;
99964 UA_assert(ctx->index < ctx->tokensSize);
99965
99966 /* An entry that was expected but shall not be decoded.
99967 * Jump over the value. */
99968 if(!entry->function && !entry->type) {
99969 skipObject(ctx);
99970 continue;
99971 }
99972
99973 /* A null-value, skip the decoding (the value is already initialized) */
99974 if(currentTokenType(ctx) == CJ5_TOKEN_NULL && !entry->function) {
99975 ctx->index++; /* skip null value */
99976 continue;
99977 }
99978
99979 /* Decode. This also moves to the next key or right after the object for
99980 * the last value. */
99981 decodeJsonSignature decodeFunc = (entry->function) ?
99982 entry->function : decodeJsonJumpTable[entry->type->typeKind];
99983 ret = decodeFunc(ctx, entry->fieldPointer, entry->type);
99984 if(ret != UA_STATUSCODE_GOOD)
99985 break;
99986 }
99987
99988 ctx->depth--;
99989 return ret;
99990}
99991
99992static status
99993Array_decodeJson(ParseCtx *ctx, void **dst, const UA_DataType *type) {
99994 /* Save the length of the array */
99995 size_t *size_ptr = (size_t*) dst - 1;
99996
99997 if(currentTokenType(ctx) != CJ5_TOKEN_ARRAY)
99998 return UA_STATUSCODE_BADDECODINGERROR;
99999
100000 size_t length = (size_t)ctx->tokens[ctx->index].size;
100001
100002 ctx->index++; /* Go to first array member or to the first element after
100003 * the array (if empty) */
100004
100005 /* Return early for empty arrays */
100006 if(length == 0) {
100007 *size_ptr = length;
100008 *dst = UA_EMPTY_ARRAY_SENTINEL;
100009 return UA_STATUSCODE_GOOD;
100010 }
100011
100012 /* Allocate memory */
100013 *dst = UA_calloc(nmemb: length, size: type->memSize);
100014 if(*dst == NULL)
100015 return UA_STATUSCODE_BADOUTOFMEMORY;
100016
100017 /* Decode array members */
100018 uintptr_t ptr = (uintptr_t)*dst;
100019 for(size_t i = 0; i < length; ++i) {
100020 if(ctx->tokens[ctx->index].type != CJ5_TOKEN_NULL) {
100021 status ret = decodeJsonJumpTable[type->typeKind](ctx, (void*)ptr, type);
100022 if(ret != UA_STATUSCODE_GOOD) {
100023 UA_Array_delete(p: *dst, size: i+1, type);
100024 *dst = NULL;
100025 return ret;
100026 }
100027 } else {
100028 ctx->index++;
100029 }
100030 ptr += type->memSize;
100031 }
100032
100033 *size_ptr = length; /* All good, set the size */
100034 return UA_STATUSCODE_GOOD;
100035}
100036
100037static status
100038decodeJsonStructure(ParseCtx *ctx, void *dst, const UA_DataType *type) {
100039 /* Check the recursion limit */
100040 if(ctx->depth >= UA_JSON_ENCODING_MAX_RECURSION - 1)
100041 return UA_STATUSCODE_BADENCODINGERROR;
100042 ctx->depth++;
100043
100044 uintptr_t ptr = (uintptr_t)dst;
100045 status ret = UA_STATUSCODE_GOOD;
100046 u8 membersSize = type->membersSize;
100047 UA_STACKARRAY(DecodeEntry, entries, membersSize);
100048 for(size_t i = 0; i < membersSize; ++i) {
100049 const UA_DataTypeMember *m = &type->members[i];
100050 const UA_DataType *mt = m->memberType;
100051 entries[i].type = mt;
100052 entries[i].fieldName = m->memberName;
100053 entries[i].found = false;
100054 if(!m->isArray) {
100055 ptr += m->padding;
100056 entries[i].fieldPointer = (void*)ptr;
100057 entries[i].function = NULL;
100058 ptr += mt->memSize;
100059 } else {
100060 ptr += m->padding;
100061 ptr += sizeof(size_t);
100062 entries[i].fieldPointer = (void*)ptr;
100063 entries[i].function = (decodeJsonSignature)Array_decodeJson;
100064 ptr += sizeof(void*);
100065 }
100066 }
100067
100068 ret = decodeFields(ctx, entries, entryCount: membersSize);
100069
100070 if(ctx->depth == 0)
100071 return UA_STATUSCODE_BADENCODINGERROR;
100072 ctx->depth--;
100073 return ret;
100074}
100075
100076static status
100077decodeJsonNotImplemented(ParseCtx *ctx, void *dst, const UA_DataType *type) {
100078 (void)dst, (void)type, (void)ctx;
100079 return UA_STATUSCODE_BADNOTIMPLEMENTED;
100080}
100081
100082const decodeJsonSignature decodeJsonJumpTable[UA_DATATYPEKINDS] = {
100083 (decodeJsonSignature)Boolean_decodeJson,
100084 (decodeJsonSignature)SByte_decodeJson, /* SByte */
100085 (decodeJsonSignature)Byte_decodeJson,
100086 (decodeJsonSignature)Int16_decodeJson, /* Int16 */
100087 (decodeJsonSignature)UInt16_decodeJson,
100088 (decodeJsonSignature)Int32_decodeJson, /* Int32 */
100089 (decodeJsonSignature)UInt32_decodeJson,
100090 (decodeJsonSignature)Int64_decodeJson, /* Int64 */
100091 (decodeJsonSignature)UInt64_decodeJson,
100092 (decodeJsonSignature)Float_decodeJson,
100093 (decodeJsonSignature)Double_decodeJson,
100094 (decodeJsonSignature)String_decodeJson,
100095 (decodeJsonSignature)DateTime_decodeJson, /* DateTime */
100096 (decodeJsonSignature)Guid_decodeJson,
100097 (decodeJsonSignature)ByteString_decodeJson, /* ByteString */
100098 (decodeJsonSignature)String_decodeJson, /* XmlElement */
100099 (decodeJsonSignature)NodeId_decodeJson,
100100 (decodeJsonSignature)ExpandedNodeId_decodeJson,
100101 (decodeJsonSignature)StatusCode_decodeJson, /* StatusCode */
100102 (decodeJsonSignature)QualifiedName_decodeJson, /* QualifiedName */
100103 (decodeJsonSignature)LocalizedText_decodeJson,
100104 (decodeJsonSignature)ExtensionObject_decodeJson,
100105 (decodeJsonSignature)DataValue_decodeJson,
100106 (decodeJsonSignature)Variant_decodeJson,
100107 (decodeJsonSignature)DiagnosticInfo_decodeJson,
100108 (decodeJsonSignature)decodeJsonNotImplemented, /* Decimal */
100109 (decodeJsonSignature)Int32_decodeJson, /* Enum */
100110 (decodeJsonSignature)decodeJsonStructure,
100111 (decodeJsonSignature)decodeJsonNotImplemented, /* Structure with optional fields */
100112 (decodeJsonSignature)decodeJsonNotImplemented, /* Union */
100113 (decodeJsonSignature)decodeJsonNotImplemented /* BitfieldCluster */
100114};
100115
100116status
100117tokenize(ParseCtx *ctx, const UA_ByteString *src, size_t tokensSize) {
100118 /* Tokenize */
100119 cj5_result r = cj5_parse(json5: (char*)src->data, len: (unsigned int)src->length,
100120 tokens: ctx->tokens, max_tokens: (unsigned int)tokensSize, NULL);
100121
100122 /* Handle overflow error by allocating the number of tokens the parser would
100123 * have needed */
100124 if(r.error == CJ5_ERROR_OVERFLOW &&
100125 tokensSize != r.num_tokens) {
100126 ctx->tokens = (cj5_token*)
100127 UA_malloc(size: sizeof(cj5_token) * r.num_tokens);
100128 if(!ctx->tokens)
100129 return UA_STATUSCODE_BADOUTOFMEMORY;
100130 return tokenize(ctx, src, tokensSize: r.num_tokens);
100131 }
100132
100133 /* Cannot recover from other errors */
100134 if(r.error != CJ5_ERROR_NONE)
100135 return UA_STATUSCODE_BADDECODINGERROR;
100136
100137 /* Set up the context */
100138 ctx->json5 = (char*)src->data;
100139 ctx->depth = 0;
100140 ctx->tokensSize = r.num_tokens;
100141 ctx->index = 0;
100142 return UA_STATUSCODE_GOOD;
100143}
100144
100145UA_StatusCode
100146UA_decodeJson(const UA_ByteString *src, void *dst, const UA_DataType *type,
100147 const UA_DecodeJsonOptions *options) {
100148 if(!dst || !src || !type)
100149 return UA_STATUSCODE_BADARGUMENTSMISSING;
100150
100151 /* Set up the context */
100152 cj5_token tokens[UA_JSON_MAXTOKENCOUNT];
100153 ParseCtx ctx;
100154 memset(s: &ctx, c: 0, n: sizeof(ParseCtx));
100155 ctx.tokens = tokens;
100156
100157 if(options) {
100158 ctx.namespaces = options->namespaces;
100159 ctx.namespacesSize = options->namespacesSize;
100160 ctx.serverUris = options->serverUris;
100161 ctx.serverUrisSize = options->serverUrisSize;
100162 ctx.customTypes = options->customTypes;
100163 }
100164
100165 /* Decode */
100166 status ret = tokenize(ctx: &ctx, src, UA_JSON_MAXTOKENCOUNT);
100167 if(ret != UA_STATUSCODE_GOOD)
100168 goto cleanup;
100169
100170 memset(s: dst, c: 0, n: type->memSize); /* Initialize the value */
100171 ret = decodeJsonJumpTable[type->typeKind](&ctx, dst, type);
100172
100173 /* Sanity check if all tokens were processed */
100174 if(ctx.index != ctx.tokensSize &&
100175 ctx.index != ctx.tokensSize - 1)
100176 ret = UA_STATUSCODE_BADDECODINGERROR;
100177
100178 cleanup:
100179
100180 /* Free token array on the heap */
100181 if(ctx.tokens != tokens)
100182 UA_free(ptr: (void*)(uintptr_t)ctx.tokens);
100183
100184 if(ret != UA_STATUSCODE_GOOD)
100185 UA_clear(p: dst, type);
100186 return ret;
100187}
100188
100189#endif /* UA_ENABLE_JSON_ENCODING */
100190
100191/**** amalgamated original file "/src/server/ua_subscription.c" ****/
100192
100193/* This Source Code Form is subject to the terms of the Mozilla Public
100194 * License, v. 2.0. If a copy of the MPL was not distributed with this
100195 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
100196 *
100197 * Copyright 2015-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
100198 * Copyright 2015 (c) Chris Iatrou
100199 * Copyright 2015-2016 (c) Sten Grüner
100200 * Copyright 2017-2018 (c) Thomas Stalder, Blue Time Concept SA
100201 * Copyright 2015 (c) Joakim L. Gilje
100202 * Copyright 2016-2017 (c) Florian Palm
100203 * Copyright 2015-2016 (c) Oleksiy Vasylyev
100204 * Copyright 2017 (c) frax2222
100205 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
100206 * Copyright 2017 (c) Ari Breitkreuz, fortiss GmbH
100207 * Copyright 2017 (c) Mattias Bornhager
100208 * Copyright 2018 (c) Hilscher Gesellschaft für Systemautomation mbH (Author: Martin Lang)
100209 * Copyright 2019 (c) HMS Industrial Networks AB (Author: Jonas Green)
100210 */
100211
100212
100213#ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */
100214
100215#define UA_MAX_RETRANSMISSIONQUEUESIZE 256
100216
100217UA_Subscription *
100218UA_Subscription_new(void) {
100219 /* Allocate the memory */
100220 UA_Subscription *newSub = (UA_Subscription*)UA_calloc(nmemb: 1, size: sizeof(UA_Subscription));
100221 if(!newSub)
100222 return NULL;
100223
100224 /* The first publish response is sent immediately */
100225 newSub->state = UA_SUBSCRIPTIONSTATE_STOPPED;
100226
100227 /* Even if the first publish response is a keepalive the sequence number is 1.
100228 * This can happen by a subscription without a monitored item (see CTT test scripts). */
100229 newSub->nextSequenceNumber = 1;
100230
100231 TAILQ_INIT(&newSub->retransmissionQueue);
100232 TAILQ_INIT(&newSub->notificationQueue);
100233 return newSub;
100234}
100235
100236static void
100237delayedFreeSubscription(void *app, void *context) {
100238 UA_free(ptr: context);
100239}
100240
100241void
100242UA_Subscription_delete(UA_Server *server, UA_Subscription *sub) {
100243 UA_LOCK_ASSERT(&server->serviceMutex, 1);
100244
100245 UA_EventLoop *el = server->config.eventLoop;
100246
100247 /* Unregister the publish callback and possible delayed callback */
100248 Subscription_setState(server, sub, state: UA_SUBSCRIPTIONSTATE_REMOVING);
100249
100250 /* Remove delayed callbacks for processing remaining notifications */
100251 if(sub->delayedCallbackRegistered) {
100252 el->removeDelayedCallback(el, &sub->delayedMoreNotifications);
100253 sub->delayedCallbackRegistered = false;
100254 }
100255
100256 /* Remove the diagnostics object for the subscription */
100257#ifdef UA_ENABLE_DIAGNOSTICS
100258 if(!UA_NodeId_isNull(p: &sub->ns0Id))
100259 deleteNode(server, nodeId: sub->ns0Id, true);
100260 UA_NodeId_clear(p: &sub->ns0Id);
100261#endif
100262
100263 UA_LOG_INFO_SUBSCRIPTION(server->config.logging, sub, "Subscription deleted");
100264
100265 /* Detach from the session if necessary */
100266 if(sub->session)
100267 UA_Session_detachSubscription(server, session: sub->session, sub, true);
100268
100269 /* Remove from the server if not previously registered */
100270 if(sub->serverListEntry.le_prev) {
100271 LIST_REMOVE(sub, serverListEntry);
100272 UA_assert(server->subscriptionsSize > 0);
100273 server->subscriptionsSize--;
100274 server->serverDiagnosticsSummary.currentSubscriptionCount--;
100275 }
100276
100277 /* Delete monitored Items */
100278 UA_assert(server->monitoredItemsSize >= sub->monitoredItemsSize);
100279 UA_MonitoredItem *mon, *tmp_mon;
100280 LIST_FOREACH_SAFE(mon, &sub->monitoredItems, listEntry, tmp_mon) {
100281 UA_MonitoredItem_delete(server, mon);
100282 }
100283 UA_assert(sub->monitoredItemsSize == 0);
100284
100285 /* Delete Retransmission Queue */
100286 UA_NotificationMessageEntry *nme, *nme_tmp;
100287 TAILQ_FOREACH_SAFE(nme, &sub->retransmissionQueue, listEntry, nme_tmp) {
100288 TAILQ_REMOVE(&sub->retransmissionQueue, nme, listEntry);
100289 UA_NotificationMessage_clear(p: &nme->message);
100290 UA_free(ptr: nme);
100291 if(sub->session)
100292 --sub->session->totalRetransmissionQueueSize;
100293 --sub->retransmissionQueueSize;
100294 }
100295 UA_assert(sub->retransmissionQueueSize == 0);
100296
100297 /* Pointers to the subscription may still exist upwards in the call stack.
100298 * Add a delayed callback to remove the Subscription when the current jobs
100299 * have completed. */
100300 sub->delayedFreePointers.callback = delayedFreeSubscription;
100301 sub->delayedFreePointers.application = NULL;
100302 sub->delayedFreePointers.context = sub;
100303 el->addDelayedCallback(el, &sub->delayedFreePointers);
100304}
100305
100306void
100307Subscription_resetLifetime(UA_Subscription *sub) {
100308 sub->currentLifetimeCount = 0;
100309}
100310
100311UA_MonitoredItem *
100312UA_Subscription_getMonitoredItem(UA_Subscription *sub, UA_UInt32 monitoredItemId) {
100313 UA_MonitoredItem *mon;
100314 LIST_FOREACH(mon, &sub->monitoredItems, listEntry) {
100315 if(mon->monitoredItemId == monitoredItemId)
100316 break;
100317 }
100318 return mon;
100319}
100320
100321static void
100322removeOldestRetransmissionMessageFromSub(UA_Subscription *sub) {
100323 UA_NotificationMessageEntry *oldestEntry =
100324 TAILQ_LAST(&sub->retransmissionQueue, NotificationMessageQueue);
100325 TAILQ_REMOVE(&sub->retransmissionQueue, oldestEntry, listEntry);
100326 UA_NotificationMessage_clear(p: &oldestEntry->message);
100327 UA_free(ptr: oldestEntry);
100328 --sub->retransmissionQueueSize;
100329 if(sub->session)
100330 --sub->session->totalRetransmissionQueueSize;
100331
100332#ifdef UA_ENABLE_DIAGNOSTICS
100333 sub->discardedMessageCount++;
100334#endif
100335}
100336
100337static void
100338removeOldestRetransmissionMessageFromSession(UA_Session *session) {
100339 UA_NotificationMessageEntry *oldestEntry = NULL;
100340 UA_Subscription *oldestSub = NULL;
100341 UA_Subscription *sub;
100342 TAILQ_FOREACH(sub, &session->subscriptions, sessionListEntry) {
100343 UA_NotificationMessageEntry *first =
100344 TAILQ_LAST(&sub->retransmissionQueue, NotificationMessageQueue);
100345 if(!first)
100346 continue;
100347 if(!oldestEntry || oldestEntry->message.publishTime > first->message.publishTime) {
100348 oldestEntry = first;
100349 oldestSub = sub;
100350 }
100351 }
100352 UA_assert(oldestEntry);
100353 UA_assert(oldestSub);
100354
100355 removeOldestRetransmissionMessageFromSub(sub: oldestSub);
100356}
100357
100358static void
100359UA_Subscription_addRetransmissionMessage(UA_Server *server, UA_Subscription *sub,
100360 UA_NotificationMessageEntry *entry) {
100361 /* Release the oldest entry if there is not enough space */
100362 UA_Session *session = sub->session;
100363 if(sub->retransmissionQueueSize >= UA_MAX_RETRANSMISSIONQUEUESIZE) {
100364 UA_LOG_WARNING_SUBSCRIPTION(server->config.logging, sub,
100365 "Subscription retransmission queue overflow");
100366 removeOldestRetransmissionMessageFromSub(sub);
100367 } else if(session && server->config.maxRetransmissionQueueSize > 0 &&
100368 session->totalRetransmissionQueueSize >=
100369 server->config.maxRetransmissionQueueSize) {
100370 UA_LOG_WARNING_SUBSCRIPTION(server->config.logging, sub,
100371 "Session-wide retransmission queue overflow");
100372 removeOldestRetransmissionMessageFromSession(session: sub->session);
100373 }
100374
100375 /* Add entry */
100376 TAILQ_INSERT_TAIL(&sub->retransmissionQueue, entry, listEntry);
100377 ++sub->retransmissionQueueSize;
100378 if(session)
100379 ++session->totalRetransmissionQueueSize;
100380}
100381
100382UA_StatusCode
100383UA_Subscription_removeRetransmissionMessage(UA_Subscription *sub, UA_UInt32 sequenceNumber) {
100384 /* Find the retransmission message */
100385 UA_NotificationMessageEntry *entry;
100386 TAILQ_FOREACH(entry, &sub->retransmissionQueue, listEntry) {
100387 if(entry->message.sequenceNumber == sequenceNumber)
100388 break;
100389 }
100390 if(!entry)
100391 return UA_STATUSCODE_BADSEQUENCENUMBERUNKNOWN;
100392
100393 /* Remove the retransmission message */
100394 TAILQ_REMOVE(&sub->retransmissionQueue, entry, listEntry);
100395 --sub->retransmissionQueueSize;
100396 UA_NotificationMessage_clear(p: &entry->message);
100397 UA_free(ptr: entry);
100398
100399 if(sub->session)
100400 --sub->session->totalRetransmissionQueueSize;
100401
100402 return UA_STATUSCODE_GOOD;
100403}
100404
100405/* The output counters are only set when the preparation is successful */
100406static UA_StatusCode
100407prepareNotificationMessage(UA_Server *server, UA_Subscription *sub,
100408 UA_NotificationMessage *message,
100409 size_t maxNotifications) {
100410 UA_assert(maxNotifications > 0);
100411
100412 /* Allocate an ExtensionObject for Event- and DataChange-Notifications. Also
100413 * there can be StatusChange-Notifications. The standard says in Part 4,
100414 * 7.2.1:
100415 *
100416 * If a Subscription contains MonitoredItems for events and data, this array
100417 * should have not more than 2 elements. */
100418 message->notificationData = (UA_ExtensionObject*)
100419 UA_Array_new(size: 2, type: &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]);
100420 if(!message->notificationData)
100421 return UA_STATUSCODE_BADOUTOFMEMORY;
100422 message->notificationDataSize = 2;
100423
100424 /* Pre-allocate DataChangeNotifications */
100425 size_t notificationDataIdx = 0;
100426 size_t dcnPos = 0; /* How many DataChangeNotifications? */
100427 UA_DataChangeNotification *dcn = NULL;
100428 if(sub->dataChangeNotifications > 0) {
100429 dcn = UA_DataChangeNotification_new();
100430 if(!dcn) {
100431 UA_NotificationMessage_clear(p: message);
100432 return UA_STATUSCODE_BADOUTOFMEMORY;
100433 }
100434 UA_ExtensionObject_setValue(eo: message->notificationData, p: dcn,
100435 type: &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION]);
100436 size_t dcnSize = sub->dataChangeNotifications;
100437 if(dcnSize > maxNotifications)
100438 dcnSize = maxNotifications;
100439 dcn->monitoredItems = (UA_MonitoredItemNotification*)
100440 UA_Array_new(size: dcnSize, type: &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION]);
100441 if(!dcn->monitoredItems) {
100442 UA_NotificationMessage_clear(p: message);
100443 return UA_STATUSCODE_BADOUTOFMEMORY;
100444 }
100445 dcn->monitoredItemsSize = dcnSize;
100446 notificationDataIdx++;
100447 }
100448
100449#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
100450 size_t enlPos = 0; /* How many EventNotifications? */
100451 UA_EventNotificationList *enl = NULL;
100452 if(sub->eventNotifications > 0) {
100453 enl = UA_EventNotificationList_new();
100454 if(!enl) {
100455 UA_NotificationMessage_clear(p: message);
100456 return UA_STATUSCODE_BADOUTOFMEMORY;
100457 }
100458 UA_ExtensionObject_setValue(eo: &message->notificationData[notificationDataIdx],
100459 p: enl, type: &UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST]);
100460 size_t enlSize = sub->eventNotifications;
100461 if(enlSize > maxNotifications)
100462 enlSize = maxNotifications;
100463 enl->events = (UA_EventFieldList*)
100464 UA_Array_new(size: enlSize, type: &UA_TYPES[UA_TYPES_EVENTFIELDLIST]);
100465 if(!enl->events) {
100466 UA_NotificationMessage_clear(p: message);
100467 return UA_STATUSCODE_BADOUTOFMEMORY;
100468 }
100469 enl->eventsSize = enlSize;
100470 notificationDataIdx++;
100471 }
100472#endif
100473
100474 UA_assert(notificationDataIdx > 0);
100475 message->notificationDataSize = notificationDataIdx;
100476
100477 /* <-- The point of no return --> */
100478
100479 /* How many notifications were moved to the response overall? */
100480 size_t totalNotifications = 0;
100481 UA_Notification *notification, *notification_tmp;
100482 TAILQ_FOREACH_SAFE(notification, &sub->notificationQueue,
100483 globalEntry, notification_tmp) {
100484 if(totalNotifications >= maxNotifications)
100485 break;
100486
100487 /* Move the content to the response */
100488 switch(notification->mon->itemToMonitor.attributeId) {
100489#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
100490 case UA_ATTRIBUTEID_EVENTNOTIFIER:
100491 UA_assert(enl != NULL); /* Have at least one event notification */
100492 enl->events[enlPos] = notification->data.event;
100493 UA_EventFieldList_init(p: &notification->data.event);
100494 enlPos++;
100495 break;
100496#endif
100497 default:
100498 UA_assert(dcn != NULL); /* Have at least one change notification */
100499 dcn->monitoredItems[dcnPos] = notification->data.dataChange;
100500 UA_DataValue_init(p: &notification->data.dataChange.value);
100501 dcnPos++;
100502 break;
100503 }
100504
100505 /* If there are Notifications *before this one* in the MonitoredItem-
100506 * local queue, remove all of them. These are earlier Notifications that
100507 * are non-reporting. And we don't want them to show up after the
100508 * current Notification has been sent out. */
100509 UA_Notification *prev;
100510 while((prev = TAILQ_PREV(notification, NotificationQueue, localEntry))) {
100511 UA_Notification_delete(n: prev);
100512 }
100513
100514 /* Delete the notification, remove from the queues and decrease the counters */
100515 UA_Notification_delete(n: notification);
100516
100517 totalNotifications++;
100518 }
100519
100520 /* Set sizes */
100521 if(dcn) {
100522 dcn->monitoredItemsSize = dcnPos;
100523 if(dcnPos == 0) {
100524 UA_free(ptr: dcn->monitoredItems);
100525 dcn->monitoredItems = NULL;
100526 }
100527 }
100528
100529#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
100530 if(enl) {
100531 enl->eventsSize = enlPos;
100532 if(enlPos == 0) {
100533 UA_free(ptr: enl->events);
100534 enl->events = NULL;
100535 }
100536 }
100537#endif
100538
100539 return UA_STATUSCODE_GOOD;
100540}
100541
100542/* According to OPC Unified Architecture, Part 4 5.13.1.1 i) The value 0 is
100543 * never used for the sequence number */
100544static UA_UInt32
100545UA_Subscription_nextSequenceNumber(UA_UInt32 sequenceNumber) {
100546 UA_UInt32 nextSequenceNumber = sequenceNumber + 1;
100547 if(nextSequenceNumber == 0)
100548 nextSequenceNumber = 1;
100549 return nextSequenceNumber;
100550}
100551
100552static void
100553sendStatusChangeDelete(UA_Server *server, UA_Subscription *sub,
100554 UA_PublishResponseEntry *pre) {
100555 /* Cannot send out the StatusChange because no response is queued.
100556 * Delete the Subscription without sending the StatusChange, if the statusChange is Bad*/
100557 if(!pre) {
100558 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, sub,
100559 "Cannot send the StatusChange notification because no response is queued.");
100560 if(UA_StatusCode_isBad(code: sub->statusChange)) {
100561 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, sub, "Removing the subscription.");
100562 UA_Subscription_delete(server, sub);
100563 }
100564 return;
100565 }
100566
100567 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, sub,
100568 "Sending out a StatusChange "
100569 "notification and removing the subscription");
100570
100571 /* Populate the response */
100572 UA_PublishResponse *response = &pre->response;
100573
100574 UA_StatusChangeNotification scn;
100575 UA_StatusChangeNotification_init(p: &scn);
100576 scn.status = sub->statusChange;
100577
100578 UA_ExtensionObject notificationData;
100579 UA_ExtensionObject_setValue(eo: &notificationData, p: &scn,
100580 type: &UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION]);
100581
100582 response->notificationMessage.notificationData = &notificationData;
100583 response->notificationMessage.notificationDataSize = 1;
100584 response->subscriptionId = sub->subscriptionId;
100585 response->notificationMessage.publishTime = UA_DateTime_now();
100586 response->notificationMessage.sequenceNumber = sub->nextSequenceNumber;
100587
100588 /* Send the response */
100589 UA_assert(sub->session); /* Otherwise pre is NULL */
100590 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, sub,
100591 "Sending out a publish response");
100592 sendResponse(server, session: sub->session, channel: sub->session->header.channel, requestId: pre->requestId,
100593 response: (UA_Response *)response, responseType: &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]);
100594
100595 /* Clean up */
100596 response->notificationMessage.notificationData = NULL;
100597 response->notificationMessage.notificationDataSize = 0;
100598 UA_PublishResponse_clear(p: &pre->response);
100599 UA_free(ptr: pre);
100600
100601 /* Delete the subscription */
100602 UA_Subscription_delete(server, sub);
100603}
100604
100605static void
100606delayedPublishNotifications(UA_Server *server, UA_Subscription *sub) {
100607 lockServer(server);
100608 sub->delayedCallbackRegistered = false;
100609 UA_Subscription_publish(server, sub);
100610 unlockServer(server);
100611}
100612
100613/* Try to publish now. Enqueue a "next publish" as a delayed callback if not
100614 * done. */
100615void
100616UA_Subscription_publish(UA_Server *server, UA_Subscription *sub) {
100617 /* Get a response */
100618 UA_PublishResponseEntry *pre = NULL;
100619 if(sub->session) {
100620 UA_EventLoop *el = server->config.eventLoop;
100621 UA_DateTime nowMonotonic = el->dateTime_nowMonotonic(el);
100622 do {
100623 /* Dequeue the oldest response */
100624 pre = UA_Session_dequeuePublishReq(session: sub->session);
100625 if(!pre)
100626 break;
100627
100628 /* Check if the TimeoutHint is still valid. Otherwise return with a bad
100629 * statuscode and continue. */
100630 if(pre->maxTime < nowMonotonic) {
100631 UA_LOG_DEBUG_SESSION(server->config.logging, sub->session,
100632 "Publish request %u has timed out", pre->requestId);
100633 pre->response.responseHeader.serviceResult = UA_STATUSCODE_BADTIMEOUT;
100634 sendResponse(server, session: sub->session, channel: sub->session->header.channel,
100635 requestId: pre->requestId, response: (UA_Response *)&pre->response,
100636 responseType: &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]);
100637 UA_PublishResponse_clear(p: &pre->response);
100638 UA_free(ptr: pre);
100639 pre = NULL;
100640 }
100641 } while(!pre);
100642 }
100643
100644 /* Update the LifetimeCounter */
100645 if(pre) {
100646 Subscription_resetLifetime(sub);
100647 } else {
100648 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, sub,
100649 "The publish queue is empty");
100650 ++sub->currentLifetimeCount;
100651 if(sub->currentLifetimeCount > sub->lifeTimeCount) {
100652 UA_LOG_WARNING_SUBSCRIPTION(server->config.logging, sub,
100653 "End of subscription lifetime");
100654 /* Set the StatusChange to delete the subscription. */
100655 sub->statusChange = UA_STATUSCODE_BADTIMEOUT;
100656 }
100657 }
100658
100659 /* Send a StatusChange notification if possible and delete the
100660 * Subscription */
100661 if(sub->statusChange != UA_STATUSCODE_GOOD) {
100662 sendStatusChangeDelete(server, sub, pre);
100663 return;
100664 }
100665
100666 /* Dsiabled subscriptions do not send notifications */
100667 UA_UInt32 notifications = (sub->state == UA_SUBSCRIPTIONSTATE_ENABLED) ?
100668 sub->notificationQueueSize : 0;
100669
100670 /* Limit the number of notifications to the configured maximum */
100671 if(notifications > sub->notificationsPerPublish)
100672 notifications = sub->notificationsPerPublish;
100673
100674 /* Return if no notifications and no keepalive */
100675 if(notifications == 0) {
100676 ++sub->currentKeepAliveCount;
100677 if(sub->currentKeepAliveCount < sub->maxKeepAliveCount) {
100678 if(pre)
100679 UA_Session_queuePublishReq(session: sub->session, entry: pre, true); /* Re-enqueue */
100680 return;
100681 }
100682 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, sub, "Sending a KeepAlive");
100683 }
100684
100685 /* We want to send a response, but cannot. Either because there is no queued
100686 * response or because the Subscription is detached from a Session or because
100687 * the SecureChannel for the Session is closed. */
100688 if(!pre || !sub->session || !sub->session->header.channel) {
100689 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, sub,
100690 "Want to send a publish response but cannot. "
100691 "The subscription is late.");
100692 sub->late = true;
100693 if(pre)
100694 UA_Session_queuePublishReq(session: sub->session, entry: pre, true); /* Re-enqueue */
100695 return;
100696 }
100697
100698 UA_assert(pre);
100699 UA_assert(sub->session); /* Otherwise pre is NULL */
100700
100701 /* Prepare the response */
100702 UA_PublishResponse *response = &pre->response;
100703 UA_NotificationMessage *message = &response->notificationMessage;
100704 UA_NotificationMessageEntry *retransmission = NULL;
100705#ifdef UA_ENABLE_DIAGNOSTICS
100706 size_t priorDataChangeNotifications = sub->dataChangeNotifications;
100707 size_t priorEventNotifications = sub->eventNotifications;
100708#endif
100709 if(notifications > 0) {
100710 if(server->config.enableRetransmissionQueue) {
100711 /* Allocate the retransmission entry */
100712 retransmission = (UA_NotificationMessageEntry*)
100713 UA_malloc(size: sizeof(UA_NotificationMessageEntry));
100714 if(!retransmission) {
100715 UA_LOG_WARNING_SUBSCRIPTION(server->config.logging, sub,
100716 "Could not allocate memory for retransmission. "
100717 "The subscription is late.");
100718 sub->late = true;
100719 UA_Session_queuePublishReq(session: sub->session, entry: pre, true); /* Re-enqueue */
100720 return;
100721 }
100722 }
100723
100724 /* Prepare the response */
100725 UA_StatusCode retval =
100726 prepareNotificationMessage(server, sub, message, maxNotifications: notifications);
100727 if(retval != UA_STATUSCODE_GOOD) {
100728 UA_LOG_WARNING_SUBSCRIPTION(server->config.logging, sub,
100729 "Could not prepare the notification message. "
100730 "The subscription is late.");
100731 /* If the retransmission queue is enabled a retransmission message is allocated */
100732 if(retransmission)
100733 UA_free(ptr: retransmission);
100734 sub->late = true;
100735 UA_Session_queuePublishReq(session: sub->session, entry: pre, true); /* Re-enqueue */
100736 return;
100737 }
100738 }
100739
100740 /* <-- The point of no return --> */
100741
100742 /* Set up the response */
100743 response->subscriptionId = sub->subscriptionId;
100744 response->moreNotifications = (sub->notificationQueueSize > 0);
100745 message->publishTime = UA_DateTime_now();
100746
100747 /* Set sequence number to message. Started at 1 which is given during
100748 * creating a new subscription. The 1 is required for initial publish
100749 * response with or without an monitored item. */
100750 message->sequenceNumber = sub->nextSequenceNumber;
100751
100752 if(notifications > 0) {
100753 /* If the retransmission queue is enabled a retransmission message is
100754 * allocated */
100755 if(retransmission) {
100756 /* Put the notification message into the retransmission queue. This
100757 * needs to be done here, so that the message itself is included in
100758 * the available sequence numbers for acknowledgement. */
100759 retransmission->message = response->notificationMessage;
100760 UA_Subscription_addRetransmissionMessage(server, sub, entry: retransmission);
100761 }
100762 /* Only if a notification was created, the sequence number must be
100763 * increased. For a keepalive the sequence number can be reused. */
100764 sub->nextSequenceNumber =
100765 UA_Subscription_nextSequenceNumber(sequenceNumber: sub->nextSequenceNumber);
100766 }
100767
100768 /* Get the available sequence numbers from the retransmission queue */
100769 UA_assert(sub->retransmissionQueueSize <= UA_MAX_RETRANSMISSIONQUEUESIZE);
100770 UA_UInt32 seqNumbers[UA_MAX_RETRANSMISSIONQUEUESIZE];
100771 response->availableSequenceNumbers = seqNumbers;
100772 response->availableSequenceNumbersSize = sub->retransmissionQueueSize;
100773 size_t i = 0;
100774 UA_NotificationMessageEntry *nme;
100775 TAILQ_FOREACH(nme, &sub->retransmissionQueue, listEntry) {
100776 response->availableSequenceNumbers[i] = nme->message.sequenceNumber;
100777 ++i;
100778 }
100779 UA_assert(i == sub->retransmissionQueueSize);
100780
100781 /* Send the response */
100782 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, sub,
100783 "Sending out a publish response with %" PRIu32
100784 " notifications", notifications);
100785 sendResponse(server, session: sub->session, channel: sub->session->header.channel, requestId: pre->requestId,
100786 response: (UA_Response*)response, responseType: &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]);
100787
100788 /* Reset the Subscription state to NORMAL. But only if all notifications
100789 * have been sent out. Otherwise keep the Subscription in the LATE state. So
100790 * we immediately answer incoming Publish requests.
100791 *
100792 * (We also check that session->responseQueueSize > 0 in Service_Publish. To
100793 * avoid answering Publish requests out of order. As we additionally may have
100794 * scheduled a publish callback as a delayed callback. */
100795 if(sub->notificationQueueSize == 0)
100796 sub->late = false;
100797
100798 /* Reset the KeepAlive after publishing */
100799 sub->currentKeepAliveCount = 0;
100800
100801 /* Free the response */
100802 if(retransmission) {
100803 /* NotificationMessage was moved into retransmission queue */
100804 UA_NotificationMessage_init(p: &response->notificationMessage);
100805 }
100806 response->availableSequenceNumbers = NULL;
100807 response->availableSequenceNumbersSize = 0;
100808 UA_PublishResponse_clear(p: &pre->response);
100809 UA_free(ptr: pre);
100810
100811 /* Update the diagnostics statistics */
100812#ifdef UA_ENABLE_DIAGNOSTICS
100813 sub->publishRequestCount++;
100814
100815 UA_UInt32 sentDCN = (UA_UInt32)
100816 (priorDataChangeNotifications - sub->dataChangeNotifications);
100817 UA_UInt32 sentEN = (UA_UInt32)(priorEventNotifications - sub->eventNotifications);
100818 sub->dataChangeNotificationsCount += sentDCN;
100819 sub->eventNotificationsCount += sentEN;
100820 sub->notificationsCount += (sentDCN + sentEN);
100821#endif
100822
100823 /* Repeat sending notifications if there are more notifications to send. But
100824 * only call monitoredItem_sampleCallback in the regular publish
100825 * callback. */
100826 UA_Boolean done = (sub->notificationQueueSize == 0);
100827 if(!done && !sub->delayedCallbackRegistered) {
100828 sub->delayedCallbackRegistered = true;
100829
100830 sub->delayedMoreNotifications.callback = (UA_Callback)delayedPublishNotifications;
100831 sub->delayedMoreNotifications.application = server;
100832 sub->delayedMoreNotifications.context = sub;
100833
100834 UA_EventLoop *el = server->config.eventLoop;
100835 el->addDelayedCallback(el, &sub->delayedMoreNotifications);
100836 }
100837}
100838
100839void
100840UA_Subscription_resendData(UA_Server *server, UA_Subscription *sub) {
100841 UA_LOCK_ASSERT(&server->serviceMutex, 1);
100842 UA_assert(server);
100843 UA_assert(sub);
100844
100845 /* Part 4, §6.7: If this Method is called, subsequent Publish responses
100846 * shall contain the current values of all data MonitoredItems in the
100847 * Subscription where the MonitoringMode is set to Reporting. If a value is
100848 * queued for a data MonitoredItem, the next value in the queue is sent in
100849 * the Publish response. If no value is queued for a data MonitoredItem, the
100850 * last value sent is repeated in the Publish response. */
100851 UA_MonitoredItem *mon;
100852 LIST_FOREACH(mon, &sub->monitoredItems, listEntry) {
100853 /* Create only DataChange notifications */
100854 if(mon->itemToMonitor.attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER)
100855 continue;
100856
100857 /* Only if the mode is monitoring */
100858 if(mon->monitoringMode != UA_MONITORINGMODE_REPORTING)
100859 continue;
100860
100861 /* If a value is queued for a data MonitoredItem, the next value in
100862 * the queue is sent in the Publish response. */
100863 if(mon->queueSize > 0)
100864 continue;
100865
100866 /* Create a notification with the last sampled value */
100867 UA_MonitoredItem_createDataChangeNotification(server, mon, value: &mon->lastValue);
100868 }
100869}
100870
100871void
100872UA_Session_ensurePublishQueueSpace(UA_Server* server, UA_Session* session) {
100873 if(server->config.maxPublishReqPerSession == 0)
100874 return;
100875
100876 while(session->responseQueueSize >= server->config.maxPublishReqPerSession) {
100877 /* Dequeue a response */
100878 UA_PublishResponseEntry *pre = UA_Session_dequeuePublishReq(session);
100879 UA_assert(pre != NULL); /* There must be a pre as session->responseQueueSize > 0 */
100880
100881 UA_LOG_DEBUG_SESSION(server->config.logging, session,
100882 "Sending out a publish response triggered by too many publish requests");
100883
100884 /* Send the response. This response has no related subscription id */
100885 UA_PublishResponse *response = &pre->response;
100886 response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYPUBLISHREQUESTS;
100887 sendResponse(server, session, channel: session->header.channel, requestId: pre->requestId,
100888 response: (UA_Response *)response, responseType: &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]);
100889
100890 /* Free the response */
100891 UA_PublishResponse_clear(p: response);
100892 UA_free(ptr: pre);
100893 }
100894}
100895
100896static void
100897sampleAndPublishCallback(UA_Server *server, UA_Subscription *sub) {
100898 UA_assert(sub);
100899
100900 lockServer(server);
100901
100902 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, sub,
100903 "Sample and Publish Callback");
100904
100905 /* Sample the MonitoredItems with sampling interval <0 (which implies
100906 * sampling in the same interval as the subscription) */
100907 UA_MonitoredItem *mon;
100908 LIST_FOREACH(mon, &sub->samplingMonitoredItems, sampling.subscriptionSampling) {
100909 monitoredItem_sampleCallback(server, mon);
100910 }
100911
100912 /* Publish the queued notifications */
100913 UA_Subscription_publish(server, sub);
100914
100915 unlockServer(server);
100916}
100917
100918UA_StatusCode
100919Subscription_setState(UA_Server *server, UA_Subscription *sub,
100920 UA_SubscriptionState state) {
100921 if(state <= UA_SUBSCRIPTIONSTATE_REMOVING) {
100922 if(sub->publishCallbackId != 0) {
100923 removeCallback(server, callbackId: sub->publishCallbackId);
100924 sub->publishCallbackId = 0;
100925#ifdef UA_ENABLE_DIAGNOSTICS
100926 sub->disableCount++;
100927#endif
100928 }
100929 } else if(sub->publishCallbackId == 0) {
100930 UA_StatusCode res =
100931 addRepeatedCallback(server, callback: (UA_ServerCallback)sampleAndPublishCallback,
100932 data: sub, interval_ms: sub->publishingInterval, callbackId: &sub->publishCallbackId);
100933 if(res != UA_STATUSCODE_GOOD) {
100934 sub->state = UA_SUBSCRIPTIONSTATE_STOPPED;
100935 return res;
100936 }
100937
100938 /* Send (at least a) keepalive after the next publish interval */
100939 sub->currentKeepAliveCount = sub->maxKeepAliveCount;
100940
100941#ifdef UA_ENABLE_DIAGNOSTICS
100942 sub->enableCount++;
100943#endif
100944 }
100945
100946 sub->state = state;
100947 return UA_STATUSCODE_GOOD;
100948}
100949
100950#endif /* UA_ENABLE_SUBSCRIPTIONS */
100951
100952/**** amalgamated original file "/src/server/ua_subscription_monitoreditem.c" ****/
100953
100954/* This Source Code Form is subject to the terms of the Mozilla Public
100955 * License, v. 2.0. If a copy of the MPL was not distributed with this
100956 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
100957 *
100958 * Copyright 2017-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
100959 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
100960 * Copyright 2018 (c) Ari Breitkreuz, fortiss GmbH
100961 * Copyright 2018 (c) Thomas Stalder, Blue Time Concept SA
100962 * Copyright 2018 (c) Fabian Arndt, Root-Core
100963 * Copyright 2020-2021 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati)
100964 */
100965
100966
100967#ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */
100968
100969/****************/
100970/* Notification */
100971/****************/
100972
100973#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
100974
100975static const UA_NodeId eventQueueOverflowEventType =
100976 {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE}};
100977
100978/* The specification states in Part 4 5.12.1.5 that an EventQueueOverflowEvent
100979 * "is generated when the first Event has to be discarded [...] without
100980 * discarding any other event". So only generate one for all deleted events. */
100981static UA_StatusCode
100982createEventOverflowNotification(UA_Server *server, UA_Subscription *sub,
100983 UA_MonitoredItem *mon) {
100984 /* Avoid creating two adjacent overflow events */
100985 UA_Notification *indicator = NULL;
100986 if(mon->parameters.discardOldest) {
100987 indicator = TAILQ_FIRST(&mon->queue);
100988 UA_assert(indicator); /* must exist */
100989 if(indicator->isOverflowEvent)
100990 return UA_STATUSCODE_GOOD;
100991 } else {
100992 indicator = TAILQ_LAST(&mon->queue, NotificationQueue);
100993 UA_assert(indicator); /* must exist */
100994 /* Skip the last element. It is the recently added notification that
100995 * shall be kept. We know it is not an OverflowEvent. */
100996 UA_Notification *before = TAILQ_PREV(indicator, NotificationQueue, localEntry);
100997 if(before && before->isOverflowEvent)
100998 return UA_STATUSCODE_GOOD;
100999 }
101000
101001 /* A Notification is inserted into the queue which includes only the
101002 * NodeId of the OverflowEventType. */
101003
101004 /* Allocate the notification */
101005 UA_Notification *overflowNotification = UA_Notification_new();
101006 if(!overflowNotification)
101007 return UA_STATUSCODE_BADOUTOFMEMORY;
101008
101009 /* Set the notification fields */
101010 overflowNotification->isOverflowEvent = true;
101011 overflowNotification->mon = mon;
101012 overflowNotification->data.event.clientHandle = mon->parameters.clientHandle;
101013 overflowNotification->data.event.eventFields = UA_Variant_new();
101014 if(!overflowNotification->data.event.eventFields) {
101015 UA_free(ptr: overflowNotification);
101016 return UA_STATUSCODE_BADOUTOFMEMORY;
101017 }
101018 overflowNotification->data.event.eventFieldsSize = 1;
101019 UA_StatusCode retval =
101020 UA_Variant_setScalarCopy(v: overflowNotification->data.event.eventFields,
101021 p: &eventQueueOverflowEventType, type: &UA_TYPES[UA_TYPES_NODEID]);
101022 if(retval != UA_STATUSCODE_GOOD) {
101023 UA_Notification_delete(n: overflowNotification);
101024 return retval;
101025 }
101026
101027 /* Insert before the removed notification. This is either first in the
101028 * queue (if the oldest notification was removed) or before the new event
101029 * that remains the last element of the queue.
101030 *
101031 * Ensure that the following is consistent with UA_Notification_enqueueMon
101032 * and UA_Notification_enqueueSub! */
101033 TAILQ_INSERT_BEFORE(indicator, overflowNotification, localEntry);
101034 ++mon->eventOverflows;
101035 ++mon->queueSize;
101036
101037 /* Test for consistency */
101038 UA_assert(mon->queueSize >= mon->eventOverflows);
101039 UA_assert(mon->eventOverflows <= mon->queueSize - mon->eventOverflows + 1);
101040
101041 if(TAILQ_NEXT(indicator, globalEntry) != UA_SUBSCRIPTION_QUEUE_SENTINEL) {
101042 /* Insert just before the indicator */
101043 TAILQ_INSERT_BEFORE(indicator, overflowNotification, globalEntry);
101044 } else {
101045 /* The indicator was not reporting or not added yet. */
101046 if(!mon->parameters.discardOldest) {
101047 /* Add last to the per-Subscription queue */
101048 TAILQ_INSERT_TAIL(&mon->subscription->notificationQueue,
101049 overflowNotification, globalEntry);
101050 } else {
101051 /* Find the oldest reported element. Add before that. */
101052 while(indicator) {
101053 indicator = TAILQ_PREV(indicator, NotificationQueue, localEntry);
101054 if(!indicator) {
101055 TAILQ_INSERT_TAIL(&mon->subscription->notificationQueue,
101056 overflowNotification, globalEntry);
101057 break;
101058 }
101059 if(TAILQ_NEXT(indicator, globalEntry) != UA_SUBSCRIPTION_QUEUE_SENTINEL) {
101060 TAILQ_INSERT_BEFORE(indicator, overflowNotification, globalEntry);
101061 break;
101062 }
101063 }
101064 }
101065 }
101066
101067 ++sub->notificationQueueSize;
101068 ++sub->eventNotifications;
101069
101070 /* Update the diagnostics statistics */
101071#ifdef UA_ENABLE_DIAGNOSTICS
101072 sub->eventQueueOverFlowCount++;
101073#endif
101074
101075 return UA_STATUSCODE_GOOD;
101076}
101077
101078#endif
101079
101080/* Set the InfoBits that a datachange notification was removed */
101081static void
101082setOverflowInfoBits(UA_MonitoredItem *mon) {
101083 /* Only for queues with more than one element */
101084 if(mon->parameters.queueSize == 1)
101085 return;
101086
101087 UA_Notification *indicator = NULL;
101088 if(mon->parameters.discardOldest) {
101089 indicator = TAILQ_FIRST(&mon->queue);
101090 } else {
101091 indicator = TAILQ_LAST(&mon->queue, NotificationQueue);
101092 }
101093 UA_assert(indicator); /* must exist */
101094
101095 indicator->data.dataChange.value.hasStatus = true;
101096 indicator->data.dataChange.value.status |=
101097 (UA_STATUSCODE_INFOTYPE_DATAVALUE | UA_STATUSCODE_INFOBITS_OVERFLOW);
101098}
101099
101100/* Remove the InfoBits when the queueSize was reduced to 1 */
101101void
101102UA_MonitoredItem_removeOverflowInfoBits(UA_MonitoredItem *mon) {
101103 /* Don't consider queue size > 1 and Event MonitoredItems */
101104 if(mon->parameters.queueSize > 1 ||
101105 mon->itemToMonitor.attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER)
101106 return;
101107
101108 /* Get the first notification */
101109 UA_Notification *n = TAILQ_FIRST(&mon->queue);
101110 if(!n)
101111 return;
101112
101113 /* Assertion that at most one notification is in the queue */
101114 UA_assert(n == TAILQ_LAST(&mon->queue, NotificationQueue));
101115
101116 /* Remve the Infobits */
101117 n->data.dataChange.value.status &= ~(UA_StatusCode)
101118 (UA_STATUSCODE_INFOTYPE_DATAVALUE | UA_STATUSCODE_INFOBITS_OVERFLOW);
101119}
101120
101121UA_Notification *
101122UA_Notification_new(void) {
101123 UA_Notification *n = (UA_Notification*)UA_calloc(nmemb: 1, size: sizeof(UA_Notification));
101124 if(n) {
101125 /* Set the sentinel for a notification that is not enqueued */
101126 TAILQ_NEXT(n, globalEntry) = UA_SUBSCRIPTION_QUEUE_SENTINEL;
101127 TAILQ_NEXT(n, localEntry) = UA_SUBSCRIPTION_QUEUE_SENTINEL;
101128 }
101129 return n;
101130}
101131
101132static void UA_Notification_dequeueMon(UA_Notification *n);
101133static void UA_Notification_enqueueSub(UA_Notification *n);
101134static void UA_Notification_dequeueSub(UA_Notification *n);
101135
101136void
101137UA_Notification_delete(UA_Notification *n) {
101138 UA_assert(n != UA_SUBSCRIPTION_QUEUE_SENTINEL);
101139 if(n->mon) {
101140 UA_Notification_dequeueMon(n);
101141 UA_Notification_dequeueSub(n);
101142 switch(n->mon->itemToMonitor.attributeId) {
101143#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
101144 case UA_ATTRIBUTEID_EVENTNOTIFIER:
101145 UA_EventFieldList_clear(p: &n->data.event);
101146 break;
101147#endif
101148 default:
101149 UA_MonitoredItemNotification_clear(p: &n->data.dataChange);
101150 break;
101151 }
101152 }
101153 UA_free(ptr: n);
101154}
101155
101156/* Add to the MonitoredItem queue, update all counters and then handle overflow */
101157static void
101158UA_Notification_enqueueMon(UA_Server *server, UA_Notification *n) {
101159 UA_MonitoredItem *mon = n->mon;
101160 UA_assert(mon);
101161 UA_assert(TAILQ_NEXT(n, localEntry) == UA_SUBSCRIPTION_QUEUE_SENTINEL);
101162
101163 /* Add to the MonitoredItem */
101164 TAILQ_INSERT_TAIL(&mon->queue, n, localEntry);
101165 ++mon->queueSize;
101166
101167#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
101168 if(n->isOverflowEvent)
101169 ++mon->eventOverflows;
101170#endif
101171
101172 /* Test for consistency */
101173 UA_assert(mon->queueSize >= mon->eventOverflows);
101174 UA_assert(mon->eventOverflows <= mon->queueSize - mon->eventOverflows + 1);
101175
101176 /* Ensure enough space is available in the MonitoredItem. Do this only after
101177 * adding the new Notification. */
101178 UA_MonitoredItem_ensureQueueSpace(server, mon);
101179
101180 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, mon->subscription,
101181 "MonitoredItem %" PRIi32 " | "
101182 "Notification enqueued (Queue size %lu / %lu)",
101183 mon->monitoredItemId,
101184 (long unsigned)mon->queueSize,
101185 (long unsigned)mon->parameters.queueSize);
101186}
101187
101188static void
101189UA_Notification_enqueueSub(UA_Notification *n) {
101190 UA_MonitoredItem *mon = n->mon;
101191 UA_assert(mon);
101192
101193 UA_Subscription *sub = mon->subscription;
101194 UA_assert(sub);
101195
101196 if(TAILQ_NEXT(n, globalEntry) != UA_SUBSCRIPTION_QUEUE_SENTINEL)
101197 return;
101198
101199 /* Add to the subscription if reporting is enabled */
101200 TAILQ_INSERT_TAIL(&sub->notificationQueue, n, globalEntry);
101201 ++sub->notificationQueueSize;
101202
101203 switch(mon->itemToMonitor.attributeId) {
101204#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
101205 case UA_ATTRIBUTEID_EVENTNOTIFIER:
101206 ++sub->eventNotifications;
101207 break;
101208#endif
101209 default:
101210 ++sub->dataChangeNotifications;
101211 break;
101212 }
101213}
101214
101215void
101216UA_Notification_enqueueAndTrigger(UA_Server *server, UA_Notification *n) {
101217 UA_MonitoredItem *mon = n->mon;
101218 UA_Subscription *sub = mon->subscription;
101219 UA_assert(sub); /* This function is never called for local MonitoredItems */
101220
101221 /* If reporting or (sampled+triggered), enqueue into the Subscription first
101222 * and then into the MonitoredItem. UA_MonitoredItem_ensureQueueSpace
101223 * (called within UA_Notification_enqueueMon) assumes the notification is
101224 * already in the Subscription's publishing queue. */
101225 if(mon->monitoringMode == UA_MONITORINGMODE_REPORTING ||
101226 (mon->monitoringMode == UA_MONITORINGMODE_SAMPLING &&
101227 mon->triggeredUntil > UA_DateTime_nowMonotonic())) {
101228 UA_Notification_enqueueSub(n);
101229 mon->triggeredUntil = UA_INT64_MIN;
101230 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, sub,
101231 "Notification enqueued (Queue size %lu)",
101232 (long unsigned)sub->notificationQueueSize);
101233 }
101234
101235 /* Insert into the MonitoredItem. This checks the queue size and
101236 * handles overflow. */
101237 UA_Notification_enqueueMon(server, n);
101238
101239 for(size_t i = mon->triggeringLinksSize - 1; i < mon->triggeringLinksSize; i--) {
101240 /* Get the triggered MonitoredItem. Remove the link if the MI doesn't exist. */
101241 UA_MonitoredItem *triggeredMon =
101242 UA_Subscription_getMonitoredItem(sub, monitoredItemId: mon->triggeringLinks[i]);
101243 if(!triggeredMon) {
101244 UA_MonitoredItem_removeLink(sub, mon, linkId: mon->triggeringLinks[i]);
101245 continue;
101246 }
101247
101248 /* Only sampling MonitoredItems receive a trigger. Reporting
101249 * MonitoredItems send out Notifications anyway and disabled
101250 * MonitoredItems don't create samples to send. */
101251 if(triggeredMon->monitoringMode != UA_MONITORINGMODE_SAMPLING)
101252 continue;
101253
101254 /* Get the latest sampled Notification from the triggered MonitoredItem.
101255 * Enqueue for publication. */
101256 UA_Notification *n2 = TAILQ_LAST(&triggeredMon->queue, NotificationQueue);
101257 if(n2)
101258 UA_Notification_enqueueSub(n: n2);
101259
101260 /* The next Notification within the publishing interval is going to be
101261 * published as well. (Falsely) assume that the publishing cycle has
101262 * started right now, so that we don't have to loop over MonitoredItems
101263 * to deactivate the triggering after the publishing cycle. */
101264 triggeredMon->triggeredUntil = UA_DateTime_nowMonotonic() +
101265 (UA_DateTime)(sub->publishingInterval * (UA_Double)UA_DATETIME_MSEC);
101266
101267 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, sub,
101268 "MonitoredItem %u triggers MonitoredItem %u",
101269 mon->monitoredItemId, triggeredMon->monitoredItemId);
101270 }
101271}
101272
101273/* Remove from the MonitoredItem queue and adjust all counters */
101274static void
101275UA_Notification_dequeueMon(UA_Notification *n) {
101276 UA_MonitoredItem *mon = n->mon;
101277 UA_assert(mon);
101278
101279 if(TAILQ_NEXT(n, localEntry) == UA_SUBSCRIPTION_QUEUE_SENTINEL)
101280 return;
101281
101282 /* Remove from the MonitoredItem queue */
101283#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
101284 if(n->isOverflowEvent)
101285 --mon->eventOverflows;
101286#endif
101287
101288 TAILQ_REMOVE(&mon->queue, n, localEntry);
101289 --mon->queueSize;
101290
101291 /* Test for consistency */
101292 UA_assert(mon->queueSize >= mon->eventOverflows);
101293 UA_assert(mon->eventOverflows <= mon->queueSize - mon->eventOverflows + 1);
101294
101295 /* Reset the sentintel */
101296 TAILQ_NEXT(n, localEntry) = UA_SUBSCRIPTION_QUEUE_SENTINEL;
101297}
101298
101299void
101300UA_Notification_dequeueSub(UA_Notification *n) {
101301 if(TAILQ_NEXT(n, globalEntry) == UA_SUBSCRIPTION_QUEUE_SENTINEL)
101302 return;
101303
101304 UA_MonitoredItem *mon = n->mon;
101305 UA_assert(mon);
101306 UA_Subscription *sub = mon->subscription;
101307 UA_assert(sub);
101308
101309 switch(mon->itemToMonitor.attributeId) {
101310#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
101311 case UA_ATTRIBUTEID_EVENTNOTIFIER:
101312 --sub->eventNotifications;
101313 break;
101314#endif
101315 default:
101316 --sub->dataChangeNotifications;
101317 break;
101318 }
101319
101320 TAILQ_REMOVE(&sub->notificationQueue, n, globalEntry);
101321 --sub->notificationQueueSize;
101322
101323 /* Reset the sentinel */
101324 TAILQ_NEXT(n, globalEntry) = UA_SUBSCRIPTION_QUEUE_SENTINEL;
101325}
101326
101327/*****************/
101328/* MonitoredItem */
101329/*****************/
101330
101331void
101332UA_MonitoredItem_init(UA_MonitoredItem *mon) {
101333 memset(s: mon, c: 0, n: sizeof(UA_MonitoredItem));
101334 TAILQ_INIT(&mon->queue);
101335 mon->triggeredUntil = UA_INT64_MIN;
101336}
101337
101338static UA_StatusCode
101339addMonitoredItemBackpointer(UA_Server *server, UA_Session *session,
101340 UA_Node *node, void *data) {
101341 UA_MonitoredItem *mon = (UA_MonitoredItem*)data;
101342 UA_assert(mon != (UA_MonitoredItem*)~0);
101343 mon->sampling.nodeListNext = node->head.monitoredItems;
101344 node->head.monitoredItems = mon;
101345 return UA_STATUSCODE_GOOD;
101346}
101347
101348static UA_StatusCode
101349removeMonitoredItemBackPointer(UA_Server *server, UA_Session *session,
101350 UA_Node *node, void *data) {
101351 if(!node->head.monitoredItems)
101352 return UA_STATUSCODE_GOOD;
101353
101354 /* Edge case that it's the first element */
101355 UA_MonitoredItem *remove = (UA_MonitoredItem*)data;
101356 if(node->head.monitoredItems == remove) {
101357 node->head.monitoredItems = remove->sampling.nodeListNext;
101358 return UA_STATUSCODE_GOOD;
101359 }
101360
101361 UA_MonitoredItem *prev = node->head.monitoredItems;
101362 UA_MonitoredItem *entry = prev->sampling.nodeListNext;
101363 for(; entry != NULL; prev = entry, entry = entry->sampling.nodeListNext) {
101364 if(entry == remove) {
101365 prev->sampling.nodeListNext = entry->sampling.nodeListNext;
101366 break;
101367 }
101368 }
101369
101370 return UA_STATUSCODE_GOOD;
101371}
101372
101373void
101374UA_Server_registerMonitoredItem(UA_Server *server, UA_MonitoredItem *mon) {
101375 UA_LOCK_ASSERT(&server->serviceMutex, 1);
101376
101377 if(mon->registered)
101378 return;
101379
101380 /* Register in Subscription and Server */
101381 UA_Subscription *sub = mon->subscription;
101382 if(sub) {
101383 mon->monitoredItemId = ++sub->lastMonitoredItemId;
101384 sub->monitoredItemsSize++;
101385 LIST_INSERT_HEAD(&sub->monitoredItems, mon, listEntry);
101386 } else {
101387 mon->monitoredItemId = ++server->lastLocalMonitoredItemId;
101388 LIST_INSERT_HEAD(&server->localMonitoredItems, mon, listEntry);
101389 }
101390 server->monitoredItemsSize++;
101391
101392 /* Register the MonitoredItem in userland */
101393 if(server->config.monitoredItemRegisterCallback) {
101394 UA_Session *session = &server->adminSession;
101395 if(sub)
101396 session = sub->session;
101397
101398 void *targetContext = NULL;
101399 getNodeContext(server, nodeId: mon->itemToMonitor.nodeId, nodeContext: &targetContext);
101400 server->config.monitoredItemRegisterCallback(server,
101401 session ? &session->sessionId : NULL,
101402 session ? session->sessionHandle : NULL,
101403 &mon->itemToMonitor.nodeId,
101404 targetContext,
101405 mon->itemToMonitor.attributeId, false);
101406 }
101407
101408 mon->registered = true;
101409}
101410
101411static void
101412UA_Server_unregisterMonitoredItem(UA_Server *server, UA_MonitoredItem *mon) {
101413 UA_LOCK_ASSERT(&server->serviceMutex, 1);
101414
101415 if(!mon->registered)
101416 return;
101417
101418 UA_Subscription *sub = mon->subscription;
101419 UA_LOG_INFO_SUBSCRIPTION(server->config.logging, sub,
101420 "MonitoredItem %" PRIi32 " | Deleting the MonitoredItem",
101421 mon->monitoredItemId);
101422
101423 /* Deregister MonitoredItem in userland */
101424 if(server->config.monitoredItemRegisterCallback) {
101425 UA_Session *session = &server->adminSession;
101426 if(sub)
101427 session = sub->session;
101428
101429 void *targetContext = NULL;
101430 getNodeContext(server, nodeId: mon->itemToMonitor.nodeId, nodeContext: &targetContext);
101431 server->config.monitoredItemRegisterCallback(server,
101432 session ? &session->sessionId : NULL,
101433 session ? session->sessionHandle : NULL,
101434 &mon->itemToMonitor.nodeId,
101435 targetContext,
101436 mon->itemToMonitor.attributeId, true);
101437 }
101438
101439 /* Deregister in Subscription and server */
101440 if(sub)
101441 sub->monitoredItemsSize--;
101442 LIST_REMOVE(mon, listEntry); /* Also for LocalMonitoredItems */
101443 server->monitoredItemsSize--;
101444
101445 mon->registered = false;
101446}
101447
101448UA_StatusCode
101449UA_MonitoredItem_setMonitoringMode(UA_Server *server, UA_MonitoredItem *mon,
101450 UA_MonitoringMode monitoringMode) {
101451 /* Check if the MonitoringMode is valid or not */
101452 if(monitoringMode > UA_MONITORINGMODE_REPORTING)
101453 return UA_STATUSCODE_BADMONITORINGMODEINVALID;
101454
101455 /* Set the MonitoringMode, store the old mode */
101456 UA_MonitoringMode oldMode = mon->monitoringMode;
101457 mon->monitoringMode = monitoringMode;
101458
101459 UA_Notification *notification;
101460 /* Reporting is disabled. This causes all Notifications to be dequeued and
101461 * deleted. Also remove the last samples so that we immediately generate a
101462 * Notification when re-activated. */
101463 if(mon->monitoringMode == UA_MONITORINGMODE_DISABLED) {
101464 UA_Notification *notification_tmp;
101465 UA_MonitoredItem_unregisterSampling(server, mon);
101466 TAILQ_FOREACH_SAFE(notification, &mon->queue, localEntry, notification_tmp) {
101467 UA_Notification_delete(n: notification);
101468 }
101469 UA_DataValue_clear(p: &mon->lastValue);
101470 return UA_STATUSCODE_GOOD;
101471 }
101472
101473 /* When reporting is enabled, put all notifications that were already
101474 * sampled into the global queue of the subscription. When sampling is
101475 * enabled, remove all notifications from the global queue. !!! This needs
101476 * to be the same operation as in UA_Notification_enqueue !!! */
101477 if(mon->monitoringMode == UA_MONITORINGMODE_REPORTING) {
101478 /* Make all notifications reporting. Re-enqueue to ensure they have the
101479 * right order if some notifications are already reported by a trigger
101480 * link. */
101481 TAILQ_FOREACH(notification, &mon->queue, localEntry) {
101482 UA_Notification_dequeueSub(n: notification);
101483 UA_Notification_enqueueSub(n: notification);
101484 }
101485 } else /* mon->monitoringMode == UA_MONITORINGMODE_SAMPLING */ {
101486 /* Make all notifications non-reporting */
101487 TAILQ_FOREACH(notification, &mon->queue, localEntry)
101488 UA_Notification_dequeueSub(n: notification);
101489 }
101490
101491 /* Register the sampling callback with an interval. If registering the
101492 * sampling callback failed, set to disabled. But don't delete the current
101493 * notifications. */
101494 UA_StatusCode res = UA_MonitoredItem_registerSampling(server, mon);
101495 if(res != UA_STATUSCODE_GOOD) {
101496 mon->monitoringMode = UA_MONITORINGMODE_DISABLED;
101497 return res;
101498 }
101499
101500 /* Manually create the first sample if the MonitoredItem was disabled, the
101501 * MonitoredItem is now sampling (or reporting) and it is not an
101502 * Event-MonitoredItem */
101503 if(oldMode == UA_MONITORINGMODE_DISABLED &&
101504 mon->monitoringMode > UA_MONITORINGMODE_DISABLED &&
101505 mon->itemToMonitor.attributeId != UA_ATTRIBUTEID_EVENTNOTIFIER)
101506 monitoredItem_sampleCallback(server, mon);
101507
101508 return UA_STATUSCODE_GOOD;
101509}
101510
101511static void
101512delayedFreeMonitoredItem(void *app, void *context) {
101513 UA_free(ptr: context);
101514}
101515
101516void
101517UA_MonitoredItem_delete(UA_Server *server, UA_MonitoredItem *mon) {
101518 UA_LOCK_ASSERT(&server->serviceMutex, 1);
101519
101520 /* Remove the sampling callback */
101521 UA_MonitoredItem_unregisterSampling(server, mon);
101522
101523 /* Deregister in Server and Subscription */
101524 if(mon->registered)
101525 UA_Server_unregisterMonitoredItem(server, mon);
101526
101527 /* Remove the TriggeringLinks */
101528 if(mon->triggeringLinksSize > 0) {
101529 UA_free(ptr: mon->triggeringLinks);
101530 mon->triggeringLinks = NULL;
101531 mon->triggeringLinksSize = 0;
101532 }
101533
101534 /* Remove the queued notifications attached to the subscription */
101535 UA_Notification *notification, *notification_tmp;
101536 TAILQ_FOREACH_SAFE(notification, &mon->queue, localEntry, notification_tmp) {
101537 UA_Notification_delete(n: notification);
101538 }
101539
101540 /* Remove the settings */
101541 UA_ReadValueId_clear(p: &mon->itemToMonitor);
101542 UA_MonitoringParameters_clear(p: &mon->parameters);
101543
101544 /* Remove the last samples */
101545 UA_DataValue_clear(p: &mon->lastValue);
101546
101547 /* Add a delayed callback to remove the MonitoredItem when the current jobs
101548 * have completed. This is needed to allow that a local MonitoredItem can
101549 * remove itself in the callback. */
101550 mon->delayedFreePointers.callback = delayedFreeMonitoredItem;
101551 mon->delayedFreePointers.application = NULL;
101552 mon->delayedFreePointers.context = mon;
101553 UA_EventLoop *el = server->config.eventLoop;
101554 el->addDelayedCallback(el, &mon->delayedFreePointers);
101555}
101556
101557void
101558UA_MonitoredItem_ensureQueueSpace(UA_Server *server, UA_MonitoredItem *mon) {
101559 /* There can be only one EventOverflow more than normal entries. Because
101560 * EventOverflows are never adjacent. */
101561 UA_assert(mon->queueSize >= mon->eventOverflows);
101562 UA_assert(mon->eventOverflows <= mon->queueSize - mon->eventOverflows + 1);
101563
101564 /* Always attached to a Subscription (no local MonitoredItem) */
101565 UA_Subscription *sub = mon->subscription;
101566 UA_assert(sub);
101567
101568 /* Nothing to do */
101569 if(mon->queueSize - mon->eventOverflows <= mon->parameters.queueSize)
101570 return;
101571
101572 /* Remove notifications until the required queue size is reached */
101573 UA_Boolean reporting = false;
101574 size_t remove = mon->queueSize - mon->eventOverflows - mon->parameters.queueSize;
101575 while(remove > 0) {
101576 /* The minimum queue size (without EventOverflows) is 1. At least two
101577 * notifications that are not EventOverflows are in the queue. */
101578 UA_assert(mon->queueSize - mon->eventOverflows >= 2);
101579
101580 /* Select the next notification to delete. Skip over overflow events. */
101581 UA_Notification *del = NULL;
101582 if(mon->parameters.discardOldest) {
101583 /* Remove the oldest */
101584 del = TAILQ_FIRST(&mon->queue);
101585#if defined(UA_ENABLE_SUBSCRIPTIONS_EVENTS) && !defined(__clang_analyzer__)
101586 while(del->isOverflowEvent)
101587 del = TAILQ_NEXT(del, localEntry); /* skip overflow events */
101588#endif
101589 } else {
101590 /* Remove the second newest (to keep the up-to-date notification).
101591 * The last entry is not an OverflowEvent -- we just added it. */
101592 del = TAILQ_LAST(&mon->queue, NotificationQueue);
101593 del = TAILQ_PREV(del, NotificationQueue, localEntry);
101594#if defined(UA_ENABLE_SUBSCRIPTIONS_EVENTS) && !defined(__clang_analyzer__)
101595 while(del->isOverflowEvent)
101596 del = TAILQ_PREV(del, NotificationQueue, localEntry); /* skip overflow events */
101597#endif
101598 }
101599
101600 UA_assert(del); /* There must have been one entry that can be deleted */
101601
101602 /* Only create OverflowEvents (and set InfoBits) if the notification
101603 * that is removed is reported */
101604 if(TAILQ_NEXT(del, globalEntry) != UA_SUBSCRIPTION_QUEUE_SENTINEL)
101605 reporting = true;
101606
101607 /* Move the entry after del in the per-MonitoredItem queue right after
101608 * del in the per-Subscription queue. So we don't starve MonitoredItems
101609 * with a high sampling interval in the Subscription queue by always
101610 * removing their first appearance in the per-Subscription queue.
101611 *
101612 * With MonitoringMode == SAMPLING, the Notifications are not (all) in
101613 * the per-Subscription queue. Don't reinsert in that case.
101614 *
101615 * For the reinsertion to work, first insert into the per-Subscription
101616 * queue. */
101617 if(TAILQ_NEXT(del, globalEntry) != UA_SUBSCRIPTION_QUEUE_SENTINEL) {
101618 UA_Notification *after_del = TAILQ_NEXT(del, localEntry);
101619 UA_assert(after_del); /* There must be one remaining element after del */
101620 if(TAILQ_NEXT(after_del, globalEntry) != UA_SUBSCRIPTION_QUEUE_SENTINEL) {
101621 TAILQ_REMOVE(&sub->notificationQueue, after_del, globalEntry);
101622 TAILQ_INSERT_AFTER(&sub->notificationQueue, del, after_del, globalEntry);
101623 }
101624 }
101625
101626 remove--;
101627
101628 /* Delete the notification and remove it from the queues */
101629 UA_Notification_delete(n: del);
101630
101631 /* Update the subscription diagnostics statistics */
101632#ifdef UA_ENABLE_DIAGNOSTICS
101633 sub->monitoringQueueOverflowCount++;
101634#endif
101635
101636 /* Assertions to help Clang's scan-analyzer */
101637 UA_assert(del != TAILQ_FIRST(&mon->queue));
101638 UA_assert(del != TAILQ_LAST(&mon->queue, NotificationQueue));
101639 UA_assert(del != TAILQ_PREV(TAILQ_LAST(&mon->queue, NotificationQueue),
101640 NotificationQueue, localEntry));
101641 }
101642
101643 /* Leave an entry to indicate that notifications were removed */
101644 if(reporting) {
101645#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
101646 if(mon->itemToMonitor.attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER)
101647 createEventOverflowNotification(server, sub, mon);
101648 else
101649#endif
101650 setOverflowInfoBits(mon);
101651 }
101652}
101653
101654UA_StatusCode
101655UA_MonitoredItem_registerSampling(UA_Server *server, UA_MonitoredItem *mon) {
101656 UA_LOCK_ASSERT(&server->serviceMutex, 1);
101657
101658 /* Sampling is already registered */
101659 if(mon->samplingType != UA_MONITOREDITEMSAMPLINGTYPE_NONE)
101660 return UA_STATUSCODE_GOOD;
101661
101662 UA_StatusCode res = UA_STATUSCODE_GOOD;
101663 UA_Subscription *sub = mon->subscription;
101664 if(mon->itemToMonitor.attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER ||
101665 mon->parameters.samplingInterval == 0.0) {
101666 /* Add to the linked list in the node */
101667 UA_Session *session = &server->adminSession;
101668 if(sub)
101669 session = sub->session;
101670 res = UA_Server_editNode(server, session, nodeId: &mon->itemToMonitor.nodeId,
101671 callback: addMonitoredItemBackpointer, data: mon);
101672 if(res == UA_STATUSCODE_GOOD)
101673 mon->samplingType = UA_MONITOREDITEMSAMPLINGTYPE_EVENT;
101674 return res;
101675 } else if(sub && mon->parameters.samplingInterval == sub->publishingInterval) {
101676 /* Add to the subscription for sampling before every publish */
101677 LIST_INSERT_HEAD(&sub->samplingMonitoredItems, mon,
101678 sampling.subscriptionSampling);
101679 mon->samplingType = UA_MONITOREDITEMSAMPLINGTYPE_PUBLISH;
101680 } else {
101681 /* DataChange MonitoredItems with a positive sampling interval have a
101682 * repeated callback. Other MonitoredItems are attached to the Node in a
101683 * linked list of backpointers. */
101684 res = addRepeatedCallback(server,
101685 callback: (UA_ServerCallback)UA_MonitoredItem_sampleCallback,
101686 data: mon, interval_ms: mon->parameters.samplingInterval,
101687 callbackId: &mon->sampling.callbackId);
101688 if(res == UA_STATUSCODE_GOOD)
101689 mon->samplingType = UA_MONITOREDITEMSAMPLINGTYPE_CYCLIC;
101690 }
101691
101692 return res;
101693}
101694
101695void
101696UA_MonitoredItem_unregisterSampling(UA_Server *server, UA_MonitoredItem *mon) {
101697 UA_LOCK_ASSERT(&server->serviceMutex, 1);
101698
101699 switch(mon->samplingType) {
101700 case UA_MONITOREDITEMSAMPLINGTYPE_CYCLIC:
101701 /* Remove repeated callback */
101702 removeCallback(server, callbackId: mon->sampling.callbackId);
101703 break;
101704
101705 case UA_MONITOREDITEMSAMPLINGTYPE_EVENT: {
101706 /* Added to a node */
101707 UA_Subscription *sub = mon->subscription;
101708 UA_Session *session = &server->adminSession;
101709 if(sub)
101710 session = sub->session;
101711 UA_Server_editNode(server, session, nodeId: &mon->itemToMonitor.nodeId,
101712 callback: removeMonitoredItemBackPointer, data: mon);
101713 break;
101714 }
101715
101716 case UA_MONITOREDITEMSAMPLINGTYPE_PUBLISH:
101717 /* Added to the subscription */
101718 LIST_REMOVE(mon, sampling.subscriptionSampling);
101719 break;
101720
101721 case UA_MONITOREDITEMSAMPLINGTYPE_NONE:
101722 default:
101723 /* Sampling is not registered */
101724 break;
101725 }
101726
101727 mon->samplingType = UA_MONITOREDITEMSAMPLINGTYPE_NONE;
101728}
101729
101730UA_StatusCode
101731UA_MonitoredItem_removeLink(UA_Subscription *sub, UA_MonitoredItem *mon, UA_UInt32 linkId) {
101732 /* Find the index */
101733 size_t i = 0;
101734 for(; i < mon->triggeringLinksSize; i++) {
101735 if(mon->triggeringLinks[i] == linkId)
101736 break;
101737 }
101738
101739 /* Not existing / already removed */
101740 if(i == mon->triggeringLinksSize)
101741 return UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
101742
101743 /* Remove the link */
101744 mon->triggeringLinksSize--;
101745 if(mon->triggeringLinksSize == 0) {
101746 UA_free(ptr: mon->triggeringLinks);
101747 mon->triggeringLinks = NULL;
101748 } else {
101749 mon->triggeringLinks[i] = mon->triggeringLinks[mon->triggeringLinksSize];
101750 UA_UInt32 *tmpLinks = (UA_UInt32*)
101751 UA_realloc(ptr: mon->triggeringLinks, size: mon->triggeringLinksSize * sizeof(UA_UInt32));
101752 if(tmpLinks)
101753 mon->triggeringLinks = tmpLinks;
101754 }
101755
101756 /* Does the target MonitoredItem exist? This is stupid, but the CTT wants us
101757 * to to this. We don't auto-remove links together with the target
101758 * MonitoredItem. Links to removed MonitoredItems are removed when the link
101759 * triggers and the target no longer exists. */
101760 UA_MonitoredItem *mon2 = UA_Subscription_getMonitoredItem(sub, monitoredItemId: linkId);
101761 if(!mon2)
101762 return UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
101763
101764 return UA_STATUSCODE_GOOD;
101765}
101766
101767UA_StatusCode
101768UA_MonitoredItem_addLink(UA_Subscription *sub, UA_MonitoredItem *mon, UA_UInt32 linkId) {
101769 /* Does the target MonitoredItem exist? */
101770 UA_MonitoredItem *mon2 = UA_Subscription_getMonitoredItem(sub, monitoredItemId: linkId);
101771 if(!mon2)
101772 return UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
101773
101774 /* Does the link already exist? */
101775 for(size_t i = 0 ; i < mon->triggeringLinksSize; i++) {
101776 if(mon->triggeringLinks[i] == linkId)
101777 return UA_STATUSCODE_GOOD;
101778 }
101779
101780 /* Allocate the memory */
101781 UA_UInt32 *tmpLinkIds = (UA_UInt32*)
101782 UA_realloc(ptr: mon->triggeringLinks, size: (mon->triggeringLinksSize + 1) * sizeof(UA_UInt32));
101783 if(!tmpLinkIds)
101784 return UA_STATUSCODE_BADOUTOFMEMORY;
101785 mon->triggeringLinks = tmpLinkIds;
101786
101787 /* Add the link */
101788 mon->triggeringLinks[mon->triggeringLinksSize] = linkId;
101789 mon->triggeringLinksSize++;
101790 return UA_STATUSCODE_GOOD;
101791}
101792
101793#endif /* UA_ENABLE_SUBSCRIPTIONS */
101794
101795/**** amalgamated original file "/src/server/ua_subscription_datachange.c" ****/
101796
101797/* This Source Code Form is subject to the terms of the Mozilla Public
101798 * License, v. 2.0. If a copy of the MPL was not distributed with this
101799 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
101800 *
101801 * Copyright 2017-2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
101802 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
101803 * Copyright 2018 (c) Ari Breitkreuz, fortiss GmbH
101804 * Copyright 2018 (c) Thomas Stalder, Blue Time Concept SA
101805 * Copyright 2018 (c) Fabian Arndt, Root-Core
101806 */
101807
101808
101809#ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */
101810
101811/* Detect value changes outside the deadband */
101812#define UA_DETECT_DEADBAND(TYPE) do { \
101813 TYPE v1 = *(const TYPE*)data1; \
101814 TYPE v2 = *(const TYPE*)data2; \
101815 TYPE diff = (v1 > v2) ? (TYPE)(v1 - v2) : (TYPE)(v2 - v1); \
101816 return ((UA_Double)diff > deadband); \
101817} while(false);
101818
101819static UA_Boolean
101820detectScalarDeadBand(const void *data1, const void *data2,
101821 const UA_DataType *type, const UA_Double deadband) {
101822 if(type->typeKind == UA_DATATYPEKIND_SBYTE) {
101823 UA_DETECT_DEADBAND(UA_SByte);
101824 } else if(type->typeKind == UA_DATATYPEKIND_BYTE) {
101825 UA_DETECT_DEADBAND(UA_Byte);
101826 } else if(type->typeKind == UA_DATATYPEKIND_INT16) {
101827 UA_DETECT_DEADBAND(UA_Int16);
101828 } else if(type->typeKind == UA_DATATYPEKIND_UINT16) {
101829 UA_DETECT_DEADBAND(UA_UInt16);
101830 } else if(type->typeKind == UA_DATATYPEKIND_INT32) {
101831 UA_DETECT_DEADBAND(UA_Int32);
101832 } else if(type->typeKind == UA_DATATYPEKIND_UINT32) {
101833 UA_DETECT_DEADBAND(UA_UInt32);
101834 } else if(type->typeKind == UA_DATATYPEKIND_INT64) {
101835 UA_DETECT_DEADBAND(UA_Int64);
101836 } else if(type->typeKind == UA_DATATYPEKIND_UINT64) {
101837 UA_DETECT_DEADBAND(UA_UInt64);
101838 } else if(type->typeKind == UA_DATATYPEKIND_FLOAT) {
101839 UA_DETECT_DEADBAND(UA_Float);
101840 } else if(type->typeKind == UA_DATATYPEKIND_DOUBLE) {
101841 UA_DETECT_DEADBAND(UA_Double);
101842 } else {
101843 return false; /* Not a known numerical type */
101844 }
101845}
101846
101847static UA_Boolean
101848detectVariantDeadband(const UA_Variant *value, const UA_Variant *oldValue,
101849 const UA_Double deadbandValue) {
101850 if(value->arrayLength != oldValue->arrayLength)
101851 return true;
101852 if(value->type != oldValue->type)
101853 return true;
101854 size_t length = 1;
101855 if(!UA_Variant_isScalar(v: value))
101856 length = value->arrayLength;
101857 uintptr_t data = (uintptr_t)value->data;
101858 uintptr_t oldData = (uintptr_t)oldValue->data;
101859 UA_UInt32 memSize = value->type->memSize;
101860 for(size_t i = 0; i < length; ++i) {
101861 if(detectScalarDeadBand(data1: (const void*)data, data2: (const void*)oldData,
101862 type: value->type, deadband: deadbandValue))
101863 return true;
101864 data += memSize;
101865 oldData += memSize;
101866 }
101867 return false;
101868}
101869
101870static UA_Boolean
101871detectValueChange(UA_Server *server, UA_MonitoredItem *mon, const UA_DataValue *dv) {
101872 UA_LOCK_ASSERT(&server->serviceMutex, 1);
101873
101874 /* Status changes are always reported */
101875 if(dv->hasStatus != mon->lastValue.hasStatus ||
101876 dv->status != mon->lastValue.status) {
101877 return true;
101878 }
101879
101880 /* Default trigger is Status + Value */
101881 UA_DataChangeTrigger trigger = UA_DATACHANGETRIGGER_STATUSVALUE;
101882
101883 /* Use the configured trigger */
101884 const UA_DataChangeFilter *dcf = NULL;
101885 const UA_ExtensionObject *filter = &mon->parameters.filter;
101886 if(filter->content.decoded.type == &UA_TYPES[UA_TYPES_DATACHANGEFILTER]) {
101887 dcf = (UA_DataChangeFilter*)filter->content.decoded.data;
101888 trigger = dcf->trigger;
101889 }
101890
101891 /* The status was already tested above */
101892 if(trigger == UA_DATACHANGETRIGGER_STATUS)
101893 return false;
101894
101895 UA_assert(trigger == UA_DATACHANGETRIGGER_STATUSVALUE ||
101896 trigger == UA_DATACHANGETRIGGER_STATUSVALUETIMESTAMP);
101897
101898 /* Test absolute deadband */
101899 if(dcf && dcf->deadbandType == UA_DEADBANDTYPE_ABSOLUTE &&
101900 dv->value.type != NULL && UA_DataType_isNumeric(type: dv->value.type))
101901 return detectVariantDeadband(value: &dv->value, oldValue: &mon->lastValue.value,
101902 deadbandValue: dcf->deadbandValue);
101903
101904 /* Compare the source timestamp if the trigger requires that */
101905 if(trigger == UA_DATACHANGETRIGGER_STATUSVALUETIMESTAMP) {
101906 if(dv->hasSourceTimestamp != mon->lastValue.hasSourceTimestamp)
101907 return true;
101908 if(dv->hasSourceTimestamp &&
101909 dv->sourceTimestamp != mon->lastValue.sourceTimestamp)
101910 return true;
101911 }
101912
101913 /* Has the value changed? */
101914 if(dv->hasValue != mon->lastValue.hasValue)
101915 return true;
101916 return !UA_equal(p1: &dv->value, p2: &mon->lastValue.value,
101917 type: &UA_TYPES[UA_TYPES_VARIANT]);
101918}
101919
101920UA_StatusCode
101921UA_MonitoredItem_createDataChangeNotification(UA_Server *server, UA_MonitoredItem *mon,
101922 const UA_DataValue *dv) {
101923 /* Allocate a new notification */
101924 UA_Notification *newNot = UA_Notification_new();
101925 if(!newNot)
101926 return UA_STATUSCODE_BADOUTOFMEMORY;
101927
101928 /* Prepare the notification */
101929 newNot->mon = mon;
101930 newNot->data.dataChange.clientHandle = mon->parameters.clientHandle;
101931 UA_StatusCode retval = UA_DataValue_copy(src: dv, dst: &newNot->data.dataChange.value);
101932 if(retval != UA_STATUSCODE_GOOD) {
101933 UA_free(ptr: newNot);
101934 return retval;
101935 }
101936
101937 /* Enqueue the notification */
101938 UA_Notification_enqueueAndTrigger(server, n: newNot);
101939 return UA_STATUSCODE_GOOD;
101940}
101941
101942void
101943UA_MonitoredItem_processSampledValue(UA_Server *server, UA_MonitoredItem *mon,
101944 UA_DataValue *value) {
101945 UA_assert(mon->itemToMonitor.attributeId != UA_ATTRIBUTEID_EVENTNOTIFIER);
101946 UA_LOCK_ASSERT(&server->serviceMutex, 1);
101947
101948 /* Has the value changed (with the filters applied)? */
101949 UA_Boolean changed = detectValueChange(server, mon, dv: value);
101950 if(!changed) {
101951 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, mon->subscription,
101952 "MonitoredItem %" PRIi32 " | "
101953 "The value has not changed", mon->monitoredItemId);
101954 UA_DataValue_clear(p: value);
101955 return;
101956 }
101957
101958 /* The MonitoredItem is attached to a subscription (not server-local).
101959 * Prepare a notification and enqueue it. */
101960 if(mon->subscription) {
101961 UA_StatusCode res =
101962 UA_MonitoredItem_createDataChangeNotification(server, mon, dv: value);
101963 if(res != UA_STATUSCODE_GOOD) {
101964 UA_LOG_WARNING_SUBSCRIPTION(server->config.logging, mon->subscription,
101965 "MonitoredItem %" PRIi32 " | "
101966 "Processing the sample returned the statuscode %s",
101967 mon->monitoredItemId, UA_StatusCode_name(res));
101968 UA_DataValue_clear(p: value);
101969 return;
101970 }
101971 }
101972
101973 /* <-- Point of no return --> */
101974
101975 /* Move/store the value for filter comparison and TransferSubscription */
101976 UA_DataValue_clear(p: &mon->lastValue);
101977 mon->lastValue = *value;
101978
101979 /* Call the local callback if the MonitoredItem is not attached to a
101980 * subscription. Do this at the very end. Because the callback might delete
101981 * the subscription. */
101982 if(!mon->subscription) {
101983 UA_LocalMonitoredItem *localMon = (UA_LocalMonitoredItem*) mon;
101984 void *nodeContext = NULL;
101985 getNodeContext(server, nodeId: mon->itemToMonitor.nodeId, nodeContext: &nodeContext);
101986 localMon->callback.dataChangeCallback(server,
101987 mon->monitoredItemId, localMon->context,
101988 &mon->itemToMonitor.nodeId, nodeContext,
101989 mon->itemToMonitor.attributeId, value);
101990 }
101991}
101992
101993void
101994UA_MonitoredItem_sampleCallback(UA_Server *server, UA_MonitoredItem *mon) {
101995 lockServer(server);
101996 monitoredItem_sampleCallback(server, mon);
101997 unlockServer(server);
101998}
101999
102000void
102001monitoredItem_sampleCallback(UA_Server *server, UA_MonitoredItem *mon) {
102002 UA_LOCK_ASSERT(&server->serviceMutex, 1);
102003 UA_assert(mon->itemToMonitor.attributeId != UA_ATTRIBUTEID_EVENTNOTIFIER);
102004
102005 UA_Subscription *sub = mon->subscription;
102006 UA_LOG_DEBUG_SUBSCRIPTION(server->config.logging, sub, "MonitoredItem %" PRIi32
102007 " | Sample callback called", mon->monitoredItemId);
102008
102009 /* Sample the current value */
102010 UA_Session *session = (sub) ? sub->session : &server->adminSession;
102011 UA_DataValue dv = readWithSession(server, session, item: &mon->itemToMonitor,
102012 timestampsToReturn: mon->timestampsToReturn);
102013
102014 /* Process the sample. This always clears the value. */
102015 UA_MonitoredItem_processSampledValue(server, mon, value: &dv);
102016}
102017
102018#endif /* UA_ENABLE_SUBSCRIPTIONS */
102019
102020/**** amalgamated original file "/src/server/ua_subscription_events.c" ****/
102021
102022/* This Source Code Form is subject to the terms of the Mozilla Public
102023 * License, v. 2.0. If a copy of the MPL was not distributed with this
102024 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
102025 *
102026 * Copyright 2018 (c) Ari Breitkreuz, fortiss GmbH
102027 * Copyright 2020 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati)
102028 * Copyright 2021 (c) Fraunhofer IOSB (Author: Andreas Ebner)
102029 */
102030
102031
102032#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
102033
102034/* We use a 16-Byte ByteString as an identifier */
102035UA_StatusCode
102036generateEventId(UA_ByteString *generatedId) {
102037 /* EventId is a ByteString, which is basically just a string
102038 * We will use a 16-Byte ByteString as an identifier */
102039 UA_StatusCode res = UA_ByteString_allocBuffer(bs: generatedId, length: 16 * sizeof(UA_Byte));
102040 if(res != UA_STATUSCODE_GOOD)
102041 return res;
102042 UA_UInt32 *ids = (UA_UInt32*)generatedId->data;
102043 ids[0] = UA_UInt32_random();
102044 ids[1] = UA_UInt32_random();
102045 ids[2] = UA_UInt32_random();
102046 ids[3] = UA_UInt32_random();
102047 return UA_STATUSCODE_GOOD;
102048}
102049
102050UA_StatusCode
102051createEvent(UA_Server *server, const UA_NodeId eventType, UA_NodeId *outNodeId) {
102052 if(!outNodeId) {
102053 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_USERLAND,
102054 msg: "outNodeId must not be NULL. The event's NodeId must be returned "
102055 "so it can be triggered.");
102056 return UA_STATUSCODE_BADINVALIDARGUMENT;
102057 }
102058
102059 /* Make sure the eventType is a subtype of BaseEventType */
102060 UA_NodeId baseEventTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEEVENTTYPE);
102061 if(!isNodeInTree_singleRef(server, leafNode: &eventType, nodeToFind: &baseEventTypeId,
102062 UA_REFERENCETYPEINDEX_HASSUBTYPE)) {
102063 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_USERLAND,
102064 msg: "Event type must be a subtype of BaseEventType!");
102065 return UA_STATUSCODE_BADINVALIDARGUMENT;
102066 }
102067
102068 /* Create an ObjectNode which represents the event */
102069 UA_QualifiedName name;
102070 /* set a dummy name. This is not used. */
102071 name = UA_QUALIFIEDNAME(nsIndex: 0,chars: "E");
102072 UA_NodeId newNodeId = UA_NODEID_NULL;
102073 UA_ObjectAttributes oAttr = UA_ObjectAttributes_default;
102074 UA_StatusCode retval = addNode(server, nodeClass: UA_NODECLASS_OBJECT,
102075 requestedNewNodeId: UA_NODEID_NULL, /* Set a random unused NodeId */
102076 parentNodeId: UA_NODEID_NULL, /* No parent */
102077 referenceTypeId: UA_NODEID_NULL, /* No parent reference */
102078 browseName: name, /* an event does not have a name */
102079 typeDefinition: eventType, /* the type of the event */
102080 attr: &oAttr, /* default attributes are fine */
102081 attributeType: &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
102082 NULL, /* no node context */
102083 outNewNodeId: &newNodeId);
102084 if(retval != UA_STATUSCODE_GOOD) {
102085 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_USERLAND,
102086 msg: "Adding event failed. StatusCode %s", UA_StatusCode_name(code: retval));
102087 return retval;
102088 }
102089
102090 /* Find the eventType variable */
102091 name = UA_QUALIFIEDNAME(nsIndex: 0, chars: "EventType");
102092 UA_BrowsePathResult bpr = browseSimplifiedBrowsePath(server, origin: newNodeId, browsePathSize: 1, browsePath: &name);
102093 if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) {
102094 retval = bpr.statusCode;
102095 UA_BrowsePathResult_clear(p: &bpr);
102096 deleteNode(server, nodeId: newNodeId, true);
102097 UA_NodeId_clear(p: &newNodeId);
102098 return retval;
102099 }
102100
102101 /* Set the EventType */
102102 UA_Variant value;
102103 UA_Variant_init(p: &value);
102104 UA_Variant_setScalar(v: &value, p: (void*)(uintptr_t)&eventType, type: &UA_TYPES[UA_TYPES_NODEID]);
102105 retval = writeValueAttribute(server, nodeId: bpr.targets[0].targetId.nodeId, value: &value);
102106 UA_BrowsePathResult_clear(p: &bpr);
102107 if(retval != UA_STATUSCODE_GOOD) {
102108 deleteNode(server, nodeId: newNodeId, true);
102109 UA_NodeId_clear(p: &newNodeId);
102110 return retval;
102111 }
102112
102113 *outNodeId = newNodeId;
102114 return UA_STATUSCODE_GOOD;
102115}
102116
102117UA_StatusCode
102118UA_Server_createEvent(UA_Server *server, const UA_NodeId eventType,
102119 UA_NodeId *outNodeId) {
102120 lockServer(server);
102121 UA_StatusCode res = createEvent(server, eventType, outNodeId);
102122 unlockServer(server);
102123 return res;
102124}
102125
102126static UA_StatusCode
102127eventSetStandardFields(UA_Server *server, const UA_NodeId *event,
102128 const UA_NodeId *origin, UA_ByteString *outEventId) {
102129 /* Set the SourceNode */
102130 UA_StatusCode retval;
102131 UA_QualifiedName name = UA_QUALIFIEDNAME(nsIndex: 0, chars: "SourceNode");
102132 UA_BrowsePathResult bpr = browseSimplifiedBrowsePath(server, origin: *event, browsePathSize: 1, browsePath: &name);
102133 if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) {
102134 retval = bpr.statusCode;
102135 UA_BrowsePathResult_clear(p: &bpr);
102136 return retval;
102137 }
102138 UA_Variant value;
102139 UA_Variant_init(p: &value);
102140 UA_Variant_setScalarCopy(v: &value, p: origin, type: &UA_TYPES[UA_TYPES_NODEID]);
102141 retval = writeValueAttribute(server, nodeId: bpr.targets[0].targetId.nodeId, value: &value);
102142 UA_Variant_clear(p: &value);
102143 UA_BrowsePathResult_clear(p: &bpr);
102144 if(retval != UA_STATUSCODE_GOOD)
102145 return retval;
102146
102147 /* Set the ReceiveTime */
102148 name = UA_QUALIFIEDNAME(nsIndex: 0, chars: "ReceiveTime");
102149 bpr = browseSimplifiedBrowsePath(server, origin: *event, browsePathSize: 1, browsePath: &name);
102150 if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) {
102151 retval = bpr.statusCode;
102152 UA_BrowsePathResult_clear(p: &bpr);
102153 return retval;
102154 }
102155 UA_DateTime rcvTime = UA_DateTime_now();
102156 UA_Variant_setScalar(v: &value, p: &rcvTime, type: &UA_TYPES[UA_TYPES_DATETIME]);
102157 retval = writeValueAttribute(server, nodeId: bpr.targets[0].targetId.nodeId, value: &value);
102158 UA_BrowsePathResult_clear(p: &bpr);
102159 if(retval != UA_STATUSCODE_GOOD)
102160 return retval;
102161
102162 /* Set the EventId */
102163 UA_ByteString eventId = UA_BYTESTRING_NULL;
102164 retval = generateEventId(generatedId: &eventId);
102165 if(retval != UA_STATUSCODE_GOOD)
102166 return retval;
102167 name = UA_QUALIFIEDNAME(nsIndex: 0, chars: "EventId");
102168 bpr = browseSimplifiedBrowsePath(server, origin: *event, browsePathSize: 1, browsePath: &name);
102169 if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) {
102170 retval = bpr.statusCode;
102171 UA_ByteString_clear(p: &eventId);
102172 UA_BrowsePathResult_clear(p: &bpr);
102173 return retval;
102174 }
102175 UA_Variant_init(p: &value);
102176 UA_Variant_setScalar(v: &value, p: &eventId, type: &UA_TYPES[UA_TYPES_BYTESTRING]);
102177 retval = writeValueAttribute(server, nodeId: bpr.targets[0].targetId.nodeId, value: &value);
102178 UA_BrowsePathResult_clear(p: &bpr);
102179 if(retval != UA_STATUSCODE_GOOD) {
102180 UA_ByteString_clear(p: &eventId);
102181 return retval;
102182 }
102183
102184 /* Return the EventId */
102185 if(outEventId)
102186 *outEventId = eventId;
102187 else
102188 UA_ByteString_clear(p: &eventId);
102189
102190 return UA_STATUSCODE_GOOD;
102191}
102192
102193/* Filters an event according to the filter specified by mon and then adds it to
102194 * mons notification queue */
102195UA_StatusCode
102196UA_MonitoredItem_addEvent(UA_Server *server, UA_MonitoredItem *mon,
102197 const UA_NodeId *event) {
102198 /* Get the filter */
102199 if(mon->parameters.filter.content.decoded.type != &UA_TYPES[UA_TYPES_EVENTFILTER])
102200 return UA_STATUSCODE_BADFILTERNOTALLOWED;
102201 UA_EventFilter *eventFilter = (UA_EventFilter*)
102202 mon->parameters.filter.content.decoded.data;
102203
102204 /* Allocate memory for the notification */
102205 UA_Notification *notification = UA_Notification_new();
102206 if(!notification)
102207 return UA_STATUSCODE_BADOUTOFMEMORY;
102208
102209 /* The MonitoredItem must be attached to a Subscription. This code path is
102210 * not taken for local MonitoredItems (once they are enabled for Events). */
102211 UA_assert(mon->subscription);
102212 UA_Subscription *sub = mon->subscription;
102213 UA_Session *session = sub->session;
102214
102215 UA_EventFilterResult res; /* FilterResult contains only statuscodes. Ignored
102216 * outside the initial setup/validation. */
102217 UA_EventFilterResult_init(p: &res);
102218 UA_StatusCode retval = filterEvent(server, session, eventNode: event, filter: eventFilter,
102219 efl: &notification->data.event, result: &res);
102220 UA_EventFilterResult_clear(p: &res);
102221 if(retval != UA_STATUSCODE_GOOD) {
102222 UA_Notification_delete(n: notification);
102223 if(retval == UA_STATUSCODE_BADNOMATCH)
102224 return UA_STATUSCODE_GOOD;
102225 return retval;
102226 }
102227
102228 notification->data.event.clientHandle = mon->parameters.clientHandle;
102229 notification->mon = mon;
102230
102231 UA_Notification_enqueueAndTrigger(server, n: notification);
102232 return UA_STATUSCODE_GOOD;
102233}
102234
102235#ifdef UA_ENABLE_HISTORIZING
102236static void
102237setHistoricalEvent(UA_Server *server, const UA_NodeId *origin,
102238 const UA_NodeId *emitNodeId, const UA_NodeId *eventNodeId) {
102239 UA_Variant historicalEventFilterValue;
102240 UA_Variant_init(p: &historicalEventFilterValue);
102241
102242 /* A HistoricalEventNode that has event history available will provide this property */
102243 UA_StatusCode retval =
102244 readObjectProperty(server, objectId: *emitNodeId,
102245 propertyName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "HistoricalEventFilter"),
102246 value: &historicalEventFilterValue);
102247 if(retval != UA_STATUSCODE_GOOD) {
102248 /* Do not vex users with no match errors */
102249 if(retval != UA_STATUSCODE_BADNOMATCH)
102250 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
102251 msg: "Cannot read the HistoricalEventFilter property of a "
102252 "listening node. StatusCode %s",
102253 UA_StatusCode_name(code: retval));
102254 return;
102255 }
102256
102257 /* If found then check if HistoricalEventFilter property has a valid value */
102258 if(UA_Variant_isEmpty(v: &historicalEventFilterValue) ||
102259 !UA_Variant_isScalar(v: &historicalEventFilterValue) ||
102260 historicalEventFilterValue.type != &UA_TYPES[UA_TYPES_EVENTFILTER]) {
102261 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
102262 msg: "HistoricalEventFilter property of a listening node "
102263 "does not have a valid value");
102264 UA_Variant_clear(p: &historicalEventFilterValue);
102265 return;
102266 }
102267
102268 /* Finally, if found and valid then filter */
102269 UA_EventFilter *filter = (UA_EventFilter*) historicalEventFilterValue.data;
102270 UA_EventFieldList efl;
102271 UA_EventFilterResult result;
102272 retval = filterEvent(server, session: &server->adminSession, eventNode: eventNodeId, filter, efl: &efl, result: &result);
102273 if(retval == UA_STATUSCODE_GOOD)
102274 server->config.historyDatabase.setEvent(server, server->config.historyDatabase.context,
102275 origin, emitNodeId, filter, &efl);
102276 UA_EventFilterResult_clear(p: &result);
102277 UA_Variant_clear(p: &historicalEventFilterValue);
102278 UA_EventFieldList_clear(p: &efl);
102279}
102280#endif
102281
102282static const UA_NodeId objectsFolderId = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_OBJECTSFOLDER}};
102283#define EMIT_REFS_ROOT_COUNT 4
102284static const UA_NodeId emitReferencesRoots[EMIT_REFS_ROOT_COUNT] =
102285 {{0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_ORGANIZES}},
102286 {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASCOMPONENT}},
102287 {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASEVENTSOURCE}},
102288 {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASNOTIFIER}}};
102289
102290static const UA_NodeId isInFolderReferences[2] =
102291 {{0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_ORGANIZES}},
102292 {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASCOMPONENT}}};
102293
102294UA_StatusCode
102295triggerEvent(UA_Server *server, const UA_NodeId eventNodeId,
102296 const UA_NodeId origin, UA_ByteString *outEventId,
102297 const UA_Boolean deleteEventNode) {
102298 UA_LOCK_ASSERT(&server->serviceMutex, 1);
102299
102300 UA_LOG_NODEID_DEBUG(&origin,
102301 UA_LOG_DEBUG(server->config.logging, UA_LOGCATEGORY_SERVER,
102302 "Events: An event is triggered on node %.*s",
102303 (int)nodeIdStr.length, nodeIdStr.data));
102304
102305#ifdef UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS
102306 UA_Boolean isCallerAC = false;
102307 if(isConditionOrBranch(server, &eventNodeId, &origin, &isCallerAC)) {
102308 if(!isCallerAC) {
102309 UA_LOG_WARNING(server->config.logging, UA_LOGCATEGORY_SERVER,
102310 "Condition Events: Please use A&C API to trigger Condition Events 0x%08X",
102311 UA_STATUSCODE_BADINVALIDARGUMENT);
102312 return UA_STATUSCODE_BADINVALIDARGUMENT;
102313 }
102314 }
102315#endif /* UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS */
102316
102317 /* Check that the origin node exists */
102318 const UA_Node *originNode = UA_NODESTORE_GET(server, nodeId: &origin);
102319 if(!originNode) {
102320 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_USERLAND,
102321 msg: "Origin node for event does not exist.");
102322 return UA_STATUSCODE_BADNOTFOUND;
102323 }
102324 UA_NODESTORE_RELEASE(server, originNode);
102325
102326 /* Make sure the origin is in the ObjectsFolder (TODO: or in the ViewsFolder) */
102327 /* Only use Organizes and HasComponent to check if we are below the ObjectsFolder */
102328 UA_StatusCode retval;
102329 UA_ReferenceTypeSet refTypes;
102330 UA_ReferenceTypeSet_init(set: &refTypes);
102331 for(int i = 0; i < 2; ++i) {
102332 UA_ReferenceTypeSet tmpRefTypes;
102333 retval = referenceTypeIndices(server, refType: &isInFolderReferences[i], indices: &tmpRefTypes, true);
102334 if(retval != UA_STATUSCODE_GOOD) {
102335 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
102336 msg: "Events: Could not create the list of references and their subtypes "
102337 "with StatusCode %s", UA_StatusCode_name(code: retval));
102338 }
102339 refTypes = UA_ReferenceTypeSet_union(setA: refTypes, setB: tmpRefTypes);
102340 }
102341
102342 if(!isNodeInTree(server, leafNode: &origin, nodeToFind: &objectsFolderId, relevantRefs: &refTypes)) {
102343 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_USERLAND,
102344 msg: "Node for event must be in ObjectsFolder!");
102345 return UA_STATUSCODE_BADINVALIDARGUMENT;
102346 }
102347
102348 /* Update the standard fields of the event */
102349 retval = eventSetStandardFields(server, event: &eventNodeId, origin: &origin, outEventId);
102350 if(retval != UA_STATUSCODE_GOOD) {
102351 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
102352 msg: "Events: Could not set the standard event fields with StatusCode %s",
102353 UA_StatusCode_name(code: retval));
102354 return retval;
102355 }
102356
102357 /* List of nodes that emit the node. Events propagate upwards (bubble up) in
102358 * the node hierarchy. */
102359 UA_ExpandedNodeId *emitNodes = NULL;
102360 size_t emitNodesSize = 0;
102361
102362 /* Add the server node to the list of nodes from which the event is emitted.
102363 * The server node emits all events.
102364 *
102365 * Part 3, 7.17: In particular, the root notifier of a Server, the Server
102366 * Object defined in Part 5, is always capable of supplying all Events from
102367 * a Server and as such has implied HasEventSource References to every event
102368 * source in a Server. */
102369 UA_NodeId emitStartNodes[2];
102370 emitStartNodes[0] = origin;
102371 emitStartNodes[1] = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER);
102372
102373 /* Get all ReferenceTypes over which the events propagate */
102374 UA_ReferenceTypeSet emitRefTypes;
102375 UA_ReferenceTypeSet_init(set: &emitRefTypes);
102376 for(size_t i = 0; i < EMIT_REFS_ROOT_COUNT; i++) {
102377 UA_ReferenceTypeSet tmpRefTypes;
102378 retval = referenceTypeIndices(server, refType: &emitReferencesRoots[i], indices: &tmpRefTypes, true);
102379 if(retval != UA_STATUSCODE_GOOD) {
102380 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
102381 msg: "Events: Could not create the list of references for event "
102382 "propagation with StatusCode %s", UA_StatusCode_name(code: retval));
102383 goto cleanup;
102384 }
102385 emitRefTypes = UA_ReferenceTypeSet_union(setA: emitRefTypes, setB: tmpRefTypes);
102386 }
102387
102388 /* Get the list of nodes in the hierarchy that emits the event. */
102389 retval = browseRecursive(server, startNodesSize: 2, startNodes: emitStartNodes, browseDirection: UA_BROWSEDIRECTION_INVERSE,
102390 refTypes: &emitRefTypes, nodeClassMask: UA_NODECLASS_UNSPECIFIED, true,
102391 resultsSize: &emitNodesSize, results: &emitNodes);
102392 if(retval != UA_STATUSCODE_GOOD) {
102393 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
102394 msg: "Events: Could not create the list of nodes listening on the "
102395 "event with StatusCode %s", UA_StatusCode_name(code: retval));
102396 goto cleanup;
102397 }
102398
102399 /* Add the event to the listening MonitoredItems at each relevant node */
102400 for(size_t i = 0; i < emitNodesSize; i++) {
102401 /* Get the node */
102402 const UA_Node *node = UA_NODESTORE_GET(server, nodeId: &emitNodes[i].nodeId);
102403 if(!node)
102404 continue;
102405
102406 /* Only consider objects */
102407 if(node->head.nodeClass != UA_NODECLASS_OBJECT) {
102408 UA_NODESTORE_RELEASE(server, node);
102409 continue;
102410 }
102411
102412 /* Add event to monitoreditems */
102413 UA_MonitoredItem *mon = node->head.monitoredItems;
102414 for(; mon != NULL; mon = mon->sampling.nodeListNext) {
102415 /* Is this an Event-MonitoredItem? */
102416 if(mon->itemToMonitor.attributeId != UA_ATTRIBUTEID_EVENTNOTIFIER)
102417 continue;
102418 retval = UA_MonitoredItem_addEvent(server, mon, event: &eventNodeId);
102419 if(retval != UA_STATUSCODE_GOOD) {
102420 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
102421 msg: "Events: Could not add the event to a listening "
102422 "node with StatusCode %s", UA_StatusCode_name(code: retval));
102423 retval = UA_STATUSCODE_GOOD; /* Only log problems with individual emit nodes */
102424 }
102425 }
102426
102427 UA_NODESTORE_RELEASE(server, node);
102428
102429 /* Add event entry in the historical database */
102430#ifdef UA_ENABLE_HISTORIZING
102431 if(server->config.historyDatabase.setEvent)
102432 setHistoricalEvent(server, origin: &origin, emitNodeId: &emitNodes[i].nodeId, eventNodeId: &eventNodeId);
102433#endif
102434 }
102435
102436 /* Delete the node representation of the event */
102437 if(deleteEventNode) {
102438 retval = deleteNode(server, nodeId: eventNodeId, true);
102439 if(retval != UA_STATUSCODE_GOOD) {
102440 UA_LOG_WARNING(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
102441 msg: "Attempt to remove event using deleteNode failed. StatusCode %s",
102442 UA_StatusCode_name(code: retval));
102443 }
102444 }
102445
102446 cleanup:
102447 UA_Array_delete(p: emitNodes, size: emitNodesSize, type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
102448 return retval;
102449}
102450
102451UA_StatusCode
102452UA_Server_triggerEvent(UA_Server *server, const UA_NodeId eventNodeId,
102453 const UA_NodeId origin, UA_ByteString *outEventId,
102454 const UA_Boolean deleteEventNode) {
102455 lockServer(server);
102456 UA_StatusCode res =
102457 triggerEvent(server, eventNodeId, origin, outEventId, deleteEventNode);
102458 unlockServer(server);
102459 return res;
102460}
102461#endif /* UA_ENABLE_SUBSCRIPTIONS_EVENTS */
102462
102463/**** amalgamated original file "/src/server/ua_subscription_events_filter.c" ****/
102464
102465/* This Source Code Form is subject to the terms of the Mozilla Public
102466 * License, v. 2.0. If a copy of the MPL was not distributed with this
102467 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
102468 *
102469 * Copyright 2018 (c) Ari Breitkreuz, fortiss GmbH
102470 * Copyright 2020 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati)
102471 * Copyright 2021 (c) Fraunhofer IOSB (Author: Andreas Ebner)
102472 * Copyright 2022 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
102473 */
102474
102475
102476#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
102477
102478/* Ternary Logic
102479 * -------------
102480 * Similar to SQL, OPC UA Queries use the K3 - Strong Kleene Logic that
102481 * considers ternary values true/false/null (unknown). Most operators resolve to
102482 * a ternary value. Some operators can resolve to a literal value (e.g. CAST). */
102483
102484typedef enum {
102485 UA_TERNARY_FALSE = -1,
102486 UA_TERNARY_NULL = 0,
102487 UA_TERNARY_TRUE = 1
102488} UA_Ternary;
102489
102490static UA_Ternary
102491UA_Ternary_and(UA_Ternary first, UA_Ternary second) {
102492 if(first == UA_TERNARY_FALSE || second == UA_TERNARY_FALSE)
102493 return UA_TERNARY_FALSE;
102494 if(first == UA_TERNARY_NULL || second == UA_TERNARY_NULL)
102495 return UA_TERNARY_NULL;
102496 return UA_TERNARY_TRUE;
102497}
102498
102499static UA_Ternary
102500UA_Ternary_or(UA_Ternary first, UA_Ternary second) {
102501 if(first == UA_TERNARY_TRUE || second == UA_TERNARY_TRUE)
102502 return UA_TERNARY_TRUE;
102503 if(first == UA_TERNARY_NULL || second == UA_TERNARY_NULL)
102504 return UA_TERNARY_NULL;
102505 return UA_TERNARY_FALSE;
102506}
102507
102508/* Part 4: The NOT operator always evaluates to NULL if applied to a NULL
102509 * operand. We simply swap true/false. */
102510static UA_Ternary
102511UA_Ternary_not(UA_Ternary v) {
102512 return (UA_Ternary)((int)v * -1);
102513}
102514
102515static UA_Ternary v2t(const UA_Variant *v) {
102516 if(UA_Variant_isEmpty(v) || !UA_Variant_hasScalarType(v, type: &UA_TYPES[UA_TYPES_BOOLEAN]))
102517 return UA_TERNARY_NULL;
102518 UA_Boolean b = *(UA_Boolean*)v->data;
102519 return (b) ? UA_TERNARY_TRUE : UA_TERNARY_FALSE;
102520}
102521
102522static const UA_Boolean bFalse = false;
102523static const UA_Boolean bTrue = true;
102524
102525static UA_Variant t2v(UA_Ternary t) {
102526 UA_Variant v;
102527 UA_Variant_init(p: &v);
102528 switch(t) {
102529 case UA_TERNARY_FALSE:
102530 UA_Variant_setScalar(v: &v, p: (void*)(uintptr_t)&bFalse, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
102531 break;
102532 case UA_TERNARY_TRUE:
102533 UA_Variant_setScalar(v: &v, p: (void*)(uintptr_t)&bTrue, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
102534 break;
102535 default:
102536 return v;
102537 }
102538 v.storageType = UA_VARIANT_DATA_NODELETE;
102539 return v;
102540}
102541
102542/* Type Casting Rules
102543 * ------------------
102544 * For comparison operations values from different datatypes can be implicitly
102545 * or explicitly cast. The standard defines rules to selected the target type
102546 * for casting and when implicit casts are possible. */
102547
102548/* Defined in Part 4 Table 123 "Data Precedence Rules". Implicit casting is
102549 * always to the type of lower precedence value. */
102550static UA_Byte typePrecedence[UA_DATATYPEKINDS] = {
102551 12, 10, 11, 8, 9, 5, 6, 3, 4, 2, 1, 14, 255, 13, 255, 255, 16,
102552 15, 7, 18, 17, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
102553};
102554
102555/* Type conversion table from the standard.
102556 * 0 -> Same Type, 1 -> Implicit Cast, 2 -> Only explicit Cast, -1 -> cast invalid */
102557static UA_SByte convertLookup[21][21] = {
102558 { 0, 1,-1,-1, 1,-1, 1,-1, 1, 1, 1,-1, 1,-1, 2,-1,-1, 1, 1, 1,-1},
102559 { 2, 0,-1,-1, 1,-1, 1,-1, 1, 1, 1,-1, 1,-1, 2,-1,-1, 1, 1, 1,-1},
102560 {-1,-1, 0,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
102561 {-1,-1,-1, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1},
102562 { 2, 2,-1,-1, 0,-1, 2,-1, 2, 2, 2,-1, 2,-1, 2,-1,-1, 2, 2, 2,-1},
102563 {-1,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1, 2,-1,-1, 1,-1,-1,-1,-1,-1,-1},
102564 { 2, 2,-1,-1, 1,-1, 0,-1, 2, 2, 2,-1, 2,-1, 2,-1,-1, 2, 2, 2,-1},
102565 {-1,-1, 2,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1},
102566 { 2, 2,-1,-1, 1,-1, 1,-1, 0, 1, 1,-1, 2,-1, 2,-1,-1, 2, 1, 1,-1},
102567 { 2, 2,-1,-1, 1,-1, 1,-1, 2, 0, 1,-1, 2, 2, 2,-1,-1, 2, 2, 1,-1},
102568 { 2, 2,-1,-1, 1,-1, 1,-1, 2, 2, 0,-1, 2, 2, 2,-1,-1, 2, 2, 2,-1},
102569 {-1,-1,-1,-1,-1, 1,-1,-1,-1,-1,-1, 0,-1,-1, 1,-1,-1,-1,-1,-1,-1},
102570 { 2, 2,-1,-1, 1,-1, 1,-1, 1, 1, 1,-1, 0,-1, 2,-1,-1, 1, 1, 1,-1},
102571 {-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1,-1,-1, 0,-1,-1,-1, 2, 1, 1,-1},
102572 { 1, 1,-1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1,-1, 0, 2, 2, 1, 1, 1,-1},
102573 {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 0,-1,-1,-1,-1,-1},
102574 {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 0,-1,-1,-1,-1},
102575 { 2, 2,-1,-1, 1,-1, 1,-1, 1, 1, 1,-1, 2, 1, 2,-1,-1, 0, 1, 1,-1},
102576 { 2, 2,-1,-1, 1,-1, 1,-1, 2, 1, 1,-1, 2, 2, 2,-1,-1, 2, 0, 1,-1},
102577 { 2, 2,-1,-1, 1,-1, 1,-1, 2, 2, 1,-1, 2, 2, 2,-1,-1, 2, 2, 0,-1},
102578 {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0}
102579};
102580
102581/* This array maps the index of the DataType-Kind to the index of the type
102582 * conversion matrix (255 -> not contained in the matrix) */
102583static UA_Byte convertLookupIndex[UA_DATATYPEKINDS] = {
102584 0, 12, 1, 8, 17, 9, 18, 10, 19, 6, 4, 14, 3, 7, 2,
102585 20, 11, 5, 13, 16, 15,255,255,255,255,255,255,255,255,255,255
102586};
102587
102588/* Returns the target type for implicit cassting or NULL if no implicit casting
102589 * is possible */
102590static const UA_DataType *
102591implicitCastTargetType(const UA_DataType *t1, const UA_DataType *t2) {
102592 if(!t1 || t1 == t2)
102593 return t1;
102594
102595 /* Get the type precedence. Return if no implicit casting is possible. */
102596 UA_Byte p1 = typePrecedence[t1->typeKind];
102597 UA_Byte p2 = typePrecedence[t2->typeKind];
102598 if(p1 == UA_BYTE_MAX || p2 == UA_BYTE_MAX)
102599 return NULL;
102600
102601 /* Which is the target type based on the precedence rules? */
102602 const UA_DataType *targetType = (p1 < p2) ? t1 : t2;
102603 const UA_DataType *sourceType = (p1 < p2) ? t2 : t1;
102604
102605 /* Lookup the casting rule */
102606 UA_Byte sourceIndex = convertLookupIndex[sourceType->typeKind];
102607 UA_Byte targetIndex = convertLookupIndex[targetType->typeKind];
102608 if(sourceIndex == UA_BYTE_MAX || targetIndex == UA_BYTE_MAX)
102609 return NULL;
102610 UA_SByte castingRule = convertLookup[sourceIndex][targetIndex];
102611
102612 /* Is implicit casting allowed? */
102613 if(castingRule != 0 && castingRule != 1)
102614 return NULL;
102615 return targetType;
102616}
102617
102618/* Cast Numerical
102619 * --------------
102620 * To reduce the number of cases we first "normalize" to either of
102621 * Int64/UInt64/Double. Then cast from there to the target type. This works for
102622 * all numericals (not only the implicit conversion).
102623 *
102624 * Numerical conversion rules from the standard:
102625 *
102626 * - If the conversion fails the result is a null value.
102627 * - Floating point values are rounded by adding 0.5 and truncating when they
102628 * are converted to integer values.
102629 * - Converting a value that is outside the range of the target type causes a
102630 * conversion error. */
102631
102632#define UA_CAST_SIGNED(t, T) \
102633 if(i < T##_MIN || (i > 0 && (t)i > T##_MAX)) \
102634 return; \
102635 *(t*)data = (t)i; \
102636 do { } while(0)
102637
102638#define UA_CAST_UNSIGNED(t, T) \
102639 if(u > T##_MAX) \
102640 return; \
102641 *(t*)data = (t)u; \
102642 do { } while(0)
102643
102644#define UA_CAST_FLOAT(t, T) \
102645 if(f + 0.5 < (UA_Double)T##_MIN || f + 0.5 > (UA_Double)T##_MAX) \
102646 return; \
102647 *(t*)data = (t)(f + 0.5); \
102648 do { } while(0)
102649
102650/* We can cast between any numerical type. So this can be reused for explicit casting. */
102651static void
102652castNumerical(const UA_Variant *in, const UA_DataType *type, UA_Variant *out) {
102653 UA_assert(UA_Variant_isScalar(in));
102654 UA_Variant_init(p: out); /* Set to null value */
102655
102656 UA_Int64 i = 0;
102657 UA_UInt64 u = 0;
102658 UA_Double f = 0.0;
102659
102660 const UA_DataTypeKind ink = (UA_DataTypeKind)in->type->typeKind;
102661 switch(ink) {
102662 case UA_DATATYPEKIND_SBYTE: i = *(UA_SByte*)in->data; break;
102663 case UA_DATATYPEKIND_INT16: i = *(UA_Int16*)in->data; break;
102664 case UA_DATATYPEKIND_INT32: i = *(UA_Int32*)in->data; break;
102665 case UA_DATATYPEKIND_INT64: i = *(UA_Int64*)in->data; break;
102666 case UA_DATATYPEKIND_BYTE: /* or */
102667 case UA_DATATYPEKIND_BOOLEAN: u = *(UA_Byte*)in->data; break;
102668 case UA_DATATYPEKIND_UINT16: u = *(UA_UInt16*)in->data; break;
102669 case UA_DATATYPEKIND_UINT32: /* or */
102670 case UA_DATATYPEKIND_STATUSCODE: u = *(UA_UInt32*)in->data; break;
102671 case UA_DATATYPEKIND_UINT64: u = *(UA_UInt64*)in->data; break;
102672 case UA_DATATYPEKIND_FLOAT: f = *(UA_Float*)in->data; break;
102673 case UA_DATATYPEKIND_DOUBLE: f = *(UA_Double*)in->data; break;
102674 default: return;
102675 }
102676
102677 void *data = UA_new(type);
102678 if(!data)
102679 return;
102680
102681 if(ink == UA_DATATYPEKIND_SBYTE || ink == UA_DATATYPEKIND_INT16 ||
102682 ink == UA_DATATYPEKIND_INT32 || ink == UA_DATATYPEKIND_INT64) {
102683 /* Cast from signed */
102684 switch(type->typeKind) {
102685 case UA_DATATYPEKIND_SBYTE: UA_CAST_SIGNED(UA_SByte, UA_SBYTE); break;
102686 case UA_DATATYPEKIND_INT16: UA_CAST_SIGNED(UA_Int16, UA_INT16); break;
102687 case UA_DATATYPEKIND_INT32: UA_CAST_SIGNED(UA_Int32, UA_INT32); break;
102688 case UA_DATATYPEKIND_INT64: *(UA_Int64*)data = i; break;
102689 case UA_DATATYPEKIND_BYTE: UA_CAST_SIGNED(UA_Byte, UA_BYTE); break;
102690 case UA_DATATYPEKIND_UINT16: UA_CAST_SIGNED(UA_UInt16, UA_UINT16); break;
102691 case UA_DATATYPEKIND_UINT32: UA_CAST_SIGNED(UA_UInt32, UA_UINT32); break;
102692 case UA_DATATYPEKIND_UINT64: UA_CAST_SIGNED(UA_UInt64, UA_UINT64); break;
102693 case UA_DATATYPEKIND_FLOAT: *(UA_Float*)data = (UA_Float)i; break;
102694 case UA_DATATYPEKIND_DOUBLE: *(UA_Double*)data = (UA_Double)i; break;
102695 default:
102696 UA_free(ptr: data);
102697 return;
102698 }
102699 } else if(ink == UA_DATATYPEKIND_BYTE || ink == UA_DATATYPEKIND_UINT16 ||
102700 ink == UA_DATATYPEKIND_UINT32 || ink == UA_DATATYPEKIND_UINT64) {
102701 /* Cast from unsigned */
102702 switch(type->typeKind) {
102703 case UA_DATATYPEKIND_SBYTE: UA_CAST_UNSIGNED(UA_SByte, UA_SBYTE); break;
102704 case UA_DATATYPEKIND_INT16: UA_CAST_UNSIGNED(UA_Int16, UA_INT16); break;
102705 case UA_DATATYPEKIND_INT32: UA_CAST_UNSIGNED(UA_Int32, UA_INT32); break;
102706 case UA_DATATYPEKIND_INT64: UA_CAST_UNSIGNED(UA_Int64, UA_INT64); break;
102707 case UA_DATATYPEKIND_BYTE: UA_CAST_UNSIGNED(UA_Byte, UA_BYTE); break;
102708 case UA_DATATYPEKIND_UINT16: UA_CAST_UNSIGNED(UA_UInt16, UA_UINT16); break;
102709 case UA_DATATYPEKIND_UINT32: UA_CAST_UNSIGNED(UA_UInt32, UA_UINT32); break;
102710 case UA_DATATYPEKIND_UINT64: *(UA_UInt64*)data = u; break;
102711 case UA_DATATYPEKIND_FLOAT: *(UA_Float*)data = (UA_Float)u; break;
102712 case UA_DATATYPEKIND_DOUBLE: *(UA_Double*)data = (UA_Double)u; break;
102713 default:
102714 UA_free(ptr: data);
102715 return;
102716 }
102717 } else {
102718 /* Cast from float */
102719 if(f != f) {
102720 /* NaN cannot be cast */
102721 UA_free(ptr: data);
102722 return;
102723 }
102724 switch(type->typeKind) {
102725 case UA_DATATYPEKIND_SBYTE: UA_CAST_FLOAT(UA_SByte, UA_SBYTE); break;
102726 case UA_DATATYPEKIND_INT16: UA_CAST_FLOAT(UA_Int16, UA_INT16); break;
102727 case UA_DATATYPEKIND_INT32: UA_CAST_FLOAT(UA_Int32, UA_INT32); break;
102728 case UA_DATATYPEKIND_INT64: UA_CAST_FLOAT(UA_Int64, UA_INT64); break;
102729 case UA_DATATYPEKIND_BYTE: UA_CAST_FLOAT(UA_Byte, UA_BYTE); break;
102730 case UA_DATATYPEKIND_UINT16: UA_CAST_FLOAT(UA_UInt16, UA_UINT16); break;
102731 case UA_DATATYPEKIND_UINT32: UA_CAST_FLOAT(UA_UInt32, UA_UINT32); break;
102732 case UA_DATATYPEKIND_UINT64: UA_CAST_FLOAT(UA_UInt64, UA_UINT64); break;
102733 case UA_DATATYPEKIND_FLOAT: *(UA_Float*)data = (UA_Float)f; break;
102734 case UA_DATATYPEKIND_DOUBLE: *(UA_Double*)data = (UA_Double)f; break;
102735 default:
102736 UA_free(ptr: data);
102737 return;
102738 }
102739 }
102740
102741 UA_Variant_setScalar(v: out, p: data, type);
102742}
102743
102744/* Implicit Casting
102745 * ---------------- */
102746
102747static UA_INLINE UA_Byte uppercase(UA_Byte in) { return in | 32; }
102748
102749static UA_StatusCode
102750castImplicitFromString(const UA_Variant *in, const UA_DataType *outType, UA_Variant *out) {
102751#if defined(UA_ENABLE_PARSING) || defined(UA_ENABLE_JSON_ENCODING)
102752 UA_StatusCode res = UA_STATUSCODE_GOOD;
102753#endif
102754 if(outType == &UA_TYPES[UA_TYPES_BOOLEAN]) {
102755 /* String -> Boolean
102756 *
102757 * Part 4 says: String values containing "true", "false", "1" or "0"
102758 * can be converted to Boolean values. Other string values cause a
102759 * conversion error. In this case Strings are case-insensitive. */
102760 UA_Boolean b;
102761 const UA_String *inStr = (const UA_String*)in->data;
102762 if(inStr->length == 1 && inStr->data[0] == '0') {
102763 b = false;
102764 } else if(inStr->length == 1 && inStr->data[0] == '1') {
102765 b = true;
102766 } else if(inStr->length == 4 &&
102767 uppercase(in: inStr->data[0])== 'T' && uppercase(in: inStr->data[1])== 'R' &&
102768 uppercase(in: inStr->data[2])== 'U' && uppercase(in: inStr->data[3])== 'E') {
102769 b = true;
102770 } else if(inStr->length == 5 && uppercase(in: inStr->data[0])== 'F' &&
102771 uppercase(in: inStr->data[1])== 'A' && uppercase(in: inStr->data[2])== 'L' &&
102772 uppercase(in: inStr->data[3])== 'S' && uppercase(in: inStr->data[4])== 'E') {
102773 b = false;
102774 } else {
102775 return UA_STATUSCODE_BADTYPEMISMATCH;
102776 }
102777 return UA_Variant_setScalarCopy(v: out, p: &b, type: outType);
102778 }
102779
102780#ifdef UA_ENABLE_PARSING
102781 else if(outType == &UA_TYPES[UA_TYPES_GUID]) {
102782 /* String -> Guid */
102783 UA_Guid guid;
102784 res = UA_Guid_parse(guid: &guid, str: *(UA_String*)in->data);
102785 if(res != UA_STATUSCODE_GOOD)
102786 return res;
102787 return UA_Variant_setScalarCopy(v: out, p: &guid, type: outType);
102788 }
102789#endif
102790
102791#ifdef UA_ENABLE_JSON_ENCODING
102792 /* String -> Numerical, uses the JSON decoding */
102793 else if(UA_DataType_isNumeric(type: outType)) {
102794 void *outData = UA_new(type: outType);
102795 if(!outData)
102796 return UA_STATUSCODE_BADOUTOFMEMORY;
102797 res = UA_decodeJson(src: (const UA_ByteString*)in->data, dst: outData, type: outType, NULL);
102798 if(res != UA_STATUSCODE_GOOD) {
102799 UA_free(ptr: outData);
102800 return res;
102801 }
102802 UA_Variant_setScalar(v: out, p: outData, type: outType);
102803 return UA_STATUSCODE_GOOD;
102804 }
102805#endif
102806
102807 /* No implicit casting possible */
102808 return UA_STATUSCODE_BADTYPEMISMATCH;
102809}
102810
102811static UA_StatusCode
102812castImplicit(const UA_Variant *in, const UA_DataType *outType, UA_Variant *out) {
102813 /* Of the input is empty, casting results in a NULL value */
102814 if(UA_Variant_isEmpty(v: in)) {
102815 UA_Variant_init(p: out);
102816 return UA_STATUSCODE_GOOD;
102817 }
102818
102819 /* TODO: We only support scalar values for now */
102820 if(!UA_Variant_isScalar(v: in))
102821 return UA_STATUSCODE_BADFILTEROPERATORUNSUPPORTED;
102822
102823 /* No casting necessary */
102824 if(in->type == outType) {
102825 *out = *in;
102826 out->storageType = UA_VARIANT_DATA_NODELETE;
102827 return UA_STATUSCODE_GOOD;
102828 }
102829
102830 UA_StatusCode res = UA_STATUSCODE_GOOD;
102831 switch(in->type->typeKind) {
102832 case UA_DATATYPEKIND_EXPANDEDNODEID: {
102833 /* ExpandedNodeId -> String */
102834 if(outType != &UA_TYPES[UA_TYPES_STRING])
102835 break;
102836 UA_String *outStr = UA_String_new();
102837 if(!outStr)
102838 return UA_STATUSCODE_BADOUTOFMEMORY;
102839 res = UA_ExpandedNodeId_print(eid: (const UA_ExpandedNodeId*)in->data, output: outStr);
102840 if(res != UA_STATUSCODE_GOOD) {
102841 UA_free(ptr: outStr);
102842 break;
102843 }
102844 UA_Variant_setScalar(v: out, p: outStr, type: outType);
102845 break;
102846 }
102847
102848 case UA_DATATYPEKIND_NODEID: {
102849 if(outType == &UA_TYPES[UA_TYPES_STRING]) {
102850 /* NodeId -> String */
102851 UA_String *outStr = UA_String_new();
102852 if(!outStr)
102853 return UA_STATUSCODE_BADOUTOFMEMORY;
102854 res = UA_NodeId_print(id: (const UA_NodeId*)in->data, output: outStr);
102855 if(res != UA_STATUSCODE_GOOD) {
102856 UA_free(ptr: outStr);
102857 break;
102858 }
102859 UA_Variant_setScalar(v: out, p: outStr, type: outType);
102860 } else if(outType == &UA_TYPES[UA_TYPES_EXPANDEDNODEID]) {
102861 /* NodeId -> ExpandedNodeId */
102862 UA_ExpandedNodeId *eid = UA_ExpandedNodeId_new();
102863 if(!eid)
102864 return UA_STATUSCODE_BADOUTOFMEMORY;
102865 res = UA_NodeId_copy(src: (const UA_NodeId*)in->data, dst: &eid->nodeId);
102866 if(res != UA_STATUSCODE_GOOD) {
102867 UA_free(ptr: eid);
102868 break;
102869 }
102870 UA_Variant_setScalar(v: out, p: eid, type: outType);
102871 }
102872 break;
102873 }
102874
102875 case UA_DATATYPEKIND_STRING:
102876 res = castImplicitFromString(in, outType, out);
102877 break;
102878
102879 case UA_DATATYPEKIND_LOCALIZEDTEXT: {
102880 if(outType != &UA_TYPES[UA_TYPES_STRING])
102881 break;
102882 /* LocalizedText -> String */
102883 UA_LocalizedText *inLT = (UA_LocalizedText*)in->data;
102884 res = UA_Variant_setScalarCopy(v: out, p: &inLT->text, type: outType);
102885 break;
102886 }
102887
102888 case UA_DATATYPEKIND_QUALIFIEDNAME: {
102889 UA_QualifiedName *inQN = (UA_QualifiedName*)in->data;
102890 if(outType == &UA_TYPES[UA_TYPES_STRING]) {
102891 /* QualifiedName -> String */
102892 res = UA_Variant_setScalarCopy(v: out, p: &inQN->name, type: outType);
102893 } else if(outType == &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]) {
102894 /* QualifiedName -> LocalizedText */
102895 UA_LocalizedText lt;
102896 lt.text = inQN->name;
102897 lt.locale = UA_STRING_NULL;
102898 res = UA_Variant_setScalarCopy(v: out, p: &lt, type: outType);
102899 }
102900 break;
102901 }
102902
102903 default:
102904 /* Try casting between numericals (also works for Boolean and StatusCode
102905 * input). The conversion can fail if the limits of the output type are
102906 * exceeded and then results in a NULL value. */
102907 castNumerical(in, type: outType, out);
102908 }
102909
102910 return res;
102911}
102912
102913/* Filter Evaluation
102914 * ----------------- */
102915
102916typedef struct {
102917 UA_Server *server;
102918 UA_Session *session;
102919 const UA_NodeId *eventNode;
102920 const UA_ContentFilter *filter;
102921 UA_ContentFilterResult *filterResult;
102922 UA_Variant results[UA_EVENTFILTER_MAXELEMENTS];
102923
102924 /* The stack contains temporary variants. Cleaned up after the evaluation of
102925 * each operator. */
102926 size_t top;
102927 UA_Variant stack[UA_EVENTFILTER_MAXOPERANDS];
102928} UA_FilterEvalContext;
102929
102930/* Operand Resolving
102931 * ~~~~~~~~~~~~~~~~~
102932 * Methods that all resolve an operator operand to a Variant. */
102933
102934/* Part 4, 7.4.4.5 SimpleAttributeOperand: The clause can point to any attribute
102935 * of nodes. Either a child of the event node and also the event type. */
102936static UA_StatusCode
102937resolveSimpleAttributeOperand(UA_Server *server, UA_Session *session,
102938 const UA_NodeId *origin,
102939 const UA_SimpleAttributeOperand *sao,
102940 UA_Variant *value) {
102941 /* Prepare the ReadValueId */
102942 UA_ReadValueId rvi;
102943 UA_ReadValueId_init(p: &rvi);
102944 rvi.indexRange = sao->indexRange;
102945 rvi.attributeId = sao->attributeId;
102946
102947 /* Read the value */
102948 UA_DataValue v;
102949 if(sao->browsePathSize == 0) {
102950 /* If this list (browsePath) is empty, the Node is the instance of the
102951 * TypeDefinition. (Part 4, 7.4.4.5) */
102952 rvi.nodeId = *origin;
102953
102954 /* A Condition is an indirection. Look up the target node. */
102955 /* TODO: check for Branches! One Condition could have multiple Branches */
102956 UA_NodeId conditionTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_CONDITIONTYPE);
102957 if(UA_NodeId_equal(p1: &sao->typeDefinitionId, p2: &conditionTypeId)) {
102958#ifdef UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS
102959 UA_StatusCode res = UA_getConditionId(server, origin, &rvi.nodeId);
102960 UA_CHECK_STATUS(res, return res);
102961#else
102962 return UA_STATUSCODE_BADNOTSUPPORTED;
102963#endif
102964 }
102965
102966 v = readWithSession(server, session, item: &rvi, timestampsToReturn: UA_TIMESTAMPSTORETURN_NEITHER);
102967 } else {
102968 /* Resolve the browse path, starting from the event-source (and not the
102969 * typeDefinitionId). */
102970 UA_BrowsePathResult bpr =
102971 browseSimplifiedBrowsePath(server, origin: *origin,
102972 browsePathSize: sao->browsePathSize, browsePath: sao->browsePath);
102973 if(bpr.targetsSize == 0 && bpr.statusCode == UA_STATUSCODE_GOOD)
102974 bpr.statusCode = UA_STATUSCODE_BADNOTFOUND;
102975 if(bpr.statusCode != UA_STATUSCODE_GOOD) {
102976 UA_StatusCode res = bpr.statusCode;
102977 UA_BrowsePathResult_clear(p: &bpr);
102978 return res;
102979 }
102980
102981 /* Use the first match */
102982 rvi.nodeId = bpr.targets[0].targetId.nodeId;
102983 v = readWithSession(server, session, item: &rvi, timestampsToReturn: UA_TIMESTAMPSTORETURN_NEITHER);
102984 UA_BrowsePathResult_clear(p: &bpr);
102985 }
102986
102987 /* Validate the result */
102988 if(v.status != UA_STATUSCODE_GOOD) {
102989 UA_Variant_clear(p: &v.value);
102990 return v.status;
102991 }
102992 if(!v.hasValue)
102993 return UA_STATUSCODE_BADNODATAAVAILABLE;
102994
102995 /* Move the result to the output */
102996 *value = v.value;
102997 return UA_STATUSCODE_GOOD;
102998}
102999
103000static UA_StatusCode
103001resolveOperand(UA_FilterEvalContext *ctx, UA_ExtensionObject *op, UA_Variant *out) {
103002 if(op->encoding != UA_EXTENSIONOBJECT_DECODED &&
103003 op->encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE)
103004 return UA_STATUSCODE_BADFILTEROPERATORUNSUPPORTED;
103005
103006 /* Result of an operator that was evaluated prior */
103007 if(op->content.decoded.type == &UA_TYPES[UA_TYPES_ELEMENTOPERAND]) {
103008 UA_ElementOperand *eo = (UA_ElementOperand*)op->content.decoded.data;
103009 *out = ctx->results[eo->index];
103010 out->storageType = UA_VARIANT_DATA_NODELETE;
103011 return UA_STATUSCODE_GOOD;
103012 }
103013
103014 /* Literal value */
103015 if(op->content.decoded.type == &UA_TYPES[UA_TYPES_LITERALOPERAND]) {
103016 UA_LiteralOperand *lo = (UA_LiteralOperand*)op->content.decoded.data;
103017 *out = lo->value;
103018 out->storageType = UA_VARIANT_DATA_NODELETE;
103019 return UA_STATUSCODE_GOOD;
103020 }
103021
103022 /* SimpleAttributeOperand with a BrowsePath */
103023 if(op->content.decoded.type == &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]) {
103024 UA_SimpleAttributeOperand *sao =
103025 (UA_SimpleAttributeOperand*)op->content.decoded.data;
103026 return resolveSimpleAttributeOperand(server: ctx->server, session: ctx->session,
103027 origin: ctx->eventNode, sao, value: out);
103028 }
103029
103030 return UA_STATUSCODE_BADFILTEROPERATORUNSUPPORTED;
103031}
103032
103033/* The operandIndex is within the operator arguments, not the operand index for
103034 * the overall stack */
103035static UA_StatusCode
103036setOperandError(UA_FilterEvalContext *ctx, size_t elementIndex,
103037 size_t operandIndex, UA_StatusCode statusCode) {
103038 UA_ContentFilterElementResult *res = &ctx->filterResult->elementResults[elementIndex];
103039 res->operandStatusCodes[operandIndex] = statusCode;
103040 /* The operator status is set globally in a single location upwards the call chain
103041 * res->statusCode = statusCode; */
103042 return statusCode;
103043}
103044
103045/* Filter Operators
103046 * ~~~~~~~~~~~~~~~~ */
103047
103048static UA_StatusCode
103049ofTypeOperator(UA_FilterEvalContext *ctx, size_t index) {
103050 const UA_ContentFilterElement *elm = &ctx->filter->elements[index];
103051 UA_assert(elm->filterOperandsSize == 1);
103052
103053 /* Get the operand. Must be a literal NodeId */
103054 UA_Variant *op0 = &ctx->stack[ctx->top++];
103055 UA_StatusCode res = resolveOperand(ctx, op: &elm->filterOperands[0], out: op0);
103056 if(res != UA_STATUSCODE_GOOD || !UA_Variant_hasScalarType(v: op0, type: &UA_TYPES[UA_TYPES_NODEID]))
103057 return setOperandError(ctx, elementIndex: index, operandIndex: 0, UA_STATUSCODE_BADFILTEROPERATORUNSUPPORTED);
103058
103059 /* Read the event type */
103060 UA_Variant eventTypeVar;
103061 UA_Variant_init(p: &eventTypeVar);
103062 const UA_NodeId *operandTypeId = (const UA_NodeId *)op0->data;
103063 res = readObjectProperty(server: ctx->server, objectId: *ctx->eventNode,
103064 propertyName: UA_QUALIFIEDNAME(nsIndex: 0, chars: "EventType"), value: &eventTypeVar);
103065 UA_CHECK_STATUS(res, return res);
103066
103067 if(!UA_Variant_hasScalarType(v: &eventTypeVar, type: &UA_TYPES[UA_TYPES_NODEID])) {
103068 UA_LOG_WARNING(logger: ctx->server->config.logging, category: UA_LOGCATEGORY_SERVER,
103069 msg: "EventType has an invalid type.");
103070 UA_Variant_clear(p: &eventTypeVar);
103071 return UA_STATUSCODE_BADINTERNALERROR;
103072 }
103073
103074 /* Check if the eventtype is equal to the operand or a subtype of it */
103075 const UA_NodeId *eventTypeId = (UA_NodeId*)eventTypeVar.data;
103076 UA_Boolean ofType = isNodeInTree_singleRef(server: ctx->server, leafNode: eventTypeId, nodeToFind: operandTypeId,
103077 UA_REFERENCETYPEINDEX_HASSUBTYPE);
103078 ctx->results[index] = t2v(t: ofType ? UA_TERNARY_TRUE : UA_TERNARY_FALSE);
103079 UA_Variant_clear(p: &eventTypeVar);
103080 return UA_STATUSCODE_GOOD;
103081}
103082
103083static UA_StatusCode
103084andOperator(UA_FilterEvalContext *ctx, size_t index) {
103085 const UA_ContentFilterElement *elm = &ctx->filter->elements[index];
103086 UA_assert(elm->filterOperandsSize == 2);
103087 UA_Variant *op0 = &ctx->stack[ctx->top++];
103088 UA_StatusCode res = resolveOperand(ctx, op: &elm->filterOperands[0], out: op0);
103089 UA_CHECK_STATUS(res, return res);
103090 UA_Variant *op1 = &ctx->stack[ctx->top++];
103091 res = resolveOperand(ctx, op: &elm->filterOperands[1], out: op1);
103092 UA_CHECK_STATUS(res, return res);
103093 ctx->results[index] = t2v(t: UA_Ternary_and(first: v2t(v: op0), second: v2t(v: op1)));
103094 return UA_STATUSCODE_GOOD;
103095}
103096
103097static UA_StatusCode
103098orOperator(UA_FilterEvalContext *ctx, size_t index) {
103099 const UA_ContentFilterElement *elm = &ctx->filter->elements[index];
103100 UA_assert(elm->filterOperandsSize == 2);
103101 UA_Variant *op0 = &ctx->stack[ctx->top++];
103102 UA_StatusCode res = resolveOperand(ctx, op: &elm->filterOperands[0], out: op0);
103103 UA_CHECK_STATUS(res, return res);
103104 UA_Variant *op1 = &ctx->stack[ctx->top++];
103105 res = resolveOperand(ctx, op: &elm->filterOperands[1], out: op1);
103106 UA_CHECK_STATUS(res, return res);
103107 ctx->results[index] = t2v(t: UA_Ternary_or(first: v2t(v: op0), second: v2t(v: op1)));
103108 return UA_STATUSCODE_GOOD;
103109}
103110
103111static UA_StatusCode
103112notOperator(UA_FilterEvalContext *ctx, size_t index) {
103113 const UA_ContentFilterElement *elm = &ctx->filter->elements[index];
103114 UA_assert(elm->filterOperandsSize == 1);
103115 UA_Variant *op0 = &ctx->stack[ctx->top++];
103116 UA_StatusCode res = resolveOperand(ctx, op: &elm->filterOperands[0], out: op0);
103117 UA_CHECK_STATUS(res, return res);
103118 ctx->results[index] = t2v(t: UA_Ternary_not(v: v2t(v: op0)));
103119 return UA_STATUSCODE_GOOD;
103120}
103121
103122/* Resolves the operands and casts them implicitly to the same type.
103123 * The result is set at &ctx->stack[ctx->top] (for the initial value of top). */
103124static UA_StatusCode
103125castResolveOperands(UA_FilterEvalContext *ctx, size_t index, UA_Boolean setError) {
103126 /* Enough space on the stack left? */
103127 const UA_ContentFilterElement *elm = &ctx->filter->elements[index];
103128 if(ctx->top + elm->filterOperandsSize > UA_EVENTFILTER_MAXOPERANDS)
103129 return UA_STATUSCODE_BADOUTOFMEMORY;
103130
103131 /* Resolve all operands */
103132 UA_assert(ctx->top == 0); /* Assume the stack is empty */
103133 UA_StatusCode res = UA_STATUSCODE_GOOD;
103134 for(size_t i = 0; i < elm->filterOperandsSize; i++) {
103135 res = resolveOperand(ctx, op: &elm->filterOperands[i], out: &ctx->stack[ctx->top++]);
103136 UA_CHECK_STATUS(res, return res);
103137 }
103138 UA_assert(ctx->top > 0); /* Assume the stack is no longer empty */
103139
103140 /* Get the datatype for casting */
103141 const UA_DataType *targetType = ctx->stack[0].type;
103142 for(size_t pos = 1; pos < ctx->top; pos++) {
103143 if(targetType)
103144 targetType = implicitCastTargetType(t1: targetType, t2: ctx->stack[pos].type);
103145 if(!targetType)
103146 return (setError) ? setOperandError(ctx, elementIndex: index, operandIndex: pos, statusCode: res) : res;
103147 }
103148
103149 /* Cast the operands. Put the result in the same location on the stack. */
103150 for(size_t pos = 0; pos < ctx->top; pos++) {
103151 UA_Variant orig = ctx->stack[pos];
103152 res = castImplicit(in: &orig, outType: targetType, out: &ctx->stack[pos]);
103153 if(res != UA_STATUSCODE_GOOD)
103154 return (setError) ? setOperandError(ctx, elementIndex: index, operandIndex: pos, statusCode: res) : res;
103155 if(ctx->stack[pos].data == orig.data) {
103156 /* Reuse the storage type of the original data if the variant is
103157 * identical or only the type has changed */
103158 ctx->stack[pos].storageType = orig.storageType;
103159 } else {
103160 UA_Variant_clear(p: &orig); /* Fresh allocation of the cast variant. Clean up. */
103161 }
103162 }
103163
103164 return UA_STATUSCODE_GOOD;
103165}
103166
103167static UA_StatusCode
103168compareOperator(UA_FilterEvalContext *ctx, size_t index, UA_FilterOperator op) {
103169 UA_assert(ctx->filter->elements[index].filterOperandsSize == 2);
103170
103171 /* Resolve and cast the operands. A failed casting results in FALSE. Note
103172 * that operands could cast to NULL. */
103173 UA_assert(ctx->top == 0); /* Assume the stack is empty */
103174 UA_StatusCode res = castResolveOperands(ctx, index, false);
103175 if(res != UA_STATUSCODE_GOOD || !ctx->stack[0].type ||
103176 ctx->stack[0].type != ctx->stack[1].type) {
103177 ctx->results[index] = t2v(t: UA_TERNARY_FALSE);
103178 return UA_STATUSCODE_GOOD;
103179 }
103180 UA_assert(ctx->top == 2); /* Assume the stack is no longer empty */
103181
103182 /* The equals operator is always possible. For the other comparisons it has
103183 * to be an ordered type: Numerical, Boolean, StatusCode or DateTime. */
103184 const UA_DataType *type = ctx->stack[0].type;
103185 if(op != UA_FILTEROPERATOR_EQUALS && !UA_DataType_isNumeric(type) &&
103186 type->typeKind != UA_DATATYPEKIND_BOOLEAN &&
103187 type->typeKind != UA_DATATYPEKIND_STATUSCODE &&
103188 type->typeKind != UA_DATATYPEKIND_DATETIME)
103189 return setOperandError(ctx, elementIndex: index, operandIndex: 0, UA_STATUSCODE_BADFILTEROPERANDINVALID);
103190
103191 /* Compute the order */
103192 UA_Order eq = UA_order(p1: ctx->stack[0].data, p2: ctx->stack[1].data, type);
103193 UA_Ternary operatorResult = UA_TERNARY_FALSE;
103194 switch(op) {
103195 case UA_FILTEROPERATOR_EQUALS:
103196 default:
103197 if(eq == UA_ORDER_EQ)
103198 operatorResult = UA_TERNARY_TRUE;
103199 break;
103200 case UA_FILTEROPERATOR_GREATERTHAN:
103201 if(eq == UA_ORDER_MORE)
103202 operatorResult = UA_TERNARY_TRUE;
103203 break;
103204 case UA_FILTEROPERATOR_LESSTHAN:
103205 if(eq == UA_ORDER_LESS)
103206 operatorResult = UA_TERNARY_TRUE;
103207 break;
103208 case UA_FILTEROPERATOR_GREATERTHANOREQUAL:
103209 if(eq == UA_ORDER_MORE || eq == UA_ORDER_EQ)
103210 operatorResult = UA_TERNARY_TRUE;
103211 break;
103212 case UA_FILTEROPERATOR_LESSTHANOREQUAL:
103213 if(eq == UA_ORDER_LESS || eq == UA_ORDER_EQ)
103214 operatorResult = UA_TERNARY_TRUE;
103215 break;
103216 }
103217
103218 /* Set result as a literal value */
103219 ctx->results[index] = t2v(t: operatorResult);
103220 return UA_STATUSCODE_GOOD;
103221}
103222
103223static UA_StatusCode
103224equalsOperator(UA_FilterEvalContext *ctx, size_t index) {
103225 return compareOperator(ctx, index, op: UA_FILTEROPERATOR_EQUALS);
103226}
103227
103228static UA_StatusCode
103229gtOperator(UA_FilterEvalContext *ctx, size_t index) {
103230 return compareOperator(ctx, index, op: UA_FILTEROPERATOR_GREATERTHAN);
103231}
103232
103233static UA_StatusCode
103234ltOperator(UA_FilterEvalContext *ctx, size_t index) {
103235 return compareOperator(ctx, index, op: UA_FILTEROPERATOR_LESSTHAN);
103236}
103237
103238static UA_StatusCode
103239gteOperator(UA_FilterEvalContext *ctx, size_t index) {
103240 return compareOperator(ctx, index, op: UA_FILTEROPERATOR_GREATERTHANOREQUAL);
103241}
103242
103243static UA_StatusCode
103244lteOperator(UA_FilterEvalContext *ctx, size_t index) {
103245 return compareOperator(ctx, index, op: UA_FILTEROPERATOR_LESSTHANOREQUAL);
103246}
103247
103248static UA_StatusCode
103249bitwiseOperator(UA_FilterEvalContext *ctx, size_t index, UA_FilterOperator op) {
103250 UA_assert(ctx->filter->elements[index].filterOperandsSize == 2);
103251
103252 /* Resolve and cast the operands. Note that operands could cast to NULL. */
103253 UA_assert(ctx->top == 0); /* Assume the stack is empty */
103254 UA_StatusCode res = castResolveOperands(ctx, index, true);
103255 UA_CHECK_STATUS(res, return res);
103256 UA_assert(ctx->top == 2); /* Assume we have two elements */
103257
103258 /* Operands can cast to NULL */
103259 const UA_DataType *type = ctx->stack[0].type;
103260 if(!type || !UA_DataType_isNumeric(type) ||
103261 ctx->stack[0].type != ctx->stack[1].type)
103262 return UA_STATUSCODE_BADTYPEMISMATCH;
103263
103264 /* Copy the casted literal to the result */
103265 res = UA_Variant_copy(src: &ctx->stack[0], dst: &ctx->results[index]);
103266 UA_CHECK_STATUS(res, return res);
103267
103268 /* Do the bitwise operation on the result data */
103269 UA_Byte *bytesOut = (UA_Byte*)ctx->results[index].data;
103270 const UA_Byte *bytes2 = (const UA_Byte*)ctx->stack[1].data;
103271 for(size_t i = 0; i < type->memSize; i++) {
103272 if(op == UA_FILTEROPERATOR_BITWISEAND)
103273 bytesOut[i] = bytesOut[i] & bytes2[i];
103274 else
103275 bytesOut[i] = bytesOut[i] | bytes2[i];
103276 }
103277 return UA_STATUSCODE_GOOD;
103278}
103279
103280static UA_StatusCode
103281bitwiseAndOperator(UA_FilterEvalContext *ctx, size_t index) {
103282 return bitwiseOperator(ctx, index, op: UA_FILTEROPERATOR_BITWISEAND);
103283}
103284
103285static UA_StatusCode
103286bitwiseOrOperator(UA_FilterEvalContext *ctx, size_t index) {
103287 return bitwiseOperator(ctx, index, op: UA_FILTEROPERATOR_BITWISEOR);
103288}
103289
103290static UA_StatusCode
103291betweenOperator(UA_FilterEvalContext *ctx, size_t index) {
103292 UA_assert(ctx->filter->elements[index].filterOperandsSize == 3);
103293
103294 /* If no implicit conversion is available and the operands are of different
103295 * types, the particular result is FALSE. */
103296 UA_assert(ctx->top == 0); /* Assume the stack is empty */
103297 UA_StatusCode res = castResolveOperands(ctx, index, false);
103298 if(res != UA_STATUSCODE_GOOD) {
103299 ctx->results[index] = t2v(t: UA_TERNARY_FALSE);
103300 return UA_STATUSCODE_GOOD;
103301 }
103302 UA_assert(ctx->top == 3); /* Assume we have three elements */
103303
103304 /* The casting can result in NULL values or a non-numerical type */
103305 const UA_DataType *type = ctx->stack[0].type;
103306 if(!type || !UA_DataType_isNumeric(type) ||
103307 type != ctx->stack[1].type || type != ctx->stack[2].type)
103308 return UA_STATUSCODE_BADTYPEMISMATCH;
103309
103310 UA_Order o1 = UA_order(p1: ctx->stack[0].data, p2: ctx->stack[1].data, type);
103311 UA_Order o2 = UA_order(p1: ctx->stack[0].data, p2: ctx->stack[2].data, type);
103312 UA_Ternary comp = ((o1 == UA_ORDER_MORE || o1 == UA_ORDER_EQ) &&
103313 (o2 == UA_ORDER_LESS || o2 == UA_ORDER_EQ)) ?
103314 UA_TERNARY_TRUE : UA_TERNARY_FALSE;
103315
103316 ctx->results[index] = t2v(t: comp);
103317 return UA_STATUSCODE_GOOD;
103318}
103319
103320static UA_StatusCode
103321inListOperator(UA_FilterEvalContext *ctx, size_t index) {
103322 const UA_ContentFilterElement *elm = &ctx->filter->elements[index];
103323 UA_assert(elm->filterOperandsSize >= 2);
103324 UA_Boolean found = false;
103325 UA_Variant *op0 = &ctx->stack[ctx->top++];
103326 UA_Variant *op1 = &ctx->stack[ctx->top++];
103327 UA_StatusCode res = resolveOperand(ctx, op: &elm->filterOperands[0], out: op0);
103328 UA_CHECK_STATUS(res, return res);
103329 for(size_t i = 1; i < elm->filterOperandsSize && !found; i++) {
103330 res = resolveOperand(ctx, op: &elm->filterOperands[i], out: op1);
103331 if(res != UA_STATUSCODE_GOOD)
103332 continue;
103333 if(op0->type == op1->type && UA_equal(p1: op0->data, p2: op1->data, type: op0->type))
103334 found = true;
103335 UA_Variant_clear(p: op1);
103336 }
103337 ctx->results[index] = t2v(t: (found) ? UA_TERNARY_TRUE: UA_TERNARY_FALSE);
103338 return UA_STATUSCODE_GOOD;
103339}
103340
103341static UA_StatusCode
103342isNullOperator(UA_FilterEvalContext *ctx, size_t index) {
103343 const UA_ContentFilterElement *elm = &ctx->filter->elements[index];
103344 UA_assert(elm->filterOperandsSize == 1);
103345 UA_Variant *op0 = &ctx->stack[ctx->top++];
103346 UA_StatusCode res = resolveOperand(ctx, op: &elm->filterOperands[0], out: op0);
103347 UA_CHECK_STATUS(res, return res);
103348 ctx->results[index] = t2v(t: UA_Variant_isEmpty(v: op0) ? UA_TERNARY_TRUE : UA_TERNARY_FALSE);
103349 return UA_STATUSCODE_GOOD;
103350}
103351
103352static UA_StatusCode
103353notImplementedOperator(UA_FilterEvalContext *ctx, size_t index) {
103354 return UA_STATUSCODE_BADFILTEROPERATORUNSUPPORTED;
103355}
103356
103357/* Filter Evaluation
103358 * ~~~~~~~~~~~~~~~~~ */
103359
103360typedef struct {
103361 UA_StatusCode (*operatorMethod)(UA_FilterEvalContext *ctx, size_t index);
103362 UA_Byte minOperatorCount;
103363 UA_Byte maxOperatorCount;
103364} UA_FilterOperatorJumptableElement;
103365
103366static const UA_FilterOperatorJumptableElement operatorJumptable[18] = {
103367 {equalsOperator, 2, 2},
103368 {isNullOperator, 1, 1},
103369 {gtOperator, 2, 2},
103370 {ltOperator, 2, 2},
103371 {gteOperator, 2, 2},
103372 {lteOperator, 2, 2},
103373 {notImplementedOperator, 0, UA_EVENTFILTER_MAXOPERANDS}, /* like */
103374 {notOperator, 1, 1},
103375 {betweenOperator, 3, 3},
103376 {inListOperator, 2, UA_EVENTFILTER_MAXOPERANDS},
103377 {andOperator, 2, 2},
103378 {orOperator, 2, 2},
103379 {notImplementedOperator, 0, UA_EVENTFILTER_MAXOPERANDS}, /* cast */
103380 {notImplementedOperator, 0, UA_EVENTFILTER_MAXOPERANDS}, /* in view */
103381 {ofTypeOperator, 1, 1},
103382 {notImplementedOperator, 0, UA_EVENTFILTER_MAXOPERANDS}, /* related to */
103383 {bitwiseAndOperator, 2, 2},
103384 {bitwiseOrOperator, 2, 2}
103385};
103386
103387UA_StatusCode
103388evaluateWhereClause(UA_Server *server, UA_Session *session, const UA_NodeId *eventNode,
103389 const UA_ContentFilter *contentFilter,
103390 UA_ContentFilterResult *contentFilterResult) {
103391 UA_LOCK_ASSERT(&server->serviceMutex, 1);
103392
103393 /* An empty filter always succeeds */
103394 if(contentFilter->elementsSize == 0)
103395 return UA_STATUSCODE_GOOD;
103396
103397 /* Prepare the context */
103398 UA_FilterEvalContext ctx;
103399 ctx.filterResult = contentFilterResult;
103400 ctx.filter = contentFilter;
103401 ctx.server = server;
103402 ctx.session = session;
103403 ctx.eventNode = eventNode;
103404 ctx.top = 0;
103405
103406 /* Pacify some compilers by initializing the first result */
103407 UA_Variant_init(p: &ctx.results[0]);
103408
103409 /* Evaluate the filter. Iterate backwards over the filter elements and
103410 * resolve each. This ensures that all element-index operands point to an
103411 * evaluated element. */
103412 UA_StatusCode res = UA_STATUSCODE_GOOD;
103413 int i = (int)contentFilter->elementsSize - 1;
103414 for(; i >= 0; i--) {
103415 UA_ContentFilterElement *cfe = &contentFilter->elements[i];
103416 res = operatorJumptable[cfe->filterOperator].operatorMethod(&ctx, (size_t)i);
103417 for(size_t j = 0; j < ctx.top; j++)
103418 UA_Variant_clear(p: &ctx.stack[j]); /* clean up the stack */
103419 ctx.top = 0;
103420 if(res != UA_STATUSCODE_GOOD)
103421 break;
103422 }
103423
103424 /* The filter matches if the operator at the first position evaluates to TRUE */
103425 if(res == UA_STATUSCODE_GOOD && v2t(v: &ctx.results[0]) != UA_TERNARY_TRUE)
103426 res = UA_STATUSCODE_BADNOMATCH;
103427
103428 /* Clean up the element result variants */
103429 for(int j = (int)contentFilter->elementsSize - 1; j > i; j--)
103430 UA_Variant_clear(p: &ctx.results[j]);
103431 return res;
103432}
103433
103434static UA_Boolean
103435isValidEvent(UA_Server *server, const UA_NodeId *validEventParent,
103436 const UA_NodeId *eventId) {
103437 UA_LOCK_ASSERT(&server->serviceMutex, 1);
103438
103439 /* Find the eventType variableNode */
103440 UA_QualifiedName findName = UA_QUALIFIEDNAME(nsIndex: 0, chars: "EventType");
103441 UA_BrowsePathResult bpr = browseSimplifiedBrowsePath(server, origin: *eventId, browsePathSize: 1, browsePath: &findName);
103442 if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) {
103443 UA_BrowsePathResult_clear(p: &bpr);
103444 return false;
103445 }
103446
103447 /* Get the EventType Property Node */
103448 UA_Variant tOutVariant;
103449 UA_Variant_init(p: &tOutVariant);
103450 /* Read the Value of EventType Property Node (the Value should be a NodeId) */
103451 UA_StatusCode retval = readWithReadValue(server, nodeId: &bpr.targets[0].targetId.nodeId,
103452 attributeId: UA_ATTRIBUTEID_VALUE, v: &tOutVariant);
103453 if(retval != UA_STATUSCODE_GOOD ||
103454 !UA_Variant_hasScalarType(v: &tOutVariant, type: &UA_TYPES[UA_TYPES_NODEID])) {
103455 UA_BrowsePathResult_clear(p: &bpr);
103456 return false;
103457 }
103458
103459 const UA_NodeId *tEventType = (UA_NodeId*)tOutVariant.data;
103460
103461 /* Check whether the EventType is a Subtype of CondtionType (Part 9 first
103462 * implementation) */
103463 UA_NodeId conditionTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_CONDITIONTYPE);
103464 if(UA_NodeId_equal(p1: validEventParent, p2: &conditionTypeId) &&
103465 isNodeInTree_singleRef(server, leafNode: tEventType, nodeToFind: &conditionTypeId,
103466 UA_REFERENCETYPEINDEX_HASSUBTYPE)) {
103467 UA_BrowsePathResult_clear(p: &bpr);
103468 UA_Variant_clear(p: &tOutVariant);
103469 return true;
103470 }
103471
103472 /* EventType is not a Subtype of CondtionType (ConditionId Clause won't be
103473 * present in Events, which are not Conditions) */
103474 /* Check whether Valid Event other than Conditions */
103475 UA_NodeId baseEventTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEEVENTTYPE);
103476 UA_Boolean isSubtypeOfBaseEvent =
103477 isNodeInTree_singleRef(server, leafNode: tEventType, nodeToFind: &baseEventTypeId,
103478 UA_REFERENCETYPEINDEX_HASSUBTYPE);
103479
103480 UA_BrowsePathResult_clear(p: &bpr);
103481 UA_Variant_clear(p: &tOutVariant);
103482 return isSubtypeOfBaseEvent;
103483}
103484
103485UA_StatusCode
103486filterEvent(UA_Server *server, UA_Session *session,
103487 const UA_NodeId *eventNode, UA_EventFilter *filter,
103488 UA_EventFieldList *efl, UA_EventFilterResult *result) {
103489 UA_LOCK_ASSERT(&server->serviceMutex, 1);
103490
103491 if(filter->selectClausesSize == 0)
103492 return UA_STATUSCODE_BADEVENTFILTERINVALID;
103493
103494 UA_EventFieldList_init(p: efl);
103495 efl->eventFields = (UA_Variant *)
103496 UA_Array_new(size: filter->selectClausesSize, type: &UA_TYPES[UA_TYPES_VARIANT]);
103497 if(!efl->eventFields)
103498 return UA_STATUSCODE_BADOUTOFMEMORY;
103499 efl->eventFieldsSize = filter->selectClausesSize;
103500
103501 /* Empty event filter result */
103502 UA_EventFilterResult_init(p: result);
103503 result->selectClauseResultsSize = filter->selectClausesSize;
103504 result->selectClauseResults = (UA_StatusCode *)
103505 UA_Array_new(size: filter->selectClausesSize, type: &UA_TYPES[UA_TYPES_STATUSCODE]);
103506 if(!result->selectClauseResults) {
103507 UA_EventFieldList_clear(p: efl);
103508 UA_EventFilterResult_clear(p: result);
103509 return UA_STATUSCODE_BADOUTOFMEMORY;
103510 }
103511
103512 /* Prepare content filter result structure */
103513 if(filter->whereClause.elementsSize > 0) {
103514 result->whereClauseResult.elementResultsSize = filter->whereClause.elementsSize;
103515 result->whereClauseResult.elementResults = (UA_ContentFilterElementResult *)
103516 UA_Array_new(size: filter->whereClause.elementsSize,
103517 type: &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENTRESULT]);
103518 if(!result->whereClauseResult.elementResults) {
103519 UA_EventFieldList_clear(p: efl);
103520 UA_EventFilterResult_clear(p: result);
103521 return UA_STATUSCODE_BADOUTOFMEMORY;
103522 }
103523
103524 for(size_t i = 0; i < filter->whereClause.elementsSize; ++i) {
103525 UA_ContentFilterElementResult *er =
103526 &result->whereClauseResult.elementResults[i];
103527 UA_ContentFilterElement *cf = &filter->whereClause.elements[i];
103528 er->operandStatusCodesSize = cf->filterOperandsSize;
103529 er->operandStatusCodes = (UA_StatusCode *)
103530 UA_Array_new(size: er->operandStatusCodesSize, type: &UA_TYPES[UA_TYPES_STATUSCODE]);
103531 if(!er->operandStatusCodes) {
103532 UA_EventFieldList_clear(p: efl);
103533 UA_EventFilterResult_clear(p: result);
103534 return UA_STATUSCODE_BADOUTOFMEMORY;
103535 }
103536 }
103537 }
103538
103539 /* Evaluate the where filter. Do we event need to consider the event? */
103540 UA_StatusCode res = evaluateWhereClause(server, session, eventNode,
103541 contentFilter: &filter->whereClause,
103542 contentFilterResult: &result->whereClauseResult);
103543 if(res != UA_STATUSCODE_GOOD){
103544 UA_EventFieldList_clear(p: efl);
103545 UA_EventFilterResult_clear(p: result);
103546 return res;
103547 }
103548
103549 /* Apply the select filter */
103550 UA_NodeId baseEventTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEEVENTTYPE);
103551 for(size_t i = 0; i < filter->selectClausesSize; i++) {
103552 UA_SimpleAttributeOperand *sc = &filter->selectClauses[i];
103553 /* Check if the browsePath is BaseEventType, in which case nothing more
103554 * needs to be checked */
103555 if(!UA_NodeId_equal(p1: &sc->typeDefinitionId, p2: &baseEventTypeId) &&
103556 !isValidEvent(server, validEventParent: &sc->typeDefinitionId, eventId: eventNode)) {
103557 UA_Variant_init(p: &efl->eventFields[i]);
103558 /* EventFilterResult currently isn't being used
103559 notification->result.selectClauseResults[i] =
103560 UA_STATUSCODE_BADTYPEDEFINITIONINVALID; */
103561 continue;
103562 }
103563
103564 /* Lookup the field. The overall filter can succeed even if a single
103565 * select-field cannot be resolved. */
103566 result->selectClauseResults[i] =
103567 resolveSimpleAttributeOperand(server, session, origin: eventNode,
103568 sao: sc, value: &efl->eventFields[i]);
103569 }
103570
103571 return UA_STATUSCODE_GOOD;
103572}
103573
103574/*****************************************/
103575/* Validation of Filters during Creation */
103576/*****************************************/
103577
103578/* Initial select clause validation. The following checks are currently performed:
103579 * - Check if typedefenitionid or browsepath of any clause is NULL
103580 * - Check if the eventType is a subtype of BaseEventType
103581 * - Check if attributeId is valid
103582 * - Check if browsePath contains null
103583 * - Check if indexRange is defined and if it is parsable
103584 * - Check if attributeId is value */
103585UA_StatusCode
103586UA_SimpleAttributeOperandValidation(UA_Server *server,
103587 const UA_SimpleAttributeOperand *sao) {
103588 /* TypeDefinition is not NULL? */
103589 if(UA_NodeId_isNull(p: &sao->typeDefinitionId))
103590 return UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
103591
103592 /* EventType is a subtype of BaseEventType? */
103593 UA_NodeId baseEventTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEEVENTTYPE);
103594 if(!isNodeInTree_singleRef(server, leafNode: &sao->typeDefinitionId,
103595 nodeToFind: &baseEventTypeId, UA_REFERENCETYPEINDEX_HASSUBTYPE))
103596 return UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
103597
103598 /* AttributeId is valid ? */
103599 if(sao->attributeId == 0 || sao->attributeId >= 28)
103600 return UA_STATUSCODE_BADATTRIBUTEIDINVALID;
103601
103602 /* If the BrowsePath is empty, the Node is the instance of the
103603 * TypeDefinition. (Part 4, 7.4.4.5) */
103604 if(sao->browsePathSize == 0)
103605 return UA_STATUSCODE_GOOD;
103606
103607 /* BrowsePath contains empty BrowseNames? */
103608 for(size_t j = 0; j < sao->browsePathSize; ++j) {
103609 if(UA_QualifiedName_isNull(q: &sao->browsePath[j]))
103610 return UA_STATUSCODE_BADBROWSENAMEINVALID;
103611 }
103612
103613 /* Get the list of subtypes from event type (including the event type itself) */
103614 UA_ReferenceTypeSet reftypes_interface =
103615 UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASSUBTYPE);
103616 UA_ExpandedNodeId *childTypeNodes = NULL;
103617 size_t childTypeNodesSize = 0;
103618 UA_StatusCode res = browseRecursive(server, startNodesSize: 1, startNodes: &sao->typeDefinitionId,
103619 browseDirection: UA_BROWSEDIRECTION_FORWARD, refTypes: &reftypes_interface,
103620 nodeClassMask: UA_NODECLASS_OBJECTTYPE, true, resultsSize: &childTypeNodesSize,
103621 results: &childTypeNodes);
103622 if(res != UA_STATUSCODE_GOOD)
103623 return UA_STATUSCODE_BADATTRIBUTEIDINVALID;
103624
103625 /* Is the browse path valid for one of them? */
103626 UA_Boolean subTypeContainField = false;
103627 for(size_t j = 0; j < childTypeNodesSize && !subTypeContainField; j++) {
103628 UA_BrowsePathResult bpr =
103629 browseSimplifiedBrowsePath(server, origin: childTypeNodes[j].nodeId,
103630 browsePathSize: sao->browsePathSize, browsePath: sao->browsePath);
103631
103632 if(bpr.statusCode == UA_STATUSCODE_GOOD && bpr.targetsSize > 0)
103633 subTypeContainField = true;
103634 UA_BrowsePathResult_clear(p: &bpr);
103635 }
103636
103637 UA_Array_delete(p: childTypeNodes, size: childTypeNodesSize, type: &UA_TYPES[UA_TYPES_EXPANDEDNODEID]);
103638
103639 if(!subTypeContainField)
103640 return UA_STATUSCODE_BADNODEIDUNKNOWN;
103641
103642 /* IndexRange is defined ? */
103643 if(!UA_String_isEmpty(s: &sao->indexRange)) {
103644 UA_NumericRange numericRange = UA_NUMERICRANGE(s: "");
103645 if(UA_NumericRange_parse(range: &numericRange, str: sao->indexRange) != UA_STATUSCODE_GOOD)
103646 return UA_STATUSCODE_BADINDEXRANGEINVALID;
103647 UA_free(ptr: numericRange.dimensions);
103648
103649 /* AttributeId has to be a value if an IndexRange is defined */
103650 if(sao->attributeId != UA_ATTRIBUTEID_VALUE)
103651 return UA_STATUSCODE_BADTYPEMISMATCH;
103652 }
103653
103654 return UA_STATUSCODE_GOOD;
103655}
103656
103657/* Initial content filter (where clause) check. Current checks:
103658 * - Number of operands for each (supported) operator
103659 * - ElementOperands point forward only */
103660UA_ContentFilterElementResult
103661UA_ContentFilterElementValidation(UA_Server *server, size_t operatorIndex,
103662 size_t operatorsCount,
103663 const UA_ContentFilterElement *ef) {
103664 /* Initialize the result structure */
103665 UA_ContentFilterElementResult er;
103666 UA_ContentFilterElementResult_init(p: &er);
103667 er.operandStatusCodes = (UA_StatusCode *)
103668 UA_Array_new(size: ef->filterOperandsSize, type: &UA_TYPES[UA_TYPES_STATUSCODE]);
103669 if(!er.operandStatusCodes) {
103670 er.statusCode = UA_STATUSCODE_BADOUTOFMEMORY;
103671 return er;
103672 }
103673 er.operandStatusCodesSize = ef->filterOperandsSize;
103674
103675 /* Is the operator in the defined range? Test this before the following
103676 * jumptable lookup. */
103677 if(ef->filterOperator < 0 || ef->filterOperator > UA_FILTEROPERATOR_BITWISEOR) {
103678 er.statusCode = UA_STATUSCODE_BADEVENTFILTERINVALID;
103679 return er;
103680 }
103681
103682 /* Number of operands supported for the operator? */
103683 if(ef->filterOperandsSize < operatorJumptable[ef->filterOperator].minOperatorCount ||
103684 ef->filterOperandsSize > operatorJumptable[ef->filterOperator].maxOperatorCount) {
103685 er.statusCode = UA_STATUSCODE_BADFILTEROPERANDCOUNTMISMATCH;
103686 return er;
103687 }
103688
103689 /* Generic validation of the operands */
103690 for(size_t i = 0; i < ef->filterOperandsSize; i++) {
103691 /* Must be a decoded ExtensionObject */
103692 UA_ExtensionObject *op = &ef->filterOperands[i];
103693 if(op->encoding != UA_EXTENSIONOBJECT_DECODED &&
103694 op->encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) {
103695 er.operandStatusCodes[i] = UA_STATUSCODE_BADFILTEROPERANDINVALID;
103696 er.statusCode = UA_STATUSCODE_BADFILTEROPERANDINVALID;
103697 return er;
103698 }
103699
103700 /* Supported type and conforming to the rules? */
103701 if(op->content.decoded.type == &UA_TYPES[UA_TYPES_ELEMENTOPERAND]) {
103702 /* Part 4, 7.4.4.2 defines conditions for Element Operands: An index
103703 * is considered valid if its value is greater than the element
103704 * index it is part of and it does not Reference a non-existent
103705 * element. Clients shall construct filters in this way to avoid
103706 * circular and invalid References. */
103707 UA_ElementOperand *eo = (UA_ElementOperand *)op->content.decoded.data;
103708 if(eo->index <= operatorIndex || eo->index >= operatorsCount) {
103709 er.operandStatusCodes[i] = UA_STATUSCODE_BADINDEXRANGEINVALID;
103710 er.statusCode = UA_STATUSCODE_BADINDEXRANGEINVALID;
103711 return er;
103712 }
103713 } else if(op->content.decoded.type == &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]) {
103714 er.operandStatusCodes[i] = UA_STATUSCODE_BADNOTSUPPORTED;
103715 er.statusCode = UA_STATUSCODE_BADFILTERNOTALLOWED;
103716 return er;
103717 } else if(op->content.decoded.type != &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND] &&
103718 op->content.decoded.type != &UA_TYPES[UA_TYPES_LITERALOPERAND]) {
103719 er.operandStatusCodes[i] = UA_STATUSCODE_BADFILTEROPERANDINVALID;
103720 er.statusCode = UA_STATUSCODE_BADFILTEROPERANDINVALID;
103721 return er;
103722 }
103723 }
103724
103725 /* Specific validations for different operators */
103726 switch(ef->filterOperator) {
103727 case UA_FILTEROPERATOR_INVIEW:
103728 case UA_FILTEROPERATOR_RELATEDTO:
103729 /* Not allowed for event WhereClause according to 7.17.3 in Part 4 */
103730 er.statusCode = UA_STATUSCODE_BADEVENTFILTERINVALID;
103731 break;
103732
103733 case UA_FILTEROPERATOR_EQUALS:
103734 case UA_FILTEROPERATOR_GREATERTHAN:
103735 case UA_FILTEROPERATOR_LESSTHAN:
103736 case UA_FILTEROPERATOR_GREATERTHANOREQUAL:
103737 case UA_FILTEROPERATOR_LESSTHANOREQUAL:
103738 case UA_FILTEROPERATOR_BITWISEAND:
103739 case UA_FILTEROPERATOR_BITWISEOR:
103740 case UA_FILTEROPERATOR_BETWEEN:
103741 case UA_FILTEROPERATOR_INLIST:
103742 case UA_FILTEROPERATOR_AND:
103743 case UA_FILTEROPERATOR_OR:
103744 case UA_FILTEROPERATOR_ISNULL:
103745 case UA_FILTEROPERATOR_NOT:
103746 break;
103747
103748 case UA_FILTEROPERATOR_OFTYPE: {
103749 /* Make sure the operand is a NodeId literal */
103750 UA_ExtensionObject *o = &ef->filterOperands[0];
103751 UA_LiteralOperand *lo = (UA_LiteralOperand *)o->content.decoded.data;
103752 if(o->content.decoded.type != &UA_TYPES[UA_TYPES_LITERALOPERAND] ||
103753 !UA_Variant_hasScalarType(v: &lo->value, type: &UA_TYPES[UA_TYPES_NODEID])) {
103754 er.operandStatusCodes[0] = UA_STATUSCODE_BADFILTEROPERANDINVALID;
103755 er.statusCode = UA_STATUSCODE_BADFILTEROPERANDINVALID;
103756 break;
103757 }
103758
103759 /* Make sure the operand is a subtype of BaseEventType */
103760 UA_NodeId baseEventTypeId = UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_BASEEVENTTYPE);
103761 if(!isNodeInTree_singleRef(server, leafNode: (UA_NodeId *)lo->value.data, nodeToFind: &baseEventTypeId,
103762 UA_REFERENCETYPEINDEX_HASSUBTYPE)) {
103763 er.operandStatusCodes[0] = UA_STATUSCODE_BADFILTEROPERANDINVALID;
103764 er.statusCode = UA_STATUSCODE_BADFILTEROPERANDINVALID;
103765 break;
103766 }
103767 break;
103768 }
103769
103770 case UA_FILTEROPERATOR_LIKE:
103771 case UA_FILTEROPERATOR_CAST:
103772 er.statusCode = UA_STATUSCODE_BADFILTEROPERATORUNSUPPORTED;
103773 break;
103774
103775 default:
103776 er.statusCode = UA_STATUSCODE_BADFILTEROPERATORINVALID;
103777 break;
103778 }
103779 return er;
103780}
103781
103782#endif /* UA_ENABLE_SUBSCRIPTIONS_EVENTS */
103783
103784/**** amalgamated original file "/src/server/ua_discovery.c" ****/
103785
103786/* This Source Code Form is subject to the terms of the Mozilla Public
103787 * License, v. 2.0. If a copy of the MPL was not distributed with this
103788 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
103789 *
103790 * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
103791 * Copyright 2014, 2017 (c) Florian Palm
103792 * Copyright 2015-2016, 2019 (c) Sten Grüner
103793 * Copyright 2015 (c) Chris Iatrou
103794 * Copyright 2015-2016 (c) Oleksiy Vasylyev
103795 * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH
103796 * Copyright 2017 (c) Julian Grothoff
103797 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
103798 * Copyright 2017 (c) HMS Industrial Networks AB (Author: Jonas Green)
103799 */
103800
103801
103802#ifdef UA_ENABLE_DISCOVERY
103803
103804void
103805UA_DiscoveryManager_setState(UA_Server *server,
103806 UA_DiscoveryManager *dm,
103807 UA_LifecycleState state) {
103808 /* Check if open connections remain */
103809 if(state == UA_LIFECYCLESTATE_STOPPING ||
103810 state == UA_LIFECYCLESTATE_STOPPED) {
103811 state = UA_LIFECYCLESTATE_STOPPED;
103812#ifdef UA_ENABLE_DISCOVERY_MULTICAST
103813 if(dm->mdnsRecvConnectionsSize != 0 || dm->mdnsSendConnection != 0)
103814 state = UA_LIFECYCLESTATE_STOPPING;
103815#endif
103816
103817 for(size_t i = 0; i < UA_MAXREGISTERREQUESTS; i++) {
103818 if(dm->registerRequests[i].client != NULL)
103819 state = UA_LIFECYCLESTATE_STOPPING;
103820 }
103821 }
103822
103823 /* No change */
103824 if(state == dm->sc.state)
103825 return;
103826
103827 /* Set the new state and notify */
103828 dm->sc.state = state;
103829 if(dm->sc.notifyState)
103830 dm->sc.notifyState(server, &dm->sc, state);
103831}
103832
103833static UA_StatusCode
103834UA_DiscoveryManager_free(UA_Server *server,
103835 struct UA_ServerComponent *sc) {
103836 UA_DiscoveryManager *dm = (UA_DiscoveryManager*)sc;
103837
103838 if(sc->state != UA_LIFECYCLESTATE_STOPPED) {
103839 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
103840 msg: "Cannot delete the DiscoveryManager because "
103841 "it is not stopped");
103842 return UA_STATUSCODE_BADINTERNALERROR;
103843 }
103844
103845 registeredServer_list_entry *rs, *rs_tmp;
103846 LIST_FOREACH_SAFE(rs, &dm->registeredServers, pointers, rs_tmp) {
103847 LIST_REMOVE(rs, pointers);
103848 UA_RegisteredServer_clear(p: &rs->registeredServer);
103849 UA_free(ptr: rs);
103850 }
103851
103852# ifdef UA_ENABLE_DISCOVERY_MULTICAST
103853 serverOnNetwork_list_entry *son, *son_tmp;
103854 LIST_FOREACH_SAFE(son, &dm->serverOnNetwork, pointers, son_tmp) {
103855 LIST_REMOVE(son, pointers);
103856 UA_ServerOnNetwork_clear(&son->serverOnNetwork);
103857 if(son->pathTmp)
103858 UA_free(son->pathTmp);
103859 UA_free(son);
103860 }
103861
103862 UA_String_clear(&dm->selfFqdnMdnsRecord);
103863
103864 for(size_t i = 0; i < SERVER_ON_NETWORK_HASH_SIZE; i++) {
103865 serverOnNetwork_hash_entry* currHash = dm->serverOnNetworkHash[i];
103866 while(currHash) {
103867 serverOnNetwork_hash_entry* nextHash = currHash->next;
103868 UA_free(currHash);
103869 currHash = nextHash;
103870 }
103871 }
103872# endif /* UA_ENABLE_DISCOVERY_MULTICAST */
103873
103874 UA_free(ptr: dm);
103875 return UA_STATUSCODE_GOOD;
103876}
103877
103878/* Cleanup server registration: If the semaphore file path is set, then it just
103879 * checks the existence of the file. When it is deleted, the registration is
103880 * removed. If there is no semaphore file, then the registration will be removed
103881 * if it is older than 60 minutes. */
103882static void
103883UA_DiscoveryManager_cleanupTimedOut(UA_Server *server,
103884 void *data) {
103885 UA_DiscoveryManager *dm = (UA_DiscoveryManager*)data;
103886
103887 /* TimedOut gives the last DateTime at which we must have seen the
103888 * registered server. Otherwise it is timed out. */
103889 UA_DateTime timedOut = UA_DateTime_nowMonotonic();
103890 if(server->config.discoveryCleanupTimeout)
103891 timedOut -= server->config.discoveryCleanupTimeout * UA_DATETIME_SEC;
103892
103893 registeredServer_list_entry *current, *temp;
103894 LIST_FOREACH_SAFE(current, &dm->registeredServers, pointers, temp) {
103895 UA_Boolean semaphoreDeleted = false;
103896
103897#ifdef UA_ENABLE_DISCOVERY_SEMAPHORE
103898 if(current->registeredServer.semaphoreFilePath.length) {
103899 size_t fpSize = current->registeredServer.semaphoreFilePath.length+1;
103900 char* filePath = (char *)UA_malloc(size: fpSize);
103901 if(filePath) {
103902 memcpy(dest: filePath, src: current->registeredServer.semaphoreFilePath.data,
103903 n: current->registeredServer.semaphoreFilePath.length );
103904 filePath[current->registeredServer.semaphoreFilePath.length] = '\0';
103905 semaphoreDeleted = UA_fileExists(filePath) == false;
103906 UA_free(ptr: filePath);
103907 } else {
103908 UA_LOG_ERROR(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
103909 msg: "Cannot check registration semaphore. Out of memory");
103910 }
103911 }
103912#endif
103913
103914 if(semaphoreDeleted ||
103915 (server->config.discoveryCleanupTimeout &&
103916 current->lastSeen < timedOut)) {
103917 if(semaphoreDeleted) {
103918 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
103919 msg: "Registration of server with URI %.*s is removed because "
103920 "the semaphore file '%.*s' was deleted",
103921 (int)current->registeredServer.serverUri.length,
103922 current->registeredServer.serverUri.data,
103923 (int)current->registeredServer.semaphoreFilePath.length,
103924 current->registeredServer.semaphoreFilePath.data);
103925 } else {
103926 // cppcheck-suppress unreadVariable
103927 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
103928 msg: "Registration of server with URI %.*s has timed out "
103929 "and is removed",
103930 (int)current->registeredServer.serverUri.length,
103931 current->registeredServer.serverUri.data);
103932 }
103933 LIST_REMOVE(current, pointers);
103934 UA_RegisteredServer_clear(p: &current->registeredServer);
103935 UA_free(ptr: current);
103936 dm->registeredServersSize--;
103937 }
103938 }
103939
103940#ifdef UA_ENABLE_DISCOVERY_MULTICAST
103941 /* Send out multicast */
103942 sendMulticastMessages(dm);
103943#endif
103944}
103945
103946static UA_StatusCode
103947UA_DiscoveryManager_start(UA_Server *server,
103948 struct UA_ServerComponent *sc) {
103949 if(sc->state != UA_LIFECYCLESTATE_STOPPED)
103950 return UA_STATUSCODE_BADINTERNALERROR;
103951
103952 UA_DiscoveryManager *dm = (UA_DiscoveryManager*)sc;
103953 UA_StatusCode res = addRepeatedCallback(server, callback: UA_DiscoveryManager_cleanupTimedOut,
103954 data: dm, interval_ms: 1000.0, callbackId: &dm->discoveryCallbackId);
103955 if(res != UA_STATUSCODE_GOOD)
103956 return res;
103957
103958 dm->logging = server->config.logging;
103959 dm->serverConfig = &server->config;
103960
103961#ifdef UA_ENABLE_DISCOVERY_MULTICAST
103962 if(server->config.mdnsEnabled)
103963 startMulticastDiscoveryServer(server);
103964#endif
103965
103966 UA_DiscoveryManager_setState(server, dm, state: UA_LIFECYCLESTATE_STARTED);
103967 return UA_STATUSCODE_GOOD;
103968}
103969
103970static void
103971UA_DiscoveryManager_stop(UA_Server *server,
103972 struct UA_ServerComponent *sc) {
103973 if(sc->state != UA_LIFECYCLESTATE_STARTED)
103974 return;
103975
103976 UA_DiscoveryManager *dm = (UA_DiscoveryManager*)sc;
103977 removeCallback(server, callbackId: dm->discoveryCallbackId);
103978
103979 /* Cancel all outstanding register requests */
103980 for(size_t i = 0; i < UA_MAXREGISTERREQUESTS; i++) {
103981 if(dm->registerRequests[i].client == NULL)
103982 continue;
103983 UA_Client_disconnectSecureChannelAsync(client: dm->registerRequests[i].client);
103984 }
103985
103986#ifdef UA_ENABLE_DISCOVERY_MULTICAST
103987 if(server->config.mdnsEnabled)
103988 stopMulticastDiscoveryServer(server);
103989#endif
103990
103991 UA_DiscoveryManager_setState(server, dm, state: UA_LIFECYCLESTATE_STOPPED);
103992}
103993
103994UA_ServerComponent *
103995UA_DiscoveryManager_new(UA_Server *server) {
103996 UA_DiscoveryManager *dm = (UA_DiscoveryManager*)
103997 UA_calloc(nmemb: 1, size: sizeof(UA_DiscoveryManager));
103998 if(!dm)
103999 return NULL;
104000
104001#ifdef UA_ENABLE_DISCOVERY_MULTICAST
104002 dm->serverOnNetworkRecordIdLastReset = UA_DateTime_now();
104003#endif /* UA_ENABLE_DISCOVERY_MULTICAST */
104004
104005 dm->sc.name = UA_STRING(chars: "discovery");
104006 dm->sc.start = UA_DiscoveryManager_start;
104007 dm->sc.stop = UA_DiscoveryManager_stop;
104008 dm->sc.free = UA_DiscoveryManager_free;
104009 return &dm->sc;
104010}
104011
104012/********************************/
104013/* Register at Discovery Server */
104014/********************************/
104015
104016static void
104017asyncRegisterRequest_clear(void *app, void *context) {
104018 UA_Server *server = (UA_Server*)app;
104019 asyncRegisterRequest *ar = (asyncRegisterRequest*)context;
104020 UA_DiscoveryManager *dm = ar->dm;
104021
104022 UA_String_clear(p: &ar->semaphoreFilePath);
104023 if(ar->client)
104024 UA_Client_delete(client: ar->client);
104025 memset(s: ar, c: 0, n: sizeof(asyncRegisterRequest));
104026
104027 /* The Discovery manager is fully stopped? */
104028 UA_DiscoveryManager_setState(server, dm, state: dm->sc.state);
104029}
104030
104031static void
104032asyncRegisterRequest_clearAsync(asyncRegisterRequest *ar) {
104033 UA_Server *server = ar->server;
104034 UA_ServerConfig *sc = &server->config;
104035 UA_EventLoop *el = sc->eventLoop;
104036
104037 ar->cleanupCallback.callback = asyncRegisterRequest_clear;
104038 ar->cleanupCallback.application = server;
104039 ar->cleanupCallback.context = ar;
104040 el->addDelayedCallback(el, &ar->cleanupCallback);
104041}
104042
104043static void
104044setupRegisterRequest(asyncRegisterRequest *ar, UA_RequestHeader *rh,
104045 UA_RegisteredServer *rs) {
104046 UA_ServerConfig *sc = ar->dm->serverConfig;
104047
104048 rh->timeoutHint = 10000;
104049
104050 rs->isOnline = !ar->unregister;
104051 rs->serverUri = sc->applicationDescription.applicationUri;
104052 rs->productUri = sc->applicationDescription.productUri;
104053 rs->serverType = sc->applicationDescription.applicationType;
104054 rs->gatewayServerUri = sc->applicationDescription.gatewayServerUri;
104055 rs->semaphoreFilePath = ar->semaphoreFilePath;
104056
104057 rs->serverNames = &sc->applicationDescription.applicationName;
104058 rs->serverNamesSize = 1;
104059
104060 /* Mirror the discovery URLs from the server config (includes hostnames from
104061 * the network layers) */
104062 rs->discoveryUrls = sc->applicationDescription.discoveryUrls;
104063 rs->discoveryUrlsSize = sc->applicationDescription.discoveryUrlsSize;
104064}
104065
104066static void
104067registerAsyncResponse(UA_Client *client, void *userdata,
104068 UA_UInt32 requestId, void *resp) {
104069 asyncRegisterRequest *ar = (asyncRegisterRequest*)userdata;
104070 const UA_ServerConfig *sc = ar->dm->serverConfig;
104071 UA_Response *response = (UA_Response*)resp;
104072 const char *regtype = (ar->register2) ? "RegisterServer2" : "RegisterServer";
104073
104074 /* Success registering? */
104075 if(response->responseHeader.serviceResult == UA_STATUSCODE_GOOD) {
104076 UA_LOG_INFO(logger: sc->logging, category: UA_LOGCATEGORY_SERVER, msg: "%s succeeded", regtype);
104077 goto done;
104078 }
104079
104080 UA_LOG_WARNING(logger: sc->logging, category: UA_LOGCATEGORY_SERVER,
104081 msg: "%s failed with statuscode %s", regtype,
104082 UA_StatusCode_name(code: response->responseHeader.serviceResult));
104083
104084 /* Try RegisterServer next */
104085 ar->register2 = false;
104086
104087 /* Try RegisterServer immediately if we can.
104088 * Otherwise wait for the next state callback. */
104089 UA_SecureChannelState ss;
104090 UA_Client_getState(client, channelState: &ss, NULL, NULL);
104091 if(!ar->shutdown && ss == UA_SECURECHANNELSTATE_OPEN) {
104092 UA_RegisterServerRequest request;
104093 UA_RegisterServerRequest_init(p: &request);
104094 setupRegisterRequest(ar, rh: &request.requestHeader, rs: &request.server);
104095 UA_StatusCode res =
104096 __UA_Client_AsyncService(client, request: &request,
104097 requestType: &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST],
104098 callback: registerAsyncResponse,
104099 responseType: &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE], userdata: ar, NULL);
104100 if(res != UA_STATUSCODE_GOOD) {
104101 UA_LOG_ERROR(logger: (const UA_Logger *)&sc->logging, category: UA_LOGCATEGORY_CLIENT,
104102 msg: "RegisterServer failed with statuscode %s",
104103 UA_StatusCode_name(code: res));
104104 goto done;
104105 }
104106 }
104107
104108 return;
104109
104110 done:
104111 /* Close the client connection, will be cleaned up in the client state
104112 * callback when closing is complete */
104113 ar->shutdown = true;
104114 UA_Client_disconnectSecureChannelAsync(client: ar->client);
104115}
104116
104117static void
104118discoveryClientStateCallback(UA_Client *client,
104119 UA_SecureChannelState channelState,
104120 UA_SessionState sessionState,
104121 UA_StatusCode connectStatus) {
104122 asyncRegisterRequest *ar = (asyncRegisterRequest*)
104123 UA_Client_getContext(client);
104124 UA_ServerConfig *sc = ar->dm->serverConfig;
104125
104126 /* Connection failed */
104127 if(connectStatus != UA_STATUSCODE_GOOD) {
104128 if(connectStatus != UA_STATUSCODE_BADCONNECTIONCLOSED) {
104129 UA_LOG_ERROR(logger: sc->logging, category: UA_LOGCATEGORY_SERVER,
104130 msg: "Could not connect to the Discovery server with error %s",
104131 UA_StatusCode_name(code: connectStatus));
104132 }
104133
104134 /* Connection fully closed */
104135 if(channelState == UA_SECURECHANNELSTATE_CLOSED) {
104136 if(!ar->connectSuccess || ar->shutdown) {
104137 asyncRegisterRequest_clearAsync(ar); /* Clean up */
104138 } else {
104139 ar->connectSuccess = false;
104140 __UA_Client_connect(client, true); /* Reconnect */
104141 }
104142 }
104143 return;
104144 }
104145
104146 /* Wait until the SecureChannel is open */
104147 if(channelState != UA_SECURECHANNELSTATE_OPEN)
104148 return;
104149
104150 /* We have at least succeeded to connect */
104151 ar->connectSuccess = true;
104152
104153 /* Is this the encrypted SecureChannel already? (We might have to wait for
104154 * the second connection after the FindServers handshake */
104155 UA_MessageSecurityMode msm = UA_MESSAGESECURITYMODE_INVALID;
104156 UA_Client_getConnectionAttribute_scalar(client, key: UA_QUALIFIEDNAME(nsIndex: 0, chars: "securityMode"),
104157 type: &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE],
104158 outValue: &msm);
104159#ifdef UA_ENABLE_ENCRYPTION
104160 if(msm != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
104161 return;
104162#endif
104163
104164 const UA_DataType *reqType;
104165 const UA_DataType *respType;
104166 UA_RegisterServerRequest reg1;
104167 UA_RegisterServer2Request reg2;
104168#ifdef UA_ENABLE_DISCOVERY_MULTICAST
104169 UA_ExtensionObject mdnsConfig;
104170#endif
104171 void *request;
104172
104173 /* Prepare the request. This does not allocate memory */
104174 if(ar->register2) {
104175 UA_RegisterServer2Request_init(p: &reg2);
104176 setupRegisterRequest(ar, rh: &reg2.requestHeader, rs: &reg2.server);
104177 reqType = &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST];
104178 respType = &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE];
104179 request = &reg2;
104180
104181#ifdef UA_ENABLE_DISCOVERY_MULTICAST
104182 /* Set the configuration that is only available for
104183 * UA_RegisterServer2Request */
104184 UA_ExtensionObject_setValueNoDelete(&mdnsConfig, &sc->mdnsConfig,
104185 &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION]);
104186 reg2.discoveryConfigurationSize = 1;
104187 reg2.discoveryConfiguration = &mdnsConfig;
104188#endif
104189 } else {
104190 UA_RegisterServerRequest_init(p: &reg1);
104191 setupRegisterRequest(ar, rh: &reg1.requestHeader, rs: &reg1.server);
104192 reqType = &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST];
104193 respType = &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE];
104194 request = &reg1;
104195 }
104196
104197 /* Try to call RegisterServer2 */
104198 UA_StatusCode res =
104199 __UA_Client_AsyncService(client, request, requestType: reqType, callback: registerAsyncResponse,
104200 responseType: respType, userdata: ar, NULL);
104201 if(res != UA_STATUSCODE_GOOD) {
104202 /* Close the client connection, will be cleaned up in the client state
104203 * callback when closing is complete */
104204 UA_Client_disconnectSecureChannelAsync(client: ar->client);
104205 UA_LOG_ERROR(logger: sc->logging, category: UA_LOGCATEGORY_CLIENT,
104206 msg: "RegisterServer2 failed with statuscode %s",
104207 UA_StatusCode_name(code: res));
104208 }
104209}
104210
104211static UA_StatusCode
104212UA_Server_register(UA_Server *server, UA_ClientConfig *cc, UA_Boolean unregister,
104213 const UA_String discoveryServerUrl,
104214 const UA_String semaphoreFilePath) {
104215 /* Get the discovery manager */
104216 UA_DiscoveryManager *dm = (UA_DiscoveryManager*)
104217 getServerComponentByName(server, name: UA_STRING(chars: "discovery"));
104218 if(!dm) {
104219 UA_ClientConfig_clear(config: cc);
104220 return UA_STATUSCODE_BADINTERNALERROR;
104221 }
104222
104223 /* Check that the discovery manager is running */
104224 UA_ServerConfig *sc = &server->config;
104225 if(dm->sc.state != UA_LIFECYCLESTATE_STARTED) {
104226 UA_LOG_ERROR(logger: sc->logging, category: UA_LOGCATEGORY_SERVER,
104227 msg: "The server must be started for registering");
104228 UA_ClientConfig_clear(config: cc);
104229 return UA_STATUSCODE_BADINTERNALERROR;
104230 }
104231
104232 /* Find a free slot for storing the async request information */
104233 asyncRegisterRequest *ar = NULL;
104234 for(size_t i = 0; i < UA_MAXREGISTERREQUESTS; i++) {
104235 if(dm->registerRequests[i].client == NULL) {
104236 ar = &dm->registerRequests[i];
104237 break;
104238 }
104239 }
104240 if(!ar) {
104241 UA_LOG_ERROR(logger: sc->logging, category: UA_LOGCATEGORY_SERVER,
104242 msg: "Too many outstanding register requests. Cannot proceed.");
104243 UA_ClientConfig_clear(config: cc);
104244 return UA_STATUSCODE_BADINTERNALERROR;
104245 }
104246
104247 /* Use the EventLoop from the server for the client */
104248 if(cc->eventLoop && !cc->externalEventLoop)
104249 cc->eventLoop->free(cc->eventLoop);
104250 cc->eventLoop = sc->eventLoop;
104251 cc->externalEventLoop = true;
104252
104253 /* Set the state callback method and context */
104254 cc->stateCallback = discoveryClientStateCallback;
104255 cc->clientContext = ar;
104256
104257 /* Use encryption by default */
104258#ifdef UA_ENABLE_ENCRYPTION
104259 cc->securityMode = UA_MESSAGESECURITYMODE_SIGNANDENCRYPT;
104260#endif
104261
104262 /* Open only a SecureChannel */
104263 cc->noSession = true;
104264
104265 /* Move the endpoint url */
104266 UA_String_clear(p: &cc->endpointUrl);
104267 UA_String_copy(src: &discoveryServerUrl, dst: &cc->endpointUrl);
104268
104269 /* Instantiate the client */
104270 ar->client = UA_Client_newWithConfig(config: cc);
104271 if(!ar->client) {
104272 UA_ClientConfig_clear(config: cc);
104273 return UA_STATUSCODE_BADOUTOFMEMORY;
104274 }
104275
104276 /* Zero out the supplied config */
104277 memset(s: cc, c: 0, n: sizeof(UA_ClientConfig));
104278
104279 /* Finish setting up the context */
104280 ar->server = server;
104281 ar->dm = dm;
104282 ar->unregister = unregister;
104283 ar->register2 = true; /* Try register2 first */
104284 UA_String_copy(src: &semaphoreFilePath, dst: &ar->semaphoreFilePath);
104285
104286 /* Connect asynchronously. The register service is called once the
104287 * connection is open. */
104288 ar->connectSuccess = false;
104289 return __UA_Client_connect(client: ar->client, true);
104290}
104291
104292UA_StatusCode
104293UA_Server_registerDiscovery(UA_Server *server, UA_ClientConfig *cc,
104294 const UA_String discoveryServerUrl,
104295 const UA_String semaphoreFilePath) {
104296 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
104297 msg: "Registering at the DiscoveryServer: %.*s",
104298 (int)discoveryServerUrl.length, discoveryServerUrl.data);
104299 lockServer(server);
104300 UA_StatusCode res =
104301 UA_Server_register(server, cc, false, discoveryServerUrl, semaphoreFilePath);
104302 unlockServer(server);
104303 return res;
104304}
104305
104306UA_StatusCode
104307UA_Server_deregisterDiscovery(UA_Server *server, UA_ClientConfig *cc,
104308 const UA_String discoveryServerUrl) {
104309 UA_LOG_INFO(logger: server->config.logging, category: UA_LOGCATEGORY_SERVER,
104310 msg: "Deregistering at the DiscoveryServer: %.*s",
104311 (int)discoveryServerUrl.length, discoveryServerUrl.data);
104312 lockServer(server);
104313 UA_StatusCode res =
104314 UA_Server_register(server, cc, true, discoveryServerUrl, semaphoreFilePath: UA_STRING_NULL);
104315 unlockServer(server);
104316 return res;
104317}
104318
104319#endif /* UA_ENABLE_DISCOVERY */
104320
104321/**** amalgamated original file "/plugins/crypto/mbedtls/securitypolicy_mbedtls_common.h" ****/
104322
104323/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
104324 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
104325 *
104326 * Copyright 2019 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
104327 */
104328
104329
104330
104331#if defined(UA_ENABLE_ENCRYPTION_MBEDTLS) || defined(UA_ENABLE_PUBSUB_ENCRYPTION)
104332
104333#include <mbedtls/md.h>
104334#include <mbedtls/x509_crt.h>
104335#include <mbedtls/ctr_drbg.h>
104336
104337// MBEDTLS_ENTROPY_HARDWARE_ALT should be defined if your hardware does not supportd platform entropy
104338
104339#define UA_SHA1_LENGTH 20
104340
104341_UA_BEGIN_DECLS
104342
104343void
104344swapBuffers(UA_ByteString *const bufA, UA_ByteString *const bufB);
104345
104346void
104347mbedtls_hmac(mbedtls_md_context_t *context, const UA_ByteString *key,
104348 const UA_ByteString *in, unsigned char *out);
104349
104350UA_StatusCode
104351mbedtls_generateKey(mbedtls_md_context_t *context,
104352 const UA_ByteString *secret, const UA_ByteString *seed,
104353 UA_ByteString *out);
104354
104355UA_StatusCode
104356mbedtls_verifySig_sha1(mbedtls_x509_crt *certificate, const UA_ByteString *message,
104357 const UA_ByteString *signature);
104358
104359UA_StatusCode
104360mbedtls_sign_sha1(mbedtls_pk_context *localPrivateKey,
104361 mbedtls_ctr_drbg_context *drbgContext,
104362 const UA_ByteString *message,
104363 UA_ByteString *signature);
104364
104365UA_StatusCode
104366mbedtls_thumbprint_sha1(const UA_ByteString *certificate,
104367 UA_ByteString *thumbprint);
104368
104369/* Set the hashing scheme before calling
104370 * E.g. mbedtls_rsa_set_padding(context, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1); */
104371UA_StatusCode
104372mbedtls_encrypt_rsaOaep(mbedtls_rsa_context *context,
104373 mbedtls_ctr_drbg_context *drbgContext,
104374 UA_ByteString *data, const size_t plainTextBlockSize);
104375
104376UA_StatusCode
104377mbedtls_decrypt_rsaOaep(mbedtls_pk_context *localPrivateKey,
104378 mbedtls_ctr_drbg_context *drbgContext,
104379 UA_ByteString *data, int hash_id);
104380
104381int UA_mbedTLS_LoadPrivateKey(const UA_ByteString *key, mbedtls_pk_context *target, void *p_rng);
104382
104383UA_StatusCode UA_mbedTLS_LoadLocalCertificate(const UA_ByteString *certData, UA_ByteString *target);
104384
104385UA_ByteString UA_mbedTLS_CopyDataFormatAware(const UA_ByteString *data);
104386
104387_UA_END_DECLS
104388
104389#endif
104390
104391
104392/**** amalgamated original file "/plugins/crypto/mbedtls/securitypolicy_mbedtls_common.c" ****/
104393
104394
104395#if defined(UA_ENABLE_ENCRYPTION_MBEDTLS) || defined(UA_ENABLE_PUBSUB_ENCRYPTION)
104396
104397
104398#include <mbedtls/aes.h>
104399#include <mbedtls/ctr_drbg.h>
104400#include <mbedtls/entropy.h>
104401#include <mbedtls/error.h>
104402#include <mbedtls/md.h>
104403#include <mbedtls/sha1.h>
104404#include <mbedtls/version.h>
104405#include <mbedtls/x509_crt.h>
104406
104407void
104408swapBuffers(UA_ByteString *const bufA, UA_ByteString *const bufB) {
104409 UA_ByteString tmp = *bufA;
104410 *bufA = *bufB;
104411 *bufB = tmp;
104412}
104413
104414void
104415mbedtls_hmac(mbedtls_md_context_t *context, const UA_ByteString *key,
104416 const UA_ByteString *in, unsigned char *out) {
104417 mbedtls_md_hmac_starts(context, key->data, key->length);
104418 mbedtls_md_hmac_update(context, in->data, in->length);
104419 mbedtls_md_hmac_finish(context, out);
104420}
104421
104422UA_StatusCode
104423mbedtls_generateKey(mbedtls_md_context_t *context,
104424 const UA_ByteString *secret, const UA_ByteString *seed,
104425 UA_ByteString *out) {
104426#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
104427 size_t hashLen = (size_t)mbedtls_md_get_size(context->md_info);
104428#else
104429 size_t hashLen = (size_t)mbedtls_md_get_size(context->private_md_info);
104430#endif
104431
104432 UA_ByteString A_and_seed;
104433 UA_ByteString_allocBuffer(&A_and_seed, hashLen + seed->length);
104434 memcpy(A_and_seed.data + hashLen, seed->data, seed->length);
104435
104436 UA_ByteString ANext_and_seed;
104437 UA_ByteString_allocBuffer(&ANext_and_seed, hashLen + seed->length);
104438 memcpy(ANext_and_seed.data + hashLen, seed->data, seed->length);
104439
104440 UA_ByteString A = {
104441 hashLen,
104442 A_and_seed.data
104443 };
104444
104445 UA_ByteString ANext = {
104446 hashLen,
104447 ANext_and_seed.data
104448 };
104449
104450 mbedtls_hmac(context, secret, seed, A.data);
104451
104452 UA_StatusCode retval = 0;
104453 for(size_t offset = 0; offset < out->length; offset += hashLen) {
104454 UA_ByteString outSegment = {
104455 hashLen,
104456 out->data + offset
104457 };
104458 UA_Boolean bufferAllocated = UA_FALSE;
104459 // Not enough room in out buffer to write the hash.
104460 if(offset + hashLen > out->length) {
104461 outSegment.data = NULL;
104462 outSegment.length = 0;
104463 retval = UA_ByteString_allocBuffer(&outSegment, hashLen);
104464 if(retval != UA_STATUSCODE_GOOD) {
104465 UA_ByteString_clear(&A_and_seed);
104466 UA_ByteString_clear(&ANext_and_seed);
104467 return retval;
104468 }
104469 bufferAllocated = UA_TRUE;
104470 }
104471
104472 mbedtls_hmac(context, secret, &A_and_seed, outSegment.data);
104473 mbedtls_hmac(context, secret, &A, ANext.data);
104474
104475 if(retval != UA_STATUSCODE_GOOD) {
104476 if(bufferAllocated)
104477 UA_ByteString_clear(&outSegment);
104478 UA_ByteString_clear(&A_and_seed);
104479 UA_ByteString_clear(&ANext_and_seed);
104480 return retval;
104481 }
104482
104483 if(bufferAllocated) {
104484 memcpy(out->data + offset, outSegment.data, out->length - offset);
104485 UA_ByteString_clear(&outSegment);
104486 }
104487
104488 swapBuffers(&ANext_and_seed, &A_and_seed);
104489 swapBuffers(&ANext, &A);
104490 }
104491
104492 UA_ByteString_clear(&A_and_seed);
104493 UA_ByteString_clear(&ANext_and_seed);
104494 return UA_STATUSCODE_GOOD;
104495}
104496
104497UA_StatusCode
104498mbedtls_verifySig_sha1(mbedtls_x509_crt *certificate, const UA_ByteString *message,
104499 const UA_ByteString *signature) {
104500 /* Compute the sha1 hash */
104501 unsigned char hash[UA_SHA1_LENGTH];
104502#if MBEDTLS_VERSION_NUMBER >= 0x02070000 && MBEDTLS_VERSION_NUMBER < 0x03000000
104503 mbedtls_sha1_ret(message->data, message->length, hash);
104504#else
104505 mbedtls_sha1(message->data, message->length, hash);
104506#endif
104507
104508 /* Set the RSA settings */
104509 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(certificate->pk);
104510 if(!rsaContext)
104511 return UA_STATUSCODE_BADINTERNALERROR;
104512 mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE);
104513
104514 /* Verify */
104515 int mbedErr = mbedtls_pk_verify(&certificate->pk,
104516 MBEDTLS_MD_SHA1, hash, UA_SHA1_LENGTH,
104517 signature->data, signature->length);
104518 if(mbedErr)
104519 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
104520 return UA_STATUSCODE_GOOD;
104521}
104522
104523UA_StatusCode
104524mbedtls_sign_sha1(mbedtls_pk_context *localPrivateKey,
104525 mbedtls_ctr_drbg_context *drbgContext,
104526 const UA_ByteString *message,
104527 UA_ByteString *signature) {
104528 unsigned char hash[UA_SHA1_LENGTH];
104529#if MBEDTLS_VERSION_NUMBER >= 0x02070000 && MBEDTLS_VERSION_NUMBER < 0x03000000
104530 mbedtls_sha1_ret(message->data, message->length, hash);
104531#else
104532 mbedtls_sha1(message->data, message->length, hash);
104533#endif
104534
104535 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(*localPrivateKey);
104536 mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE);
104537
104538 size_t sigLen = 0;
104539 int mbedErr = mbedtls_pk_sign(localPrivateKey, MBEDTLS_MD_SHA1, hash,
104540 UA_SHA1_LENGTH, signature->data,
104541#if MBEDTLS_VERSION_NUMBER >= 0x03000000
104542 signature->length,
104543#endif
104544 &sigLen,
104545 mbedtls_ctr_drbg_random, drbgContext);
104546 if(mbedErr)
104547 return UA_STATUSCODE_BADINTERNALERROR;
104548 return UA_STATUSCODE_GOOD;
104549}
104550
104551UA_StatusCode
104552mbedtls_thumbprint_sha1(const UA_ByteString *certificate,
104553 UA_ByteString *thumbprint) {
104554 if(UA_ByteString_equal(certificate, &UA_BYTESTRING_NULL))
104555 return UA_STATUSCODE_BADINTERNALERROR;
104556
104557 if(thumbprint->length != UA_SHA1_LENGTH)
104558 return UA_STATUSCODE_BADINTERNALERROR;
104559
104560 /* The certificate thumbprint is always a 20 bit sha1 hash, see Part 4 of the Specification. */
104561#if MBEDTLS_VERSION_NUMBER >= 0x02070000 && MBEDTLS_VERSION_NUMBER < 0x03000000
104562 mbedtls_sha1_ret(certificate->data, certificate->length, thumbprint->data);
104563#else
104564 mbedtls_sha1(certificate->data, certificate->length, thumbprint->data);
104565#endif
104566 return UA_STATUSCODE_GOOD;
104567}
104568
104569UA_StatusCode
104570mbedtls_encrypt_rsaOaep(mbedtls_rsa_context *context,
104571 mbedtls_ctr_drbg_context *drbgContext,
104572 UA_ByteString *data, const size_t plainTextBlockSize) {
104573 if(data->length % plainTextBlockSize != 0)
104574 return UA_STATUSCODE_BADINTERNALERROR;
104575
104576 size_t max_blocks = data->length / plainTextBlockSize;
104577#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
104578 size_t keylen = context->len;
104579#else
104580 size_t keylen = mbedtls_rsa_get_len(context);
104581#endif
104582
104583 UA_ByteString encrypted;
104584 UA_StatusCode retval = UA_ByteString_allocBuffer(&encrypted, max_blocks * keylen);
104585 if(retval != UA_STATUSCODE_GOOD)
104586 return retval;
104587
104588 size_t lenDataToEncrypt = data->length;
104589 size_t inOffset = 0;
104590 size_t offset = 0;
104591 const unsigned char *label = NULL;
104592 while(lenDataToEncrypt >= plainTextBlockSize) {
104593#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
104594 int mbedErr = mbedtls_rsa_rsaes_oaep_encrypt(context, mbedtls_ctr_drbg_random,
104595 drbgContext, MBEDTLS_RSA_PUBLIC,
104596 label, 0, plainTextBlockSize,
104597 data->data + inOffset, encrypted.data + offset);
104598#else
104599 int mbedErr = mbedtls_rsa_rsaes_oaep_encrypt(context, mbedtls_ctr_drbg_random,
104600 drbgContext, label, 0, plainTextBlockSize,
104601 data->data + inOffset, encrypted.data + offset);
104602#endif
104603
104604 if(mbedErr) {
104605 UA_ByteString_clear(&encrypted);
104606 return UA_STATUSCODE_BADINTERNALERROR;
104607 }
104608
104609 inOffset += plainTextBlockSize;
104610 offset += keylen;
104611 lenDataToEncrypt -= plainTextBlockSize;
104612 }
104613
104614 memcpy(data->data, encrypted.data, offset);
104615 UA_ByteString_clear(&encrypted);
104616 return UA_STATUSCODE_GOOD;
104617}
104618
104619UA_StatusCode
104620mbedtls_decrypt_rsaOaep(mbedtls_pk_context *localPrivateKey,
104621 mbedtls_ctr_drbg_context *drbgContext,
104622 UA_ByteString *data, int hash_id) {
104623 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(*localPrivateKey);
104624#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
104625 mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V21, hash_id);
104626 size_t keylen = rsaContext->len;
104627#else
104628 mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V21, (mbedtls_md_type_t)hash_id);
104629 size_t keylen = mbedtls_rsa_get_len(rsaContext);
104630#endif
104631 if(data->length % keylen != 0)
104632 return UA_STATUSCODE_BADINTERNALERROR;
104633
104634 size_t inOffset = 0;
104635 size_t outOffset = 0;
104636 size_t outLength = 0;
104637 unsigned char buf[512];
104638
104639 while(inOffset < data->length) {
104640#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
104641 int mbedErr = mbedtls_rsa_rsaes_oaep_decrypt(rsaContext, mbedtls_ctr_drbg_random,
104642 drbgContext, MBEDTLS_RSA_PRIVATE,
104643 NULL, 0, &outLength,
104644 data->data + inOffset,
104645 buf, 512);
104646#else
104647 int mbedErr = mbedtls_rsa_rsaes_oaep_decrypt(rsaContext, mbedtls_ctr_drbg_random,
104648 drbgContext,
104649 NULL, 0, &outLength,
104650 data->data + inOffset,
104651 buf, 512);
104652#endif
104653
104654 if(mbedErr)
104655 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
104656
104657 memcpy(data->data + outOffset, buf, outLength);
104658 inOffset += keylen;
104659 outOffset += outLength;
104660 }
104661
104662 data->length = outOffset;
104663 return UA_STATUSCODE_GOOD;
104664}
104665
104666int
104667UA_mbedTLS_LoadPrivateKey(const UA_ByteString *key, mbedtls_pk_context *target, void *p_rng) {
104668 UA_ByteString data = UA_mbedTLS_CopyDataFormatAware(key);
104669#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
104670 int mbedErr = mbedtls_pk_parse_key(target, data.data, data.length, NULL, 0);
104671#else
104672 int mbedErr = mbedtls_pk_parse_key(target, data.data, data.length, NULL, 0, mbedtls_entropy_func, p_rng);
104673#endif
104674 UA_ByteString_clear(&data);
104675 return mbedErr;
104676}
104677
104678UA_StatusCode
104679UA_mbedTLS_LoadLocalCertificate(const UA_ByteString *certData,
104680 UA_ByteString *target) {
104681 UA_ByteString data = UA_mbedTLS_CopyDataFormatAware(certData);
104682
104683 mbedtls_x509_crt cert;
104684 mbedtls_x509_crt_init(&cert);
104685
104686 int mbedErr = mbedtls_x509_crt_parse(&cert, data.data, data.length);
104687
104688 UA_StatusCode result = UA_STATUSCODE_BADINVALIDARGUMENT;
104689
104690 if (!mbedErr) {
104691 UA_ByteString tmp;
104692 tmp.data = cert.raw.p;
104693 tmp.length = cert.raw.len;
104694
104695 result = UA_ByteString_copy(&tmp, target);
104696 } else {
104697 UA_ByteString_init(target);
104698 }
104699
104700 UA_ByteString_clear(&data);
104701 mbedtls_x509_crt_free(&cert);
104702 return result;
104703}
104704
104705// mbedTLS expects PEM data to be null terminated
104706// The data length parameter must include the null terminator
104707UA_ByteString
104708UA_mbedTLS_CopyDataFormatAware(const UA_ByteString *data) {
104709 UA_ByteString result;
104710 UA_ByteString_init(&result);
104711
104712 if (!data->length)
104713 return result;
104714
104715 if (data->length && data->data[0] == '-') {
104716 UA_ByteString_allocBuffer(&result, data->length + 1);
104717 memcpy(result.data, data->data, data->length);
104718 result.data[data->length] = '\0';
104719 } else {
104720 UA_ByteString_copy(data, &result);
104721 }
104722
104723 return result;
104724}
104725
104726#endif
104727
104728/**** amalgamated original file "/plugins/ua_log_stdout.c" ****/
104729
104730/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
104731 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
104732 *
104733 * Copyright 2016-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
104734 * Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA
104735 */
104736
104737
104738#include <stdio.h>
104739
104740/* ANSI escape sequences for color output taken from here:
104741 * https://stackoverflow.com/questions/3219393/stdlib-and-colored-output-in-c*/
104742
104743#ifdef UA_ARCHITECTURE_POSIX
104744# define ANSI_COLOR_RED "\x1b[31m"
104745# define ANSI_COLOR_GREEN "\x1b[32m"
104746# define ANSI_COLOR_YELLOW "\x1b[33m"
104747# define ANSI_COLOR_BLUE "\x1b[34m"
104748# define ANSI_COLOR_MAGENTA "\x1b[35m"
104749# define ANSI_COLOR_CYAN "\x1b[36m"
104750# define ANSI_COLOR_RESET "\x1b[0m"
104751#else
104752# define ANSI_COLOR_RED ""
104753# define ANSI_COLOR_GREEN ""
104754# define ANSI_COLOR_YELLOW ""
104755# define ANSI_COLOR_BLUE ""
104756# define ANSI_COLOR_MAGENTA ""
104757# define ANSI_COLOR_CYAN ""
104758# define ANSI_COLOR_RESET ""
104759#endif
104760
104761static
104762const char *logLevelNames[6] = {"trace", "debug",
104763 ANSI_COLOR_GREEN "info",
104764 ANSI_COLOR_YELLOW "warn",
104765 ANSI_COLOR_RED "error",
104766 ANSI_COLOR_MAGENTA "fatal"};
104767static const char *
104768logCategoryNames[UA_LOGCATEGORIES] =
104769 {"network", "channel", "session", "server", "client",
104770 "userland", "securitypolicy", "eventloop", "pubsub", "discovery"};
104771
104772/* Protect crosstalk during logging via global lock. Use a spinlock as we cannot
104773 * statically initialize a global lock across all platforms. */
104774#if UA_MULTITHREADING >= 100
104775void * volatile logSpinLock = NULL;
104776static UA_INLINE void spinLock(void) {
104777 while(UA_atomic_cmpxchg(&logSpinLock, NULL, (void*)0x1) != NULL) {}
104778}
104779static UA_INLINE void spinUnLock(void) {
104780 UA_atomic_xchg(&logSpinLock, NULL);
104781}
104782#endif
104783
104784#ifdef __clang__
104785__attribute__((__format__(__printf__, 4 , 0)))
104786#endif
104787static void
104788UA_Log_Stdout_log(void *context, UA_LogLevel level, UA_LogCategory category,
104789 const char *msg, va_list args) {
104790 /* MinLevel encoded in the context pointer */
104791 UA_LogLevel minLevel = (UA_LogLevel)(uintptr_t)context;
104792 if(minLevel > level)
104793 return;
104794
104795 UA_Int64 tOffset = UA_DateTime_localTimeUtcOffset();
104796 UA_DateTimeStruct dts = UA_DateTime_toStruct(t: UA_DateTime_now() + tOffset);
104797
104798 int logLevelSlot = ((int)level / 100) - 1;
104799 if(logLevelSlot < 0 || logLevelSlot > 5)
104800 logLevelSlot = 5; /* Set to fatal if the level is outside the range */
104801
104802 /* Lock */
104803#if UA_MULTITHREADING >= 100
104804 spinLock();
104805#endif
104806
104807 /* Log */
104808 printf(format: "[%04u-%02u-%02u %02u:%02u:%02u.%03u (UTC%+05d)] %s/%s" ANSI_COLOR_RESET "\t",
104809 dts.year, dts.month, dts.day, dts.hour, dts.min, dts.sec, dts.milliSec,
104810 (int)(tOffset / UA_DATETIME_SEC / 36), logLevelNames[logLevelSlot],
104811 logCategoryNames[category]);
104812 vprintf(format: msg, arg: args);
104813 printf(format: "\n");
104814 fflush(stdout);
104815
104816 /* Unlock */
104817#if UA_MULTITHREADING >= 100
104818 spinUnLock();
104819#endif
104820}
104821
104822static void
104823UA_Log_Stdout_clear(UA_Logger *logger) {
104824 UA_free(ptr: logger);
104825}
104826
104827const UA_Logger UA_Log_Stdout_ = {UA_Log_Stdout_log, NULL, NULL};
104828const UA_Logger *UA_Log_Stdout = &UA_Log_Stdout_;
104829
104830UA_Logger
104831UA_Log_Stdout_withLevel(UA_LogLevel minlevel) {
104832 UA_Logger logger =
104833 {UA_Log_Stdout_log, (void*)(uintptr_t)minlevel, NULL};
104834 return logger;
104835}
104836
104837UA_Logger *
104838UA_Log_Stdout_new(UA_LogLevel minlevel) {
104839 UA_Logger *logger = (UA_Logger*)UA_malloc(size: sizeof(UA_Logger));
104840 if(!logger)
104841 return NULL;
104842 *logger = UA_Log_Stdout_withLevel(minlevel);
104843 logger->clear = UA_Log_Stdout_clear;
104844 return logger;
104845}
104846
104847/**** amalgamated original file "/plugins/ua_accesscontrol_default.c" ****/
104848
104849/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
104850 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
104851 *
104852 * Copyright 2016-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
104853 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
104854 * Copyright 2019 (c) HMS Industrial Networks AB (Author: Jonas Green)
104855 */
104856
104857
104858/* Example access control management. Anonymous and username / password login.
104859 * The access rights are maximally permissive.
104860 *
104861 * FOR PRODUCTION USE, THIS EXAMPLE PLUGIN SHOULD BE REPLACED WITH LESS
104862 * PERMISSIVE ACCESS CONTROL.
104863 *
104864 * For TransferSubscriptions, we check whether the transfer happens between
104865 * Sessions for the same user. */
104866
104867typedef struct {
104868 UA_Boolean allowAnonymous;
104869 size_t usernamePasswordLoginSize;
104870 UA_UsernamePasswordLogin *usernamePasswordLogin;
104871 UA_UsernamePasswordLoginCallback loginCallback;
104872 void *loginContext;
104873 UA_CertificateVerification verifyX509;
104874} AccessControlContext;
104875
104876#define ANONYMOUS_POLICY "open62541-anonymous-policy"
104877#define CERTIFICATE_POLICY "open62541-certificate-policy"
104878#define USERNAME_POLICY "open62541-username-policy"
104879const UA_String anonymous_policy = UA_STRING_STATIC(ANONYMOUS_POLICY);
104880const UA_String certificate_policy = UA_STRING_STATIC(CERTIFICATE_POLICY);
104881const UA_String username_policy = UA_STRING_STATIC(USERNAME_POLICY);
104882
104883/************************/
104884/* Access Control Logic */
104885/************************/
104886
104887static UA_StatusCode
104888activateSession_default(UA_Server *server, UA_AccessControl *ac,
104889 const UA_EndpointDescription *endpointDescription,
104890 const UA_ByteString *secureChannelRemoteCertificate,
104891 const UA_NodeId *sessionId,
104892 const UA_ExtensionObject *userIdentityToken,
104893 void **sessionContext) {
104894 AccessControlContext *context = (AccessControlContext*)ac->context;
104895 UA_ServerConfig *config = UA_Server_getConfig(server);
104896
104897 /* The empty token is interpreted as anonymous */
104898 UA_AnonymousIdentityToken anonToken;
104899 UA_ExtensionObject tmpIdentity;
104900 if(userIdentityToken->encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY) {
104901 UA_AnonymousIdentityToken_init(p: &anonToken);
104902 UA_ExtensionObject_init(p: &tmpIdentity);
104903 UA_ExtensionObject_setValueNoDelete(eo: &tmpIdentity,
104904 p: &anonToken,
104905 type: &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]);
104906 userIdentityToken = &tmpIdentity;
104907 }
104908
104909 /* Could the token be decoded? */
104910 if(userIdentityToken->encoding < UA_EXTENSIONOBJECT_DECODED)
104911 return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
104912
104913 const UA_DataType *tokenType = userIdentityToken->content.decoded.type;
104914 if(tokenType == &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]) {
104915 /* Anonymous login */
104916 if(!context->allowAnonymous)
104917 return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
104918
104919 const UA_AnonymousIdentityToken *token = (UA_AnonymousIdentityToken*)
104920 userIdentityToken->content.decoded.data;
104921
104922 /* Match the beginnig of the PolicyId.
104923 * Compatibility notice: Siemens OPC Scout v10 provides an empty
104924 * policyId. This is not compliant. For compatibility, assume that empty
104925 * policyId == ANONYMOUS_POLICY */
104926 if(token->policyId.data &&
104927 (token->policyId.length < anonymous_policy.length ||
104928 strncmp(s1: (const char*)token->policyId.data,
104929 s2: (const char*)anonymous_policy.data,
104930 n: anonymous_policy.length) != 0)) {
104931 return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
104932 }
104933 } else if(tokenType == &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]) {
104934 /* Username and password */
104935 const UA_UserNameIdentityToken *userToken = (UA_UserNameIdentityToken*)
104936 userIdentityToken->content.decoded.data;
104937
104938 /* Match the beginnig of the PolicyId */
104939 if(userToken->policyId.length < username_policy.length ||
104940 strncmp(s1: (const char*)userToken->policyId.data,
104941 s2: (const char*)username_policy.data,
104942 n: username_policy.length) != 0) {
104943 return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
104944 }
104945
104946 /* The userToken has been decrypted by the server before forwarding
104947 * it to the plugin. This information can be used here. */
104948 /* if(userToken->encryptionAlgorithm.length > 0) {} */
104949
104950 /* Empty username and password */
104951 if(userToken->userName.length == 0 && userToken->password.length == 0)
104952 return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
104953
104954 /* Try to match username/pw */
104955 UA_Boolean match = false;
104956 if(context->loginCallback) {
104957 if(context->loginCallback(&userToken->userName, &userToken->password,
104958 context->usernamePasswordLoginSize, context->usernamePasswordLogin,
104959 sessionContext, context->loginContext) == UA_STATUSCODE_GOOD)
104960 match = true;
104961 } else {
104962 for(size_t i = 0; i < context->usernamePasswordLoginSize; i++) {
104963 if(UA_String_equal(p1: &userToken->userName, p2: &context->usernamePasswordLogin[i].username) &&
104964 UA_String_equal(p1: &userToken->password, p2: &context->usernamePasswordLogin[i].password)) {
104965 match = true;
104966 break;
104967 }
104968 }
104969 }
104970 if(!match)
104971 return UA_STATUSCODE_BADUSERACCESSDENIED;
104972 } else if(tokenType == &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN]) {
104973 /* x509 certificate */
104974 const UA_X509IdentityToken *userToken = (UA_X509IdentityToken*)
104975 userIdentityToken->content.decoded.data;
104976
104977 /* Match the beginnig of the PolicyId */
104978 if(userToken->policyId.length < certificate_policy.length ||
104979 strncmp(s1: (const char*)userToken->policyId.data,
104980 s2: (const char*)certificate_policy.data,
104981 n: certificate_policy.length) != 0) {
104982 return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
104983 }
104984
104985 if(!config->sessionPKI.verifyCertificate)
104986 return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
104987
104988 UA_StatusCode res = config->sessionPKI.
104989 verifyCertificate(&config->sessionPKI, &userToken->certificateData);
104990 if(res != UA_STATUSCODE_GOOD)
104991 return UA_STATUSCODE_BADIDENTITYTOKENREJECTED;
104992 } else {
104993 /* Unsupported token type */
104994 return UA_STATUSCODE_BADIDENTITYTOKENINVALID;
104995 }
104996
104997 return UA_STATUSCODE_GOOD;
104998}
104999
105000static void
105001closeSession_default(UA_Server *server, UA_AccessControl *ac,
105002 const UA_NodeId *sessionId, void *sessionContext) {
105003}
105004
105005static UA_UInt32
105006getUserRightsMask_default(UA_Server *server, UA_AccessControl *ac,
105007 const UA_NodeId *sessionId, void *sessionContext,
105008 const UA_NodeId *nodeId, void *nodeContext) {
105009 return 0xFFFFFFFF;
105010}
105011
105012static UA_Byte
105013getUserAccessLevel_default(UA_Server *server, UA_AccessControl *ac,
105014 const UA_NodeId *sessionId, void *sessionContext,
105015 const UA_NodeId *nodeId, void *nodeContext) {
105016 return 0xFF;
105017}
105018
105019static UA_Boolean
105020getUserExecutable_default(UA_Server *server, UA_AccessControl *ac,
105021 const UA_NodeId *sessionId, void *sessionContext,
105022 const UA_NodeId *methodId, void *methodContext) {
105023 return true;
105024}
105025
105026static UA_Boolean
105027getUserExecutableOnObject_default(UA_Server *server, UA_AccessControl *ac,
105028 const UA_NodeId *sessionId, void *sessionContext,
105029 const UA_NodeId *methodId, void *methodContext,
105030 const UA_NodeId *objectId, void *objectContext) {
105031 return true;
105032}
105033
105034static UA_Boolean
105035allowAddNode_default(UA_Server *server, UA_AccessControl *ac,
105036 const UA_NodeId *sessionId, void *sessionContext,
105037 const UA_AddNodesItem *item) {
105038 return true;
105039}
105040
105041static UA_Boolean
105042allowAddReference_default(UA_Server *server, UA_AccessControl *ac,
105043 const UA_NodeId *sessionId, void *sessionContext,
105044 const UA_AddReferencesItem *item) {
105045 return true;
105046}
105047
105048static UA_Boolean
105049allowDeleteNode_default(UA_Server *server, UA_AccessControl *ac,
105050 const UA_NodeId *sessionId, void *sessionContext,
105051 const UA_DeleteNodesItem *item) {
105052 return true;
105053}
105054
105055static UA_Boolean
105056allowDeleteReference_default(UA_Server *server, UA_AccessControl *ac,
105057 const UA_NodeId *sessionId, void *sessionContext,
105058 const UA_DeleteReferencesItem *item) {
105059 return true;
105060}
105061
105062static UA_Boolean
105063allowBrowseNode_default(UA_Server *server, UA_AccessControl *ac,
105064 const UA_NodeId *sessionId, void *sessionContext,
105065 const UA_NodeId *nodeId, void *nodeContext) {
105066 return true;
105067}
105068
105069#ifdef UA_ENABLE_SUBSCRIPTIONS
105070static UA_Boolean
105071allowTransferSubscription_default(UA_Server *server, UA_AccessControl *ac,
105072 const UA_NodeId *oldSessionId, void *oldSessionContext,
105073 const UA_NodeId *newSessionId, void *newSessionContext) {
105074 if(!oldSessionId)
105075 return true;
105076 /* Allow the transfer if the same user-id was used to activate both sessions */
105077 UA_Variant session1UserId;
105078 UA_Variant_init(p: &session1UserId);
105079 UA_Server_getSessionAttribute(server, sessionId: oldSessionId,
105080 key: UA_QUALIFIEDNAME(nsIndex: 0, chars: "clientUserId"),
105081 outValue: &session1UserId);
105082 UA_Variant session2UserId;
105083 UA_Variant_init(p: &session2UserId);
105084 UA_Server_getSessionAttribute(server, sessionId: newSessionId,
105085 key: UA_QUALIFIEDNAME(nsIndex: 0, chars: "clientUserId"),
105086 outValue: &session2UserId);
105087
105088 return (UA_order(p1: &session1UserId, p2: &session2UserId,
105089 type: &UA_TYPES[UA_TYPES_VARIANT]) == UA_ORDER_EQ);
105090}
105091#endif
105092
105093#ifdef UA_ENABLE_HISTORIZING
105094static UA_Boolean
105095allowHistoryUpdateUpdateData_default(UA_Server *server, UA_AccessControl *ac,
105096 const UA_NodeId *sessionId, void *sessionContext,
105097 const UA_NodeId *nodeId,
105098 UA_PerformUpdateType performInsertReplace,
105099 const UA_DataValue *value) {
105100 return true;
105101}
105102
105103static UA_Boolean
105104allowHistoryUpdateDeleteRawModified_default(UA_Server *server, UA_AccessControl *ac,
105105 const UA_NodeId *sessionId, void *sessionContext,
105106 const UA_NodeId *nodeId,
105107 UA_DateTime startTimestamp,
105108 UA_DateTime endTimestamp,
105109 bool isDeleteModified) {
105110 return true;
105111}
105112#endif
105113
105114/***************************************/
105115/* Create Delete Access Control Plugin */
105116/***************************************/
105117
105118static void clear_default(UA_AccessControl *ac) {
105119 UA_Array_delete(p: (void*)(uintptr_t)ac->userTokenPolicies,
105120 size: ac->userTokenPoliciesSize,
105121 type: &UA_TYPES[UA_TYPES_USERTOKENPOLICY]);
105122 ac->userTokenPolicies = NULL;
105123 ac->userTokenPoliciesSize = 0;
105124
105125 AccessControlContext *context = (AccessControlContext*)ac->context;
105126
105127 if (context) {
105128 for(size_t i = 0; i < context->usernamePasswordLoginSize; i++) {
105129 UA_String_clear(p: &context->usernamePasswordLogin[i].username);
105130 UA_String_clear(p: &context->usernamePasswordLogin[i].password);
105131 }
105132 if(context->usernamePasswordLoginSize > 0)
105133 UA_free(ptr: context->usernamePasswordLogin);
105134
105135 UA_free(ptr: ac->context);
105136 ac->context = NULL;
105137 }
105138}
105139
105140UA_StatusCode
105141UA_AccessControl_default(UA_ServerConfig *config,
105142 UA_Boolean allowAnonymous,
105143 const UA_ByteString *userTokenPolicyUri,
105144 size_t usernamePasswordLoginSize,
105145 const UA_UsernamePasswordLogin *usernamePasswordLogin) {
105146 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
105147 msg: "AccessControl: Unconfigured AccessControl. Users have all permissions.");
105148 UA_AccessControl *ac = &config->accessControl;
105149
105150 if(ac->clear)
105151 ac->clear(ac);
105152
105153 ac->clear = clear_default;
105154 ac->activateSession = activateSession_default;
105155 ac->closeSession = closeSession_default;
105156 ac->getUserRightsMask = getUserRightsMask_default;
105157 ac->getUserAccessLevel = getUserAccessLevel_default;
105158 ac->getUserExecutable = getUserExecutable_default;
105159 ac->getUserExecutableOnObject = getUserExecutableOnObject_default;
105160 ac->allowAddNode = allowAddNode_default;
105161 ac->allowAddReference = allowAddReference_default;
105162 ac->allowBrowseNode = allowBrowseNode_default;
105163
105164#ifdef UA_ENABLE_SUBSCRIPTIONS
105165 ac->allowTransferSubscription = allowTransferSubscription_default;
105166#endif
105167
105168#ifdef UA_ENABLE_HISTORIZING
105169 ac->allowHistoryUpdateUpdateData = allowHistoryUpdateUpdateData_default;
105170 ac->allowHistoryUpdateDeleteRawModified = allowHistoryUpdateDeleteRawModified_default;
105171#endif
105172
105173 ac->allowDeleteNode = allowDeleteNode_default;
105174 ac->allowDeleteReference = allowDeleteReference_default;
105175
105176 AccessControlContext *context = (AccessControlContext*)
105177 UA_malloc(size: sizeof(AccessControlContext));
105178 if(!context)
105179 return UA_STATUSCODE_BADOUTOFMEMORY;
105180 memset(s: context, c: 0, n: sizeof(AccessControlContext));
105181 ac->context = context;
105182
105183 /* Allow anonymous? */
105184 context->allowAnonymous = allowAnonymous;
105185 if(allowAnonymous) {
105186 UA_LOG_INFO(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
105187 msg: "AccessControl: Anonymous login is enabled");
105188 }
105189
105190 /* Copy username/password to the access control plugin */
105191 if(usernamePasswordLoginSize > 0) {
105192 context->usernamePasswordLogin = (UA_UsernamePasswordLogin*)
105193 UA_malloc(size: usernamePasswordLoginSize * sizeof(UA_UsernamePasswordLogin));
105194 if(!context->usernamePasswordLogin)
105195 return UA_STATUSCODE_BADOUTOFMEMORY;
105196 context->usernamePasswordLoginSize = usernamePasswordLoginSize;
105197 for(size_t i = 0; i < usernamePasswordLoginSize; i++) {
105198 UA_String_copy(src: &usernamePasswordLogin[i].username,
105199 dst: &context->usernamePasswordLogin[i].username);
105200 UA_String_copy(src: &usernamePasswordLogin[i].password,
105201 dst: &context->usernamePasswordLogin[i].password);
105202 }
105203 }
105204
105205 size_t numOfPolcies = 1;
105206 if(!userTokenPolicyUri) {
105207 if(config->securityPoliciesSize > 0)
105208 numOfPolcies = config->securityPoliciesSize;
105209 else {
105210 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
105211 msg: "No security policies defined for the secure channel.");
105212 return UA_STATUSCODE_BADINTERNALERROR;
105213 }
105214 }
105215
105216 /* Set the allowed policies */
105217 size_t policies = 0;
105218 if(allowAnonymous)
105219 policies++;
105220 if(usernamePasswordLoginSize > 0)
105221 policies++;
105222 if(config->sessionPKI.verifyCertificate)
105223 policies++;
105224 ac->userTokenPoliciesSize = 0;
105225 ac->userTokenPolicies = (UA_UserTokenPolicy *)
105226 UA_Array_new(size: policies * numOfPolcies, type: &UA_TYPES[UA_TYPES_USERTOKENPOLICY]);
105227 if(!ac->userTokenPolicies)
105228 return UA_STATUSCODE_BADOUTOFMEMORY;
105229 ac->userTokenPoliciesSize = policies * numOfPolcies;
105230
105231 if(policies == 0) {
105232 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
105233 msg: "No allowed policies set.");
105234 return UA_STATUSCODE_GOOD;
105235 }
105236
105237 const UA_ByteString *utpUri = NULL;
105238 policies = 0;
105239 for(size_t i = 0; i < numOfPolcies; i++) {
105240 if(userTokenPolicyUri) {
105241 utpUri = userTokenPolicyUri;
105242 } else {
105243 utpUri = &config->securityPolicies[i].policyUri;
105244 }
105245 if(allowAnonymous) {
105246 ac->userTokenPolicies[policies].tokenType = UA_USERTOKENTYPE_ANONYMOUS;
105247 ac->userTokenPolicies[policies].policyId = UA_STRING_ALLOC(ANONYMOUS_POLICY);
105248 UA_ByteString_copy(src: utpUri,
105249 dst: &ac->userTokenPolicies[policies].securityPolicyUri);
105250 policies++;
105251 }
105252
105253 if(config->sessionPKI.verifyCertificate) {
105254 ac->userTokenPolicies[policies].tokenType = UA_USERTOKENTYPE_CERTIFICATE;
105255 ac->userTokenPolicies[policies].policyId = UA_STRING_ALLOC(CERTIFICATE_POLICY);
105256#if UA_LOGLEVEL <= 400
105257 if(UA_ByteString_equal(p1: utpUri, p2: &UA_SECURITY_POLICY_NONE_URI)) {
105258 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
105259 msg: "x509 Certificate Authentication configured, "
105260 "but no encrypting SecurityPolicy. "
105261 "This can leak credentials on the network.");
105262 }
105263#endif
105264 UA_ByteString_copy(src: utpUri,
105265 dst: &ac->userTokenPolicies[policies].securityPolicyUri);
105266 policies++;
105267 }
105268
105269 if(usernamePasswordLoginSize > 0) {
105270 ac->userTokenPolicies[policies].tokenType = UA_USERTOKENTYPE_USERNAME;
105271 ac->userTokenPolicies[policies].policyId = UA_STRING_ALLOC(USERNAME_POLICY);
105272#if UA_LOGLEVEL <= 400
105273 if(UA_ByteString_equal(p1: utpUri, p2: &UA_SECURITY_POLICY_NONE_URI)) {
105274 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_SERVER,
105275 msg: "Username/Password Authentication configured, "
105276 "but no encrypting SecurityPolicy. "
105277 "This can leak credentials on the network.");
105278 }
105279#endif
105280 UA_ByteString_copy(src: utpUri,
105281 dst: &ac->userTokenPolicies[policies].securityPolicyUri);
105282 policies++;
105283 }
105284 }
105285 return UA_STATUSCODE_GOOD;
105286}
105287
105288UA_StatusCode
105289UA_AccessControl_defaultWithLoginCallback(UA_ServerConfig *config,
105290 UA_Boolean allowAnonymous,
105291 const UA_ByteString *userTokenPolicyUri,
105292 size_t usernamePasswordLoginSize,
105293 const UA_UsernamePasswordLogin *usernamePasswordLogin,
105294 UA_UsernamePasswordLoginCallback loginCallback,
105295 void *loginContext) {
105296 AccessControlContext *context;
105297 UA_StatusCode sc =
105298 UA_AccessControl_default(config, allowAnonymous, userTokenPolicyUri,
105299 usernamePasswordLoginSize, usernamePasswordLogin);
105300 if(sc != UA_STATUSCODE_GOOD)
105301 return sc;
105302
105303 context = (AccessControlContext *)config->accessControl.context;
105304 context->loginCallback = loginCallback;
105305 context->loginContext = loginContext;
105306
105307 return UA_STATUSCODE_GOOD;
105308}
105309
105310
105311/**** amalgamated original file "/plugins/ua_nodestore_ziptree.c" ****/
105312
105313/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
105314 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
105315 *
105316 * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
105317 * Copyright 2017 (c) Julian Grothoff
105318 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
105319 */
105320
105321
105322#ifndef container_of
105323#define container_of(ptr, type, member) \
105324 (type *)((uintptr_t)ptr - offsetof(type,member))
105325#endif
105326
105327struct NodeEntry;
105328typedef struct NodeEntry NodeEntry;
105329
105330struct NodeEntry {
105331 ZIP_ENTRY(NodeEntry) zipfields;
105332 UA_UInt32 nodeIdHash;
105333 UA_UInt16 refCount; /* How many consumers have a reference to the node? */
105334 UA_Boolean deleted; /* Node was marked as deleted and can be deleted when refCount == 0 */
105335 NodeEntry *orig; /* If a copy is made to replace a node, track that we
105336 * replace only the node from which the copy was made.
105337 * Important for concurrent operations. */
105338 UA_NodeId nodeId; /* This is actually a UA_Node that also starts with a NodeId */
105339};
105340
105341/* Absolute ordering for NodeIds */
105342static enum ZIP_CMP
105343cmpNodeId(const void *a, const void *b) {
105344 const NodeEntry *aa = (const NodeEntry*)a;
105345 const NodeEntry *bb = (const NodeEntry*)b;
105346
105347 /* Compare hash */
105348 if(aa->nodeIdHash < bb->nodeIdHash)
105349 return ZIP_CMP_LESS;
105350 if(aa->nodeIdHash > bb->nodeIdHash)
105351 return ZIP_CMP_MORE;
105352
105353 /* Compore nodes in detail */
105354 return (enum ZIP_CMP)UA_NodeId_order(n1: &aa->nodeId, n2: &bb->nodeId);
105355}
105356
105357ZIP_HEAD(NodeTree, NodeEntry);
105358typedef struct NodeTree NodeTree;
105359
105360typedef struct {
105361 NodeTree root;
105362
105363 /* Maps ReferenceTypeIndex to the NodeId of the ReferenceType */
105364 UA_NodeId referenceTypeIds[UA_REFERENCETYPESET_MAX];
105365 UA_Byte referenceTypeCounter;
105366} ZipContext;
105367
105368ZIP_FUNCTIONS(NodeTree, NodeEntry, zipfields, NodeEntry, zipfields, cmpNodeId)
105369
105370static NodeEntry *
105371newEntry(UA_NodeClass nodeClass) {
105372 size_t size = sizeof(NodeEntry) - sizeof(UA_NodeId);
105373 switch(nodeClass) {
105374 case UA_NODECLASS_OBJECT:
105375 size += sizeof(UA_ObjectNode);
105376 break;
105377 case UA_NODECLASS_VARIABLE:
105378 size += sizeof(UA_VariableNode);
105379 break;
105380 case UA_NODECLASS_METHOD:
105381 size += sizeof(UA_MethodNode);
105382 break;
105383 case UA_NODECLASS_OBJECTTYPE:
105384 size += sizeof(UA_ObjectTypeNode);
105385 break;
105386 case UA_NODECLASS_VARIABLETYPE:
105387 size += sizeof(UA_VariableTypeNode);
105388 break;
105389 case UA_NODECLASS_REFERENCETYPE:
105390 size += sizeof(UA_ReferenceTypeNode);
105391 break;
105392 case UA_NODECLASS_DATATYPE:
105393 size += sizeof(UA_DataTypeNode);
105394 break;
105395 case UA_NODECLASS_VIEW:
105396 size += sizeof(UA_ViewNode);
105397 break;
105398 default:
105399 return NULL;
105400 }
105401 NodeEntry *entry = (NodeEntry*)UA_calloc(nmemb: 1, size: size);
105402 if(!entry)
105403 return NULL;
105404 UA_Node *node = (UA_Node*)&entry->nodeId;
105405 node->head.nodeClass = nodeClass;
105406 return entry;
105407}
105408
105409static void
105410deleteEntry(NodeEntry *entry) {
105411 UA_Node_clear(node: (UA_Node*)&entry->nodeId);
105412 UA_free(ptr: entry);
105413}
105414
105415static void
105416cleanupEntry(NodeEntry *entry) {
105417 if(entry->refCount > 0)
105418 return;
105419 if(entry->deleted) {
105420 deleteEntry(entry);
105421 return;
105422 }
105423 UA_NodeHead *head = (UA_NodeHead*)&entry->nodeId;
105424 for(size_t i = 0; i < head->referencesSize; i++) {
105425 UA_NodeReferenceKind *rk = &head->references[i];
105426 if(rk->targetsSize > 16 && !rk->hasRefTree)
105427 UA_NodeReferenceKind_switch(rk);
105428 }
105429}
105430
105431/***********************/
105432/* Interface functions */
105433/***********************/
105434
105435/* Not yet inserted into the ZipContext */
105436static UA_Node *
105437zipNsNewNode(void *nsCtx, UA_NodeClass nodeClass) {
105438 NodeEntry *entry = newEntry(nodeClass);
105439 if(!entry)
105440 return NULL;
105441 return (UA_Node*)&entry->nodeId;
105442}
105443
105444/* Not yet inserted into the ZipContext */
105445static void
105446zipNsDeleteNode(void *nsCtx, UA_Node *node) {
105447 deleteEntry(container_of(node, NodeEntry, nodeId));
105448}
105449
105450static const UA_Node *
105451zipNsGetNode(void *nsCtx, const UA_NodeId *nodeId,
105452 UA_UInt32 attributeMask,
105453 UA_ReferenceTypeSet references,
105454 UA_BrowseDirection referenceDirections) {
105455 ZipContext *ns = (ZipContext*)nsCtx;
105456 NodeEntry dummy;
105457 dummy.nodeIdHash = UA_NodeId_hash(n: nodeId);
105458 dummy.nodeId = *nodeId;
105459 NodeEntry *entry = ZIP_FIND(NodeTree, &ns->root, &dummy);
105460 if(!entry)
105461 return NULL;
105462 ++entry->refCount;
105463 return (const UA_Node*)&entry->nodeId;
105464}
105465
105466static const UA_Node *
105467zipNsGetNodeFromPtr(void *nsCtx, UA_NodePointer ptr,
105468 UA_UInt32 attributeMask,
105469 UA_ReferenceTypeSet references,
105470 UA_BrowseDirection referenceDirections) {
105471 if(!UA_NodePointer_isLocal(np: ptr))
105472 return NULL;
105473 UA_NodeId id = UA_NodePointer_toNodeId(np: ptr);
105474 return zipNsGetNode(nsCtx, nodeId: &id, attributeMask,
105475 references, referenceDirections);
105476}
105477
105478static void
105479zipNsReleaseNode(void *nsCtx, const UA_Node *node) {
105480 if(!node)
105481 return;
105482 NodeEntry *entry = container_of(node, NodeEntry, nodeId);
105483 UA_assert(entry->refCount > 0);
105484 --entry->refCount;
105485 cleanupEntry(entry);
105486}
105487
105488static UA_StatusCode
105489zipNsGetNodeCopy(void *nsCtx, const UA_NodeId *nodeId,
105490 UA_Node **outNode) {
105491 /* Get the node (with all attributes and references, the mask and refs are
105492 currently noy evaluated within the plugin.) */
105493 const UA_Node *node =
105494 zipNsGetNode(nsCtx, nodeId, attributeMask: UA_NODEATTRIBUTESMASK_ALL,
105495 references: UA_REFERENCETYPESET_ALL, referenceDirections: UA_BROWSEDIRECTION_BOTH);
105496 if(!node)
105497 return UA_STATUSCODE_BADNODEIDUNKNOWN;
105498
105499 /* Create the new entry */
105500 NodeEntry *ne = newEntry(nodeClass: node->head.nodeClass);
105501 if(!ne) {
105502 zipNsReleaseNode(nsCtx, node);
105503 return UA_STATUSCODE_BADOUTOFMEMORY;
105504 }
105505
105506 /* Copy the node content */
105507 UA_Node *nnode = (UA_Node*)&ne->nodeId;
105508 UA_StatusCode retval = UA_Node_copy(src: node, dst: nnode);
105509 zipNsReleaseNode(nsCtx, node);
105510 if(retval != UA_STATUSCODE_GOOD) {
105511 deleteEntry(entry: ne);
105512 return retval;
105513 }
105514
105515 ne->orig = container_of(node, NodeEntry, nodeId);
105516 *outNode = nnode;
105517 return UA_STATUSCODE_GOOD;
105518}
105519
105520static UA_StatusCode
105521zipNsInsertNode(void *nsCtx, UA_Node *node, UA_NodeId *addedNodeId) {
105522 NodeEntry *entry = container_of(node, NodeEntry, nodeId);
105523 ZipContext *ns = (ZipContext*)nsCtx;
105524
105525 /* Ensure that the NodeId is unique */
105526 NodeEntry dummy;
105527 memset(s: &dummy, c: 0, n: sizeof(NodeEntry));
105528 dummy.nodeId = node->head.nodeId;
105529 if(node->head.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC &&
105530 node->head.nodeId.identifier.numeric == 0) {
105531 do { /* Create a random nodeid until we find an unoccupied id */
105532 UA_UInt32 numId = UA_UInt32_random();
105533#if SIZE_MAX <= UA_UINT32_MAX
105534 /* The compressed "immediate" representation of nodes does not
105535 * support the full range on 32bit systems. Generate smaller
105536 * identifiers as they can be stored more compactly. */
105537 if(numId >= (0x01 << 24))
105538 numId = numId % (0x01 << 24);
105539#endif
105540 node->head.nodeId.identifier.numeric = numId;
105541 dummy.nodeId.identifier.numeric = numId;
105542 dummy.nodeIdHash = UA_NodeId_hash(n: &node->head.nodeId);
105543 } while(ZIP_FIND(NodeTree, &ns->root, &dummy));
105544 } else {
105545 dummy.nodeIdHash = UA_NodeId_hash(n: &node->head.nodeId);
105546 if(ZIP_FIND(NodeTree, &ns->root, &dummy)) { /* The nodeid exists */
105547 deleteEntry(entry);
105548 return UA_STATUSCODE_BADNODEIDEXISTS;
105549 }
105550 }
105551
105552 /* Copy the NodeId */
105553 if(addedNodeId) {
105554 UA_StatusCode retval = UA_NodeId_copy(src: &node->head.nodeId, dst: addedNodeId);
105555 if(retval != UA_STATUSCODE_GOOD) {
105556 deleteEntry(entry);
105557 return retval;
105558 }
105559 }
105560
105561 /* For new ReferencetypeNodes add to the index map */
105562 if(node->head.nodeClass == UA_NODECLASS_REFERENCETYPE) {
105563 UA_ReferenceTypeNode *refNode = &node->referenceTypeNode;
105564 if(ns->referenceTypeCounter >= UA_REFERENCETYPESET_MAX) {
105565 deleteEntry(entry);
105566 return UA_STATUSCODE_BADINTERNALERROR;
105567 }
105568
105569 UA_StatusCode retval =
105570 UA_NodeId_copy(src: &node->head.nodeId, dst: &ns->referenceTypeIds[ns->referenceTypeCounter]);
105571 if(retval != UA_STATUSCODE_GOOD) {
105572 deleteEntry(entry);
105573 return UA_STATUSCODE_BADINTERNALERROR;
105574 }
105575
105576 /* Assign the ReferenceTypeIndex to the new ReferenceTypeNode */
105577 refNode->referenceTypeIndex = ns->referenceTypeCounter;
105578 refNode->subTypes = UA_REFTYPESET(index: ns->referenceTypeCounter);
105579
105580 ns->referenceTypeCounter++;
105581 }
105582
105583 /* Insert the node */
105584 entry->nodeIdHash = dummy.nodeIdHash;
105585 ZIP_INSERT(NodeTree, &ns->root, entry);
105586 return UA_STATUSCODE_GOOD;
105587}
105588
105589static UA_StatusCode
105590zipNsReplaceNode(void *nsCtx, UA_Node *node) {
105591 /* Find the node (the mask and refs are not evaluated yet by the plugin)*/
105592 const UA_Node *oldNode =
105593 zipNsGetNode(nsCtx, nodeId: &node->head.nodeId, attributeMask: UA_NODEATTRIBUTESMASK_ALL,
105594 references: UA_REFERENCETYPESET_ALL, referenceDirections: UA_BROWSEDIRECTION_BOTH);
105595 if(!oldNode) {
105596 deleteEntry(container_of(node, NodeEntry, nodeId));
105597 return UA_STATUSCODE_BADNODEIDUNKNOWN;
105598 }
105599
105600 /* Test if the copy is current */
105601 NodeEntry *entry = container_of(node, NodeEntry, nodeId);
105602 NodeEntry *oldEntry = container_of(oldNode, NodeEntry, nodeId);
105603 if(oldEntry != entry->orig) {
105604 /* The node was already updated since the copy was made */
105605 deleteEntry(entry);
105606 zipNsReleaseNode(nsCtx, node: oldNode);
105607 return UA_STATUSCODE_BADINTERNALERROR;
105608 }
105609
105610 /* Replace */
105611 ZipContext *ns = (ZipContext*)nsCtx;
105612 ZIP_REMOVE(NodeTree, &ns->root, oldEntry);
105613 entry->nodeIdHash = oldEntry->nodeIdHash;
105614 ZIP_INSERT(NodeTree, &ns->root, entry);
105615 oldEntry->deleted = true;
105616
105617 zipNsReleaseNode(nsCtx, node: oldNode);
105618 return UA_STATUSCODE_GOOD;
105619}
105620
105621static UA_StatusCode
105622zipNsRemoveNode(void *nsCtx, const UA_NodeId *nodeId) {
105623 ZipContext *ns = (ZipContext*)nsCtx;
105624 NodeEntry dummy;
105625 dummy.nodeIdHash = UA_NodeId_hash(n: nodeId);
105626 dummy.nodeId = *nodeId;
105627 NodeEntry *entry = ZIP_FIND(NodeTree, &ns->root, &dummy);
105628 if(!entry)
105629 return UA_STATUSCODE_BADNODEIDUNKNOWN;
105630 ZIP_REMOVE(NodeTree, &ns->root, entry);
105631 entry->deleted = true;
105632 cleanupEntry(entry);
105633 return UA_STATUSCODE_GOOD;
105634}
105635
105636static const UA_NodeId *
105637zipNsGetReferenceTypeId(void *nsCtx, UA_Byte refTypeIndex) {
105638 ZipContext *ns = (ZipContext*)nsCtx;
105639 if(refTypeIndex >= ns->referenceTypeCounter)
105640 return NULL;
105641 return &ns->referenceTypeIds[refTypeIndex];
105642}
105643
105644struct VisitorData {
105645 UA_NodestoreVisitor visitor;
105646 void *visitorContext;
105647};
105648
105649static void *
105650nodeVisitor(void *data, NodeEntry *entry) {
105651 struct VisitorData *d = (struct VisitorData*)data;
105652 d->visitor(d->visitorContext, (UA_Node*)&entry->nodeId);
105653 return NULL;
105654}
105655
105656static void
105657zipNsIterate(void *nsCtx, UA_NodestoreVisitor visitor,
105658 void *visitorCtx) {
105659 struct VisitorData d;
105660 d.visitor = visitor;
105661 d.visitorContext = visitorCtx;
105662 ZipContext *ns = (ZipContext*)nsCtx;
105663 ZIP_ITER(NodeTree, &ns->root, nodeVisitor, &d);
105664}
105665
105666static void *
105667deleteNodeVisitor(void *data, NodeEntry *entry) {
105668 deleteEntry(entry);
105669 return NULL;
105670}
105671
105672/***********************/
105673/* Nodestore Lifecycle */
105674/***********************/
105675
105676static void
105677zipNsClear(void *nsCtx) {
105678 if (!nsCtx)
105679 return;
105680 ZipContext *ns = (ZipContext*)nsCtx;
105681 ZIP_ITER(NodeTree, &ns->root, deleteNodeVisitor, NULL);
105682
105683 /* Clean up the ReferenceTypes index array */
105684 for(size_t i = 0; i < ns->referenceTypeCounter; i++)
105685 UA_NodeId_clear(p: &ns->referenceTypeIds[i]);
105686
105687 UA_free(ptr: ns);
105688}
105689
105690UA_StatusCode
105691UA_Nodestore_ZipTree(UA_Nodestore *ns) {
105692 /* Allocate and initialize the context */
105693 ZipContext *ctx = (ZipContext*)UA_malloc(size: sizeof(ZipContext));
105694 if(!ctx)
105695 return UA_STATUSCODE_BADOUTOFMEMORY;
105696
105697 ZIP_INIT(&ctx->root);
105698 ctx->referenceTypeCounter = 0;
105699
105700 /* Populate the nodestore */
105701 ns->context = (void*)ctx;
105702 ns->clear = zipNsClear;
105703 ns->newNode = zipNsNewNode;
105704 ns->deleteNode = zipNsDeleteNode;
105705 ns->getNode = zipNsGetNode;
105706 ns->getNodeFromPtr = zipNsGetNodeFromPtr;
105707 ns->releaseNode = zipNsReleaseNode;
105708 ns->getNodeCopy = zipNsGetNodeCopy;
105709 ns->insertNode = zipNsInsertNode;
105710 ns->replaceNode = zipNsReplaceNode;
105711 ns->removeNode = zipNsRemoveNode;
105712 ns->getReferenceTypeId = zipNsGetReferenceTypeId;
105713 ns->iterate = zipNsIterate;
105714
105715 return UA_STATUSCODE_GOOD;
105716}
105717
105718/**** amalgamated original file "/plugins/ua_nodestore_hashmap.c" ****/
105719
105720/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
105721 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
105722 *
105723 * Copyright 2014-2019 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
105724 * Copyright 2017 (c) Julian Grothoff
105725 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
105726 */
105727
105728
105729#ifndef container_of
105730#define container_of(ptr, type, member) \
105731 (type *)((uintptr_t)ptr - offsetof(type,member))
105732#endif
105733
105734/* The default Nodestore is simply a hash-map from NodeIds to Nodes. To find an
105735 * entry, iterate over candidate positions according to the NodeId hash.
105736 *
105737 * - Tombstone or non-matching NodeId: continue searching
105738 * - Matching NodeId: Return the entry
105739 * - NULL: Abort the search */
105740
105741typedef struct UA_NodeMapEntry {
105742 struct UA_NodeMapEntry *orig; /* the version this is a copy from (or NULL) */
105743 UA_UInt16 refCount; /* How many consumers have a reference to the node? */
105744 UA_Boolean deleted; /* Node was marked as deleted and can be deleted when refCount == 0 */
105745 UA_Node node;
105746} UA_NodeMapEntry;
105747
105748#define UA_NODEMAP_MINSIZE 64
105749#define UA_NODEMAP_TOMBSTONE ((UA_NodeMapEntry*)0x01)
105750
105751typedef struct {
105752 UA_NodeMapEntry *entry;
105753 UA_UInt32 nodeIdHash;
105754} UA_NodeMapSlot;
105755
105756typedef struct {
105757 UA_NodeMapSlot *slots;
105758 UA_UInt32 size;
105759 UA_UInt32 count;
105760 UA_UInt32 sizePrimeIndex;
105761
105762 /* Maps ReferenceTypeIndex to the NodeId of the ReferenceType */
105763 UA_NodeId referenceTypeIds[UA_REFERENCETYPESET_MAX];
105764 UA_Byte referenceTypeCounter;
105765} UA_NodeMap;
105766
105767/*********************/
105768/* HashMap Utilities */
105769/*********************/
105770
105771/* The size of the hash-map is always a prime number. They are chosen to be
105772 * close to the next power of 2. So the size ca. doubles with each prime. */
105773static UA_UInt32 const primes[] = {
105774 7, 13, 31, 61, 127, 251,
105775 509, 1021, 2039, 4093, 8191, 16381,
105776 32749, 65521, 131071, 262139, 524287, 1048573,
105777 2097143, 4194301, 8388593, 16777213, 33554393, 67108859,
105778 134217689, 268435399, 536870909, 1073741789, 2147483647, 4294967291
105779};
105780
105781static UA_UInt32 mod(UA_UInt32 h, UA_UInt32 size) { return h % size; }
105782static UA_UInt32 mod2(UA_UInt32 h, UA_UInt32 size) { return 1 + (h % (size - 2)); }
105783
105784static UA_UInt16
105785higher_prime_index(UA_UInt32 n) {
105786 UA_UInt16 low = 0;
105787 UA_UInt16 high = (UA_UInt16)(sizeof(primes) / sizeof(UA_UInt32));
105788 while(low != high) {
105789 UA_UInt16 mid = (UA_UInt16)(low + ((high - low) / 2));
105790 if(n > primes[mid])
105791 low = (UA_UInt16)(mid + 1);
105792 else
105793 high = mid;
105794 }
105795 return low;
105796}
105797
105798/* Returns an empty slot or null if the nodeid exists or if no empty slot is found. */
105799static UA_NodeMapSlot *
105800findFreeSlot(const UA_NodeMap *ns, const UA_NodeId *nodeid) {
105801 UA_UInt32 h = UA_NodeId_hash(n: nodeid);
105802 UA_UInt32 size = ns->size;
105803 UA_UInt64 idx = mod(h, size); /* Use 64bit container to avoid overflow */
105804 UA_UInt32 startIdx = (UA_UInt32)idx;
105805 UA_UInt32 hash2 = mod2(h, size);
105806
105807 UA_NodeMapSlot *candidate = NULL;
105808 do {
105809 UA_NodeMapSlot *slot = &ns->slots[(UA_UInt32)idx];
105810
105811 if(slot->entry > UA_NODEMAP_TOMBSTONE) {
105812 /* A Node with the NodeId does already exist */
105813 if(slot->nodeIdHash == h &&
105814 UA_NodeId_equal(p1: &slot->entry->node.head.nodeId, p2: nodeid))
105815 return NULL;
105816 } else {
105817 /* Found a candidate node */
105818 if(!candidate)
105819 candidate = slot;
105820 /* No matching node can come afterwards */
105821 if(slot->entry == NULL)
105822 return candidate;
105823 }
105824
105825 idx += hash2;
105826 if(idx >= size)
105827 idx -= size;
105828 } while((UA_UInt32)idx != startIdx);
105829
105830 return candidate;
105831}
105832
105833/* The occupancy of the table after the call will be about 50% */
105834static UA_StatusCode
105835expand(UA_NodeMap *ns) {
105836 UA_UInt32 osize = ns->size;
105837 UA_UInt32 count = ns->count;
105838 /* Resize only when table after removal of unused elements is either too
105839 full or too empty */
105840 if(count * 2 < osize && (count * 8 > osize || osize <= UA_NODEMAP_MINSIZE))
105841 return UA_STATUSCODE_GOOD;
105842
105843 UA_NodeMapSlot *oslots = ns->slots;
105844 UA_UInt32 nindex = higher_prime_index(n: count * 2);
105845 UA_UInt32 nsize = primes[nindex];
105846 UA_NodeMapSlot *nslots= (UA_NodeMapSlot*)UA_calloc(nmemb: nsize, size: sizeof(UA_NodeMapSlot));
105847 if(!nslots)
105848 return UA_STATUSCODE_BADOUTOFMEMORY;
105849
105850 ns->slots = nslots;
105851 ns->size = nsize;
105852 ns->sizePrimeIndex = nindex;
105853
105854 /* recompute the position of every entry and insert the pointer */
105855 for(size_t i = 0, j = 0; i < osize && j < count; ++i) {
105856 if(oslots[i].entry <= UA_NODEMAP_TOMBSTONE)
105857 continue;
105858 UA_NodeMapSlot *s = findFreeSlot(ns, nodeid: &oslots[i].entry->node.head.nodeId);
105859 UA_assert(s);
105860 *s = oslots[i];
105861 ++j;
105862 }
105863
105864 UA_free(ptr: oslots);
105865 return UA_STATUSCODE_GOOD;
105866}
105867
105868static UA_NodeMapEntry *
105869createEntry(UA_NodeClass nodeClass) {
105870 size_t size = sizeof(UA_NodeMapEntry) - sizeof(UA_Node);
105871 switch(nodeClass) {
105872 case UA_NODECLASS_OBJECT:
105873 size += sizeof(UA_ObjectNode);
105874 break;
105875 case UA_NODECLASS_VARIABLE:
105876 size += sizeof(UA_VariableNode);
105877 break;
105878 case UA_NODECLASS_METHOD:
105879 size += sizeof(UA_MethodNode);
105880 break;
105881 case UA_NODECLASS_OBJECTTYPE:
105882 size += sizeof(UA_ObjectTypeNode);
105883 break;
105884 case UA_NODECLASS_VARIABLETYPE:
105885 size += sizeof(UA_VariableTypeNode);
105886 break;
105887 case UA_NODECLASS_REFERENCETYPE:
105888 size += sizeof(UA_ReferenceTypeNode);
105889 break;
105890 case UA_NODECLASS_DATATYPE:
105891 size += sizeof(UA_DataTypeNode);
105892 break;
105893 case UA_NODECLASS_VIEW:
105894 size += sizeof(UA_ViewNode);
105895 break;
105896 default:
105897 return NULL;
105898 }
105899 UA_NodeMapEntry *entry = (UA_NodeMapEntry*)UA_calloc(nmemb: 1, size: size);
105900 if(!entry)
105901 return NULL;
105902 entry->node.head.nodeClass = nodeClass;
105903 return entry;
105904}
105905
105906static void
105907deleteNodeMapEntry(UA_NodeMapEntry *entry) {
105908 UA_Node_clear(node: &entry->node);
105909 UA_free(ptr: entry);
105910}
105911
105912static void
105913cleanupNodeMapEntry(UA_NodeMapEntry *entry) {
105914 if(entry->refCount > 0)
105915 return;
105916 if(entry->deleted) {
105917 deleteNodeMapEntry(entry);
105918 return;
105919 }
105920 for(size_t i = 0; i < entry->node.head.referencesSize; i++) {
105921 UA_NodeReferenceKind *rk = &entry->node.head.references[i];
105922 if(rk->targetsSize > 16 && !rk->hasRefTree)
105923 UA_NodeReferenceKind_switch(rk);
105924 }
105925}
105926
105927static UA_NodeMapSlot *
105928findOccupiedSlot(const UA_NodeMap *ns, const UA_NodeId *nodeid) {
105929 UA_UInt32 h = UA_NodeId_hash(n: nodeid);
105930 UA_UInt32 size = ns->size;
105931 UA_UInt64 idx = mod(h, size); /* Use 64bit container to avoid overflow */
105932 UA_UInt32 hash2 = mod2(h, size);
105933 UA_UInt32 startIdx = (UA_UInt32)idx;
105934
105935 do {
105936 UA_NodeMapSlot *slot= &ns->slots[(UA_UInt32)idx];
105937 if(slot->entry > UA_NODEMAP_TOMBSTONE) {
105938 if(slot->nodeIdHash == h &&
105939 UA_NodeId_equal(p1: &slot->entry->node.head.nodeId, p2: nodeid))
105940 return slot;
105941 } else {
105942 if(slot->entry == NULL)
105943 return NULL; /* No further entry possible */
105944 }
105945
105946 idx += hash2;
105947 if(idx >= size)
105948 idx -= size;
105949 } while((UA_UInt32)idx != startIdx);
105950
105951 return NULL;
105952}
105953
105954/***********************/
105955/* Interface functions */
105956/***********************/
105957
105958static UA_Node *
105959UA_NodeMap_newNode(void *context, UA_NodeClass nodeClass) {
105960 UA_NodeMapEntry *entry = createEntry(nodeClass);
105961 if(!entry)
105962 return NULL;
105963 return &entry->node;
105964}
105965
105966static void
105967UA_NodeMap_deleteNode(void *context, UA_Node *node) {
105968 UA_NodeMapEntry *entry = container_of(node, UA_NodeMapEntry, node);
105969 UA_assert(&entry->node == node);
105970 deleteNodeMapEntry(entry);
105971}
105972
105973static const UA_Node *
105974UA_NodeMap_getNode(void *context, const UA_NodeId *nodeid,
105975 UA_UInt32 attributeMask,
105976 UA_ReferenceTypeSet references,
105977 UA_BrowseDirection referenceDirections) {
105978 UA_NodeMap *ns = (UA_NodeMap*)context;
105979 UA_NodeMapSlot *slot = findOccupiedSlot(ns, nodeid);
105980 if(!slot)
105981 return NULL;
105982 ++slot->entry->refCount;
105983 return &slot->entry->node;
105984}
105985
105986static const UA_Node *
105987UA_NodeMap_getNodeFromPtr(void *context, UA_NodePointer ptr,
105988 UA_UInt32 attributeMask,
105989 UA_ReferenceTypeSet references,
105990 UA_BrowseDirection referenceDirections) {
105991 if(!UA_NodePointer_isLocal(np: ptr))
105992 return NULL;
105993 UA_NodeId id = UA_NodePointer_toNodeId(np: ptr);
105994 return UA_NodeMap_getNode(context, nodeid: &id, attributeMask, references, referenceDirections);
105995}
105996
105997static void
105998UA_NodeMap_releaseNode(void *context, const UA_Node *node) {
105999 if (!node)
106000 return;
106001 UA_NodeMapEntry *entry = container_of(node, UA_NodeMapEntry, node);
106002 UA_assert(&entry->node == node);
106003 UA_assert(entry->refCount > 0);
106004 --entry->refCount;
106005 cleanupNodeMapEntry(entry);
106006}
106007
106008static UA_StatusCode
106009UA_NodeMap_getNodeCopy(void *context, const UA_NodeId *nodeid,
106010 UA_Node **outNode) {
106011 UA_NodeMap *ns = (UA_NodeMap*)context;
106012 UA_NodeMapSlot *slot = findOccupiedSlot(ns, nodeid);
106013 if(!slot)
106014 return UA_STATUSCODE_BADNODEIDUNKNOWN;
106015 UA_NodeMapEntry *entry = slot->entry;
106016 UA_NodeMapEntry *newItem = createEntry(nodeClass: entry->node.head.nodeClass);
106017 if(!newItem)
106018 return UA_STATUSCODE_BADOUTOFMEMORY;
106019 UA_StatusCode retval = UA_Node_copy(src: &entry->node, dst: &newItem->node);
106020 if(retval == UA_STATUSCODE_GOOD) {
106021 newItem->orig = entry; /* Store the pointer to the original */
106022 *outNode = &newItem->node;
106023 } else {
106024 deleteNodeMapEntry(entry: newItem);
106025 }
106026 return retval;
106027}
106028
106029static UA_StatusCode
106030UA_NodeMap_removeNode(void *context, const UA_NodeId *nodeid) {
106031 UA_NodeMap *ns = (UA_NodeMap*)context;
106032 UA_NodeMapSlot *slot = findOccupiedSlot(ns, nodeid);
106033 if(!slot)
106034 return UA_STATUSCODE_BADNODEIDUNKNOWN;
106035
106036 UA_NodeMapEntry *entry = slot->entry;
106037 slot->entry = UA_NODEMAP_TOMBSTONE;
106038 entry->deleted = true;
106039 cleanupNodeMapEntry(entry);
106040 --ns->count;
106041 /* Downsize the hashmap if it is very empty */
106042 if(ns->count * 8 < ns->size && ns->size > UA_NODEMAP_MINSIZE)
106043 expand(ns); /* Can fail. Just continue with the bigger hashmap. */
106044 return UA_STATUSCODE_GOOD;
106045}
106046
106047/*
106048 * If this function fails in any way, the node parameter is deleted here,
106049 * so the caller function does not need to take care of it anymore
106050 */
106051static UA_StatusCode
106052UA_NodeMap_insertNode(void *context, UA_Node *node,
106053 UA_NodeId *addedNodeId) {
106054 UA_NodeMap *ns = (UA_NodeMap*)context;
106055 if(ns->size * 3 <= ns->count * 4) {
106056 if(expand(ns) != UA_STATUSCODE_GOOD){
106057 deleteNodeMapEntry(container_of(node, UA_NodeMapEntry, node));
106058 return UA_STATUSCODE_BADINTERNALERROR;
106059 }
106060 }
106061
106062 UA_NodeMapSlot *slot;
106063 if(node->head.nodeId.identifierType == UA_NODEIDTYPE_NUMERIC &&
106064 node->head.nodeId.identifier.numeric == 0) {
106065 /* Create a random nodeid: Start at least with 50,000 to make sure we
106066 * don not conflict with nodes from the spec. If we find a conflict, we
106067 * just try another identifier until we have tried all possible
106068 * identifiers. Since the size is prime and we don't change the increase
106069 * val, we will reach the starting id again. E.g. adding a nodeset will
106070 * create children while there are still other nodes which need to be
106071 * created. Thus the node ids may collide. */
106072 UA_UInt32 size = ns->size;
106073 UA_UInt64 identifier = mod(h: 50000 + size+1, UA_UINT32_MAX); /* Use 64bit to
106074 * avoid overflow */
106075 UA_UInt32 increase = mod2(h: ns->count+1, size);
106076 UA_UInt32 startId = (UA_UInt32)identifier; /* mod ensures us that the id
106077 * is a valid 32 bit integer */
106078
106079 do {
106080 node->head.nodeId.identifier.numeric = (UA_UInt32)identifier;
106081 slot = findFreeSlot(ns, nodeid: &node->head.nodeId);
106082 if(slot)
106083 break;
106084 identifier += increase;
106085 if(identifier >= size)
106086 identifier -= size;
106087#if SIZE_MAX <= UA_UINT32_MAX
106088 /* The compressed "immediate" representation of nodes does not
106089 * support the full range on 32bit systems. Generate smaller
106090 * identifiers as they can be stored more compactly. */
106091 if(identifier >= (0x01 << 24))
106092 identifier = identifier % (0x01 << 24);
106093#endif
106094 } while((UA_UInt32)identifier != startId);
106095 } else {
106096 slot = findFreeSlot(ns, nodeid: &node->head.nodeId);
106097 }
106098
106099 if(!slot) {
106100 deleteNodeMapEntry(container_of(node, UA_NodeMapEntry, node));
106101 return UA_STATUSCODE_BADNODEIDEXISTS;
106102 }
106103
106104 /* Copy the NodeId */
106105 UA_StatusCode retval = UA_STATUSCODE_GOOD;
106106 if(addedNodeId) {
106107 retval = UA_NodeId_copy(src: &node->head.nodeId, dst: addedNodeId);
106108 if(retval != UA_STATUSCODE_GOOD) {
106109 deleteNodeMapEntry(container_of(node, UA_NodeMapEntry, node));
106110 return retval;
106111 }
106112 }
106113
106114 /* For new ReferencetypeNodes add to the index map */
106115 if(node->head.nodeClass == UA_NODECLASS_REFERENCETYPE) {
106116 UA_ReferenceTypeNode *refNode = &node->referenceTypeNode;
106117 if(ns->referenceTypeCounter >= UA_REFERENCETYPESET_MAX) {
106118 deleteNodeMapEntry(container_of(node, UA_NodeMapEntry, node));
106119 return UA_STATUSCODE_BADINTERNALERROR;
106120 }
106121
106122 retval = UA_NodeId_copy(src: &node->head.nodeId, dst: &ns->referenceTypeIds[ns->referenceTypeCounter]);
106123 if(retval != UA_STATUSCODE_GOOD) {
106124 deleteNodeMapEntry(container_of(node, UA_NodeMapEntry, node));
106125 return UA_STATUSCODE_BADINTERNALERROR;
106126 }
106127
106128 /* Assign the ReferenceTypeIndex to the new ReferenceTypeNode */
106129 refNode->referenceTypeIndex = ns->referenceTypeCounter;
106130 refNode->subTypes = UA_REFTYPESET(index: ns->referenceTypeCounter);
106131
106132 ns->referenceTypeCounter++;
106133 }
106134
106135 /* Insert the node */
106136 UA_NodeMapEntry *newEntry = container_of(node, UA_NodeMapEntry, node);
106137 slot->nodeIdHash = UA_NodeId_hash(n: &node->head.nodeId);
106138 slot->entry = newEntry;
106139 ++ns->count;
106140 return retval;
106141}
106142
106143static UA_StatusCode
106144UA_NodeMap_replaceNode(void *context, UA_Node *node) {
106145 UA_NodeMap *ns = (UA_NodeMap*)context;
106146 UA_NodeMapEntry *newEntry = container_of(node, UA_NodeMapEntry, node);
106147
106148 /* Find the node */
106149 UA_NodeMapSlot *slot = findOccupiedSlot(ns, nodeid: &node->head.nodeId);
106150 if(!slot) {
106151 deleteNodeMapEntry(entry: newEntry);
106152 return UA_STATUSCODE_BADNODEIDUNKNOWN;
106153 }
106154
106155 /* The node was already updated since the copy was made? */
106156 UA_NodeMapEntry *oldEntry = slot->entry;
106157 if(oldEntry != newEntry->orig) {
106158 deleteNodeMapEntry(entry: newEntry);
106159 return UA_STATUSCODE_BADINTERNALERROR;
106160 }
106161
106162 /* Replace the entry */
106163 slot->entry = newEntry;
106164 oldEntry->deleted = true;
106165 cleanupNodeMapEntry(entry: oldEntry);
106166 return UA_STATUSCODE_GOOD;
106167}
106168
106169static const UA_NodeId *
106170UA_NodeMap_getReferenceTypeId(void *nsCtx, UA_Byte refTypeIndex) {
106171 UA_NodeMap *ns = (UA_NodeMap*)nsCtx;
106172 if(refTypeIndex >= ns->referenceTypeCounter)
106173 return NULL;
106174 return &ns->referenceTypeIds[refTypeIndex];
106175}
106176
106177static void
106178UA_NodeMap_iterate(void *context, UA_NodestoreVisitor visitor,
106179 void *visitorContext) {
106180 UA_NodeMap *ns = (UA_NodeMap*)context;
106181 for(UA_UInt32 i = 0; i < ns->size; ++i) {
106182 UA_NodeMapSlot *slot = &ns->slots[i];
106183 if(slot->entry > UA_NODEMAP_TOMBSTONE) {
106184 /* The visitor can delete the node. So refcount here. */
106185 slot->entry->refCount++;
106186 visitor(visitorContext, &slot->entry->node);
106187 slot->entry->refCount--;
106188 cleanupNodeMapEntry(entry: slot->entry);
106189 }
106190 }
106191}
106192
106193static void
106194UA_NodeMap_delete(void *context) {
106195 /* Already cleaned up? */
106196 if(!context)
106197 return;
106198
106199 UA_NodeMap *ns = (UA_NodeMap*)context;
106200 UA_UInt32 size = ns->size;
106201 UA_NodeMapSlot *slots = ns->slots;
106202 for(UA_UInt32 i = 0; i < size; ++i) {
106203 if(slots[i].entry > UA_NODEMAP_TOMBSTONE) {
106204 /* On debugging builds, check that all nodes were release */
106205 UA_assert(slots[i].entry->refCount == 0);
106206 /* Delete the node */
106207 deleteNodeMapEntry(entry: slots[i].entry);
106208 }
106209 }
106210 UA_free(ptr: ns->slots);
106211
106212 /* Clean up the ReferenceTypes index array */
106213 for(size_t i = 0; i < ns->referenceTypeCounter; i++)
106214 UA_NodeId_clear(p: &ns->referenceTypeIds[i]);
106215
106216 UA_free(ptr: ns);
106217}
106218
106219UA_StatusCode
106220UA_Nodestore_HashMap(UA_Nodestore *ns) {
106221 /* Allocate and initialize the nodemap */
106222 UA_NodeMap *nodemap = (UA_NodeMap*)UA_malloc(size: sizeof(UA_NodeMap));
106223 if(!nodemap)
106224 return UA_STATUSCODE_BADOUTOFMEMORY;
106225 nodemap->sizePrimeIndex = higher_prime_index(UA_NODEMAP_MINSIZE);
106226 nodemap->size = primes[nodemap->sizePrimeIndex];
106227 nodemap->count = 0;
106228 nodemap->slots = (UA_NodeMapSlot*)
106229 UA_calloc(nmemb: nodemap->size, size: sizeof(UA_NodeMapSlot));
106230 if(!nodemap->slots) {
106231 UA_free(ptr: nodemap);
106232 return UA_STATUSCODE_BADOUTOFMEMORY;
106233 }
106234
106235 nodemap->referenceTypeCounter = 0;
106236
106237 /* Populate the nodestore */
106238 ns->context = nodemap;
106239 ns->clear = UA_NodeMap_delete;
106240 ns->newNode = UA_NodeMap_newNode;
106241 ns->deleteNode = UA_NodeMap_deleteNode;
106242 ns->getNode = UA_NodeMap_getNode;
106243 ns->getNodeFromPtr = UA_NodeMap_getNodeFromPtr;
106244 ns->releaseNode = UA_NodeMap_releaseNode;
106245 ns->getNodeCopy = UA_NodeMap_getNodeCopy;
106246 ns->insertNode = UA_NodeMap_insertNode;
106247 ns->replaceNode = UA_NodeMap_replaceNode;
106248 ns->removeNode = UA_NodeMap_removeNode;
106249 ns->getReferenceTypeId = UA_NodeMap_getReferenceTypeId;
106250 ns->iterate = UA_NodeMap_iterate;
106251 return UA_STATUSCODE_GOOD;
106252}
106253
106254/**** amalgamated original file "/plugins/ua_config_default.c" ****/
106255
106256/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
106257 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
106258 *
106259 * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
106260 * Copyright 2017 (c) Julian Grothoff
106261 * Copyright 2017-2018 (c) Mark Giraud, Fraunhofer IOSB
106262 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
106263 * Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA
106264 * Copyright 2018 (c) Daniel Feist, Precitec GmbH & Co. KG
106265 * Copyright 2018 (c) Fabian Arndt, Root-Core
106266 * Copyright 2019 (c) Kalycito Infotech Private Limited
106267 * Copyright 2017-2020 (c) HMS Industrial Networks AB (Author: Jonas Green)
106268 * Copyright 2020 (c) Wind River Systems, Inc.
106269 */
106270
106271
106272
106273#include <stdio.h>
106274#ifdef UA_ARCHITECTURE_WIN32
106275# include <winsock2.h>
106276#else
106277# include <unistd.h>
106278#endif
106279
106280/* Struct initialization works across ANSI C/C99/C++ if it is done when the
106281 * variable is first declared. Assigning values to existing structs is
106282 * heterogeneous across the three. */
106283static UA_INLINE UA_UInt32Range
106284UA_UINT32RANGE(UA_UInt32 min, UA_UInt32 max) {
106285 UA_UInt32Range range = {min, max};
106286 return range;
106287}
106288
106289static UA_INLINE UA_DurationRange
106290UA_DURATIONRANGE(UA_Duration min, UA_Duration max) {
106291 UA_DurationRange range = {min, max};
106292 return range;
106293}
106294
106295/* Request the private key password from stdin if no callback is defined */
106296#ifdef UA_ENABLE_ENCRYPTION
106297static UA_StatusCode
106298readPrivateKeyPassword(UA_ByteString *password) {
106299 /* Read from stdin */
106300 char buf[256];
106301 fputs(s: "Private key requires a password. Enter and press return: ", stdout);
106302 char *s = fgets(s: buf, n: 256, stdin);
106303 if(!s)
106304 return UA_STATUSCODE_BADINTERNALERROR;
106305
106306 /* Get rid of any trailing \n */
106307 size_t len = strlen(s: buf);
106308 if(len == 0)
106309 return UA_STATUSCODE_BADINTERNALERROR;
106310 if(buf[len-1] == '\n')
106311 buf[len-1] = 0;
106312
106313 *password = UA_BYTESTRING_ALLOC(buf);
106314 return UA_STATUSCODE_GOOD;
106315}
106316#endif
106317
106318UA_Server *
106319UA_Server_new(void) {
106320 UA_ServerConfig config;
106321 memset(s: &config, c: 0, n: sizeof(UA_ServerConfig));
106322 UA_StatusCode res = UA_ServerConfig_setDefault(config: &config);
106323 if(res != UA_STATUSCODE_GOOD)
106324 return NULL;
106325 return UA_Server_newWithConfig(config: &config);
106326}
106327
106328#if defined(UA_ARCHITECTURE_POSIX) || defined(UA_ARCHITECTURE_WIN32)
106329
106330/* Required for the definition of SIGINT */
106331#include <signal.h>
106332
106333struct InterruptContext {
106334 UA_Server *server;
106335 UA_Boolean running;
106336};
106337
106338static void
106339shutdownServer(UA_Server *server, void *context) {
106340 struct InterruptContext *ic = (struct InterruptContext*)context;
106341 UA_ServerConfig *config = UA_Server_getConfig(server: ic->server);
106342 UA_LOG_INFO(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
106343 msg: "Stopping the server");
106344 ic->running = false;
106345}
106346
106347static void
106348interruptServer(UA_InterruptManager *im, uintptr_t interruptHandle,
106349 void *context, const UA_KeyValueMap *parameters) {
106350 struct InterruptContext *ic = (struct InterruptContext*)context;
106351 UA_ServerConfig *config = UA_Server_getConfig(server: ic->server);
106352
106353 if(config->shutdownDelay <= 0.0) {
106354 UA_LOG_INFO(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
106355 msg: "Received SIGINT interrupt. Stopping the server.");
106356 ic->running = false;
106357 return;
106358 }
106359
106360 UA_LOG_INFO(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
106361 msg: "Received SIGINT interrupt. Stopping the server in %.2fs.",
106362 config->shutdownDelay / 1000.0);
106363
106364 UA_UInt32 secondsTillShutdown = (UA_UInt32)(config->shutdownDelay / 1000.0);
106365 UA_Variant val;
106366 UA_Variant_setScalar(v: &val, p: &secondsTillShutdown, type: &UA_TYPES[UA_TYPES_UINT32]);
106367 UA_Server_writeValue(server: ic->server,
106368 nodeId: UA_NODEID_NUMERIC(nsIndex: 0, UA_NS0ID_SERVER_SERVERSTATUS_SECONDSTILLSHUTDOWN), value: val);
106369 UA_Server_addTimedCallback(server: ic->server, callback: shutdownServer, data: ic, date: UA_DateTime_nowMonotonic() +
106370 (UA_DateTime)(config->shutdownDelay * UA_DATETIME_MSEC),
106371 NULL);
106372
106373 /* Notify the application that the server is stopping */
106374 if(config->notifyLifecycleState)
106375 config->notifyLifecycleState(ic->server, UA_LIFECYCLESTATE_STOPPING);
106376}
106377
106378UA_StatusCode
106379UA_Server_runUntilInterrupt(UA_Server *server) {
106380 if(!server)
106381 return UA_STATUSCODE_BADINTERNALERROR;
106382 UA_ServerConfig *config = UA_Server_getConfig(server);
106383 UA_EventLoop *el = config->eventLoop;
106384 if(!el)
106385 return UA_STATUSCODE_BADINTERNALERROR;
106386
106387 /* Get the interrupt manager */
106388 UA_EventSource *es = el->eventSources;
106389 while(es) {
106390 if(es->eventSourceType == UA_EVENTSOURCETYPE_INTERRUPTMANAGER)
106391 break;
106392 es = es->next;
106393 }
106394 if(!es) {
106395 UA_LOG_ERROR(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
106396 msg: "No Interrupt EventSource configured");
106397 return UA_STATUSCODE_BADINTERNALERROR;
106398 }
106399 UA_InterruptManager *im = (UA_InterruptManager*)es;
106400
106401 /* Register the interrupt */
106402 struct InterruptContext ic;
106403 ic.server = server;
106404 ic.running = true;
106405 UA_StatusCode retval =
106406 im->registerInterrupt(im, SIGINT, &UA_KEYVALUEMAP_NULL,
106407 interruptServer, &ic);
106408 if(retval != UA_STATUSCODE_GOOD) {
106409 UA_LOG_ERROR(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
106410 msg: "Could not register the interrupt with status code %s",
106411 UA_StatusCode_name(code: retval));
106412 return retval;
106413 }
106414
106415 /* Run the server */
106416 retval = UA_Server_run_startup(server);
106417 if(retval != UA_STATUSCODE_GOOD)
106418 goto deregister_interrupt;
106419 while(ic.running) {
106420 UA_Server_run_iterate(server, true);
106421 }
106422
106423 /* Shut down the server */
106424 retval = UA_Server_run_shutdown(server);
106425
106426 /* Deregister the interrupt */
106427 deregister_interrupt:
106428 im->deregisterInterrupt(im, SIGINT);
106429 return retval;
106430}
106431
106432#endif /* defined(UA_ARCHITECTURE_POSIX) || defined(UA_ARCHITECTURE_WIN32) */
106433
106434/*******************************/
106435/* Default Connection Settings */
106436/*******************************/
106437
106438const UA_ConnectionConfig UA_ConnectionConfig_default = {
106439 0, /* .protocolVersion */
106440 1 << 16, /* .sendBufferSize, 64k per chunk */
106441 1 << 16, /* .recvBufferSize, 64k per chunk */
106442 1 << 29, /* .localMaxMessageSize, 512 MB */
106443 1 << 29, /* .remoteMaxMessageSize, 512 MB */
106444 1 << 14, /* .localMaxChunkCount, 16k */
106445 1 << 14 /* .remoteMaxChunkCount, 16k */
106446};
106447
106448/***************************/
106449/* Default Server Settings */
106450/***************************/
106451
106452#define MANUFACTURER_NAME "open62541"
106453#define PRODUCT_NAME "open62541 OPC UA Server"
106454#define PRODUCT_URI "http://open62541.org"
106455#define APPLICATION_NAME "open62541-based OPC UA Application"
106456#define APPLICATION_URI "urn:unconfigured:application"
106457#define APPLICATION_URI_SERVER "urn:open62541.server.application"
106458
106459#ifdef UA_INCLUDE_INSECURE_POLICIES
106460# define SECURITY_POLICY_SIZE 5
106461#else
106462# define SECURITY_POLICY_SIZE 3
106463#endif
106464
106465#define STRINGIFY(arg) #arg
106466#define VERSION(MAJOR, MINOR, PATCH, LABEL) \
106467 STRINGIFY(MAJOR) "." STRINGIFY(MINOR) "." STRINGIFY(PATCH) LABEL
106468
106469static UA_StatusCode
106470addEndpoint(UA_ServerConfig *conf,
106471 const UA_SecurityPolicy *securityPolicy,
106472 UA_MessageSecurityMode securityMode) {
106473 /* Test if the endpoint already exists */
106474 for(size_t i = 0; i < conf->endpointsSize; i++) {
106475 UA_EndpointDescription *ep = &conf->endpoints[i];
106476 if(!UA_String_equal(p1: &securityPolicy->policyUri, p2: &ep->securityPolicyUri))
106477 continue;
106478 if(ep->securityMode != securityMode)
106479 continue;
106480 return UA_STATUSCODE_GOOD;
106481 }
106482
106483 /* Reallocate the array size */
106484 UA_EndpointDescription *tmp = (UA_EndpointDescription *)
106485 UA_realloc(ptr: conf->endpoints,
106486 size: sizeof(UA_EndpointDescription) * (1 + conf->endpointsSize));
106487 if(!tmp)
106488 return UA_STATUSCODE_BADOUTOFMEMORY;
106489 conf->endpoints = tmp;
106490
106491 /* The following fields are overwritten internally with up-to-date
106492 * information from the server config:
106493 *
106494 * UserTokenPolicies
106495 * ApplicationDescription (server)
106496 * ServerCertificate
106497 * EndpointURL */
106498 UA_EndpointDescription *endpoint = &conf->endpoints[conf->endpointsSize];
106499 UA_EndpointDescription_init(p: endpoint);
106500 endpoint->transportProfileUri =
106501 UA_STRING_ALLOC("http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary");
106502 endpoint->securityMode = securityMode;
106503
106504 /* A numeric value that indicates how secure the EndpointDescription is compared to other EndpointDescriptions
106505 * for the same Server. A value of 0 indicates that the EndpointDescription is not recommended and is only
106506 * supported for backward compatibility. A higher value indicates better security. */
106507 UA_String noneuri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#None");
106508 UA_String basic128uri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15");
106509 UA_String basic256uri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Basic256");
106510 if(UA_String_equal(p1: &securityPolicy->policyUri, p2: &noneuri) ||
106511 UA_String_equal(p1: &securityPolicy->policyUri, p2: &basic128uri) ||
106512 UA_String_equal(p1: &securityPolicy->policyUri, p2: &basic256uri)) {
106513 endpoint->securityLevel = 0;
106514 } else {
106515 endpoint->securityLevel = 1;
106516 }
106517
106518 UA_StatusCode retval = UA_String_copy(src: &securityPolicy->policyUri,
106519 dst: &endpoint->securityPolicyUri);
106520
106521 if(retval == UA_STATUSCODE_GOOD) {
106522 conf->endpointsSize++;
106523 } else {
106524 UA_EndpointDescription_clear(p: endpoint);
106525 if(conf->endpointsSize == 0) {
106526 UA_free(ptr: conf->endpoints);
106527 conf->endpoints = NULL;
106528 }
106529 }
106530
106531 return retval;
106532}
106533
106534static UA_StatusCode
106535setDefaultConfig(UA_ServerConfig *conf, UA_UInt16 portNumber) {
106536 if(!conf)
106537 return UA_STATUSCODE_BADINVALIDARGUMENT;
106538
106539 /* NodeStore */
106540 if(conf->nodestore.context == NULL)
106541 UA_Nodestore_HashMap(ns: &conf->nodestore);
106542
106543 /* Logging */
106544 if(conf->logging == NULL)
106545 conf->logging = UA_Log_Stdout_new(minlevel: UA_LOGLEVEL_INFO);
106546
106547 /* EventLoop */
106548 if(conf->eventLoop == NULL) {
106549 conf->eventLoop = UA_EventLoop_new_POSIX(logger: conf->logging);
106550 if(conf->eventLoop == NULL)
106551 return UA_STATUSCODE_BADOUTOFMEMORY;
106552
106553 conf->externalEventLoop = false;
106554
106555 /* Add the TCP connection manager */
106556 UA_ConnectionManager *tcpCM =
106557 UA_ConnectionManager_new_POSIX_TCP(eventSourceName: UA_STRING(chars: "tcp connection manager"));
106558 if(tcpCM)
106559 conf->eventLoop->registerEventSource(conf->eventLoop, (UA_EventSource *)tcpCM);
106560
106561 /* Add the UDP connection manager */
106562 UA_ConnectionManager *udpCM =
106563 UA_ConnectionManager_new_POSIX_UDP(eventSourceName: UA_STRING(chars: "udp connection manager"));
106564 if(udpCM)
106565 conf->eventLoop->registerEventSource(conf->eventLoop, (UA_EventSource *)udpCM);
106566
106567 /* Add the Ethernet connection manager */
106568#if defined(UA_ARCHITECTURE_POSIX) && (defined(__linux__))
106569 UA_ConnectionManager *ethCM =
106570 UA_ConnectionManager_new_POSIX_Ethernet(eventSourceName: UA_STRING(chars: "eth connection manager"));
106571 if(ethCM)
106572 conf->eventLoop->registerEventSource(conf->eventLoop, (UA_EventSource *)ethCM);
106573#endif
106574
106575 /* Add the interrupt manager */
106576 UA_InterruptManager *im = UA_InterruptManager_new_POSIX(eventSourceName: UA_STRING(chars: "interrupt manager"));
106577 if(im) {
106578 conf->eventLoop->registerEventSource(conf->eventLoop, &im->eventSource);
106579 } else {
106580 UA_LOG_WARNING(logger: conf->logging, category: UA_LOGCATEGORY_USERLAND,
106581 msg: "Cannot create the Interrupt Manager (only relevant if used)");
106582 }
106583#ifdef UA_ENABLE_MQTT
106584 /* Add the MQTT connection manager */
106585 UA_ConnectionManager *mqttCM =
106586 UA_ConnectionManager_new_MQTT(UA_STRING("mqtt connection manager"));
106587 if(mqttCM)
106588 conf->eventLoop->registerEventSource(conf->eventLoop, (UA_EventSource *)mqttCM);
106589#endif
106590 }
106591 if(conf->eventLoop != NULL) {
106592 if(conf->eventLoop->state != UA_EVENTLOOPSTATE_STARTED) {
106593 UA_StatusCode statusCode = conf->eventLoop->start(conf->eventLoop);
106594 if(statusCode != UA_STATUSCODE_GOOD) {
106595 return statusCode;
106596 }
106597 }
106598 }
106599
106600 /* If a second server is started later it can "steal" the port.
106601 * Having port reuse enabled is important for development.
106602 * Otherwise a long TCP TIME_WAIT is required before the port can be used again. */
106603 conf->tcpReuseAddr = true;
106604
106605 /* --> Start setting the default static config <-- */
106606
106607 conf->shutdownDelay = 0.0;
106608
106609 /* Server Description */
106610 UA_BuildInfo_clear(p: &conf->buildInfo);
106611 conf->buildInfo.productUri = UA_STRING_ALLOC(PRODUCT_URI);
106612 conf->buildInfo.manufacturerName = UA_STRING_ALLOC(MANUFACTURER_NAME);
106613 conf->buildInfo.productName = UA_STRING_ALLOC(PRODUCT_NAME);
106614 conf->buildInfo.softwareVersion =
106615 UA_STRING_ALLOC(VERSION(UA_OPEN62541_VER_MAJOR, UA_OPEN62541_VER_MINOR,
106616 UA_OPEN62541_VER_PATCH, UA_OPEN62541_VER_LABEL));
106617 conf->buildInfo.buildNumber = UA_STRING_ALLOC(__DATE__ " " __TIME__);
106618 conf->buildInfo.buildDate = UA_DateTime_now();
106619
106620 UA_ApplicationDescription_clear(p: &conf->applicationDescription);
106621 conf->applicationDescription.applicationUri = UA_STRING_ALLOC(APPLICATION_URI_SERVER);
106622 conf->applicationDescription.productUri = UA_STRING_ALLOC(PRODUCT_URI);
106623 conf->applicationDescription.applicationName =
106624 UA_LOCALIZEDTEXT_ALLOC(locale: "en", APPLICATION_NAME);
106625 conf->applicationDescription.applicationType = UA_APPLICATIONTYPE_SERVER;
106626 /* conf->applicationDescription.gatewayServerUri = UA_STRING_NULL; */
106627 /* conf->applicationDescription.discoveryProfileUri = UA_STRING_NULL; */
106628 /* conf->applicationDescription.discoveryUrlsSize = 0; */
106629 /* conf->applicationDescription.discoveryUrls = NULL; */
106630
106631#ifdef UA_ENABLE_DISCOVERY_MULTICAST
106632 UA_MdnsDiscoveryConfiguration_clear(&conf->mdnsConfig);
106633 conf->mdnsInterfaceIP = UA_STRING_NULL;
106634# if !defined(UA_HAS_GETIFADDR)
106635 conf->mdnsIpAddressList = NULL;
106636 conf->mdnsIpAddressListSize = 0;
106637# endif
106638#endif
106639
106640 /* Custom DataTypes */
106641 /* conf->customDataTypesSize = 0; */
106642 /* conf->customDataTypes = NULL; */
106643
106644 /* Networking */
106645 /* Set up the local ServerUrls. They are used during startup to initialize
106646 * the server sockets. */
106647 UA_String serverUrls[1];
106648 size_t serverUrlsSize = 0;
106649 char serverUrlBuffer[1][512];
106650
106651 if(portNumber == 0) {
106652 UA_LOG_WARNING(logger: conf->logging, category: UA_LOGCATEGORY_USERLAND,
106653 msg: "Dynamic port assignment will be used.");
106654 }
106655
106656 if(conf->serverUrlsSize > 0) {
106657 UA_LOG_WARNING(logger: conf->logging, category: UA_LOGCATEGORY_USERLAND,
106658 msg: "ServerUrls already set. Overriding.");
106659 UA_Array_delete(p: conf->serverUrls, size: conf->serverUrlsSize,
106660 type: &UA_TYPES[UA_TYPES_STRING]);
106661 conf->serverUrls = NULL;
106662 conf->serverUrlsSize = 0;
106663 }
106664
106665 /* Listen on all interfaces (also external). This must be the first
106666 * entry if this is desired. Otherwise some interfaces may be blocked
106667 * (already in use) with a hostname that is only locally reachable.*/
106668 mp_snprintf(s: serverUrlBuffer[0], n: sizeof(serverUrlBuffer[0]),
106669 format: "opc.tcp://:%u", portNumber);
106670 serverUrls[serverUrlsSize] = UA_STRING(chars: serverUrlBuffer[0]);
106671 serverUrlsSize++;
106672
106673 /* Add to the config */
106674 UA_StatusCode retval =
106675 UA_Array_copy(src: serverUrls, size: serverUrlsSize,
106676 dst: (void**)&conf->serverUrls, type: &UA_TYPES[UA_TYPES_STRING]);
106677 if(retval != UA_STATUSCODE_GOOD)
106678 return retval;
106679 conf->serverUrlsSize = serverUrlsSize;
106680
106681 /* Endpoints */
106682 /* conf->endpoints = {0, NULL}; */
106683
106684 /* Set Logger for Certificate Verification */
106685 if(!conf->secureChannelPKI.logging)
106686 conf->secureChannelPKI.logging = conf->logging;
106687 if(!conf->sessionPKI.logging)
106688 conf->sessionPKI.logging = conf->logging;
106689
106690 /* Certificate Verification that accepts every certificate. Can be
106691 * overwritten when the policy is specialized. */
106692 UA_CertificateVerification_AcceptAll(cv: &conf->secureChannelPKI);
106693
106694 UA_CertificateVerification_AcceptAll(cv: &conf->sessionPKI);
106695
106696 /* * Global Node Lifecycle * */
106697 /* conf->nodeLifecycle.constructor = NULL; */
106698 /* conf->nodeLifecycle.destructor = NULL; */
106699 /* conf->nodeLifecycle.createOptionalChild = NULL; */
106700 /* conf->nodeLifecycle.generateChildNodeId = NULL; */
106701 conf->modellingRulesOnInstances = true;
106702
106703 /* Limits for SecureChannels */
106704 conf->maxSecureChannels = 100;
106705 conf->maxSecurityTokenLifetime = 10 * 60 * 1000; /* 10 minutes */
106706
106707 /* Limits for Sessions */
106708 conf->maxSessions = 100;
106709 conf->maxSessionTimeout = 60.0 * 60.0 * 1000.0; /* 1h */
106710
106711#ifdef UA_ENABLE_SUBSCRIPTIONS
106712 /* Limits for Subscriptions */
106713 conf->publishingIntervalLimits = UA_DURATIONRANGE(min: 100.0, max: 3600.0 * 1000.0);
106714 conf->lifeTimeCountLimits = UA_UINT32RANGE(min: 3, max: 15000);
106715 conf->keepAliveCountLimits = UA_UINT32RANGE(min: 1, max: 100);
106716 conf->maxNotificationsPerPublish = 1000;
106717 conf->enableRetransmissionQueue = true;
106718 conf->maxRetransmissionQueueSize = 0; /* unlimited */
106719# ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
106720 conf->maxEventsPerNode = 0; /* unlimited */
106721# endif
106722
106723 /* Limits for MonitoredItems */
106724 conf->samplingIntervalLimits = UA_DURATIONRANGE(min: 50.0, max: 24.0 * 3600.0 * 1000.0);
106725 conf->queueSizeLimits = UA_UINT32RANGE(min: 1, max: 100);
106726#endif
106727
106728#ifdef UA_ENABLE_DISCOVERY
106729 conf->discoveryCleanupTimeout = 60 * 60;
106730#endif
106731
106732#ifdef UA_ENABLE_HISTORIZING
106733 /* conf->accessHistoryDataCapability = false; */
106734 /* conf->maxReturnDataValues = 0; */
106735
106736 /* conf->accessHistoryEventsCapability = false; */
106737 /* conf->maxReturnEventValues = 0; */
106738
106739 /* conf->insertDataCapability = false; */
106740 /* conf->insertEventCapability = false; */
106741 /* conf->insertAnnotationsCapability = false; */
106742
106743 /* conf->replaceDataCapability = false; */
106744 /* conf->replaceEventCapability = false; */
106745
106746 /* conf->updateDataCapability = false; */
106747 /* conf->updateEventCapability = false; */
106748
106749 /* conf->deleteRawCapability = false; */
106750 /* conf->deleteEventCapability = false; */
106751 /* conf->deleteAtTimeDataCapability = false; */
106752#endif
106753
106754#if UA_MULTITHREADING >= 100
106755 conf->maxAsyncOperationQueueSize = 0;
106756 conf->asyncOperationTimeout = 120000; /* Async Operation Timeout in ms (2 minutes) */
106757#endif
106758
106759#ifdef UA_ENABLE_PUBSUB
106760 conf->pubSubConfig.enableDeltaFrames = true;
106761#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
106762 conf->pubSubConfig.enableInformationModelMethods = true;
106763#endif
106764#endif
106765
106766 /* --> Finish setting the default static config <-- */
106767
106768 return UA_STATUSCODE_GOOD;
106769}
106770
106771UA_EXPORT UA_StatusCode
106772UA_ServerConfig_setBasics(UA_ServerConfig* conf) {
106773 return UA_ServerConfig_setBasics_withPort(conf, portNumber: 4840);
106774}
106775
106776UA_EXPORT UA_StatusCode
106777UA_ServerConfig_setBasics_withPort(UA_ServerConfig* conf, UA_UInt16 portNumber) {
106778 return setDefaultConfig(conf, portNumber);
106779}
106780
106781UA_EXPORT UA_StatusCode
106782UA_ServerConfig_addSecurityPolicyNone(UA_ServerConfig *config,
106783 const UA_ByteString *certificate) {
106784 /* Allocate the SecurityPolicies */
106785 UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
106786 UA_realloc(ptr: config->securityPolicies,
106787 size: sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
106788 if(!tmp)
106789 return UA_STATUSCODE_BADOUTOFMEMORY;
106790 config->securityPolicies = tmp;
106791
106792 /* Populate the SecurityPolicies */
106793 UA_ByteString localCertificate = UA_BYTESTRING_NULL;
106794 if(certificate)
106795 localCertificate = *certificate;
106796 UA_StatusCode retval =
106797 UA_SecurityPolicy_None(policy: &config->securityPolicies[config->securityPoliciesSize],
106798 localCertificate, logger: config->logging);
106799 if(retval != UA_STATUSCODE_GOOD) {
106800 if(config->securityPoliciesSize == 0) {
106801 UA_free(ptr: config->securityPolicies);
106802 config->securityPolicies = NULL;
106803 }
106804 return retval;
106805 }
106806
106807 config->securityPoliciesSize++;
106808 return UA_STATUSCODE_GOOD;
106809}
106810
106811UA_EXPORT UA_StatusCode
106812UA_ServerConfig_addEndpoint(UA_ServerConfig *config, const UA_String securityPolicyUri,
106813 UA_MessageSecurityMode securityMode) {
106814 /* Lookup the security policy */
106815 const UA_SecurityPolicy *policy = NULL;
106816 for (size_t i = 0; i < config->securityPoliciesSize; ++i) {
106817 if (UA_String_equal(p1: &securityPolicyUri, p2: &config->securityPolicies[i].policyUri)) {
106818 policy = &config->securityPolicies[i];
106819 break;
106820 }
106821 }
106822 if(!policy)
106823 return UA_STATUSCODE_BADINVALIDARGUMENT;
106824
106825 /* Populate the endpoint */
106826 return addEndpoint(conf: config, securityPolicy: policy, securityMode);
106827}
106828
106829UA_EXPORT UA_StatusCode
106830UA_ServerConfig_addAllEndpoints(UA_ServerConfig *config) {
106831 /* Populate the endpoints */
106832 for(size_t i = 0; i < config->securityPoliciesSize; ++i) {
106833 if(UA_String_equal(p1: &UA_SECURITY_POLICY_NONE_URI, p2: &config->securityPolicies[i].policyUri)) {
106834 UA_StatusCode retval =
106835 addEndpoint(conf: config, securityPolicy: &config->securityPolicies[i], securityMode: UA_MESSAGESECURITYMODE_NONE);
106836 if(retval != UA_STATUSCODE_GOOD)
106837 return retval;
106838 } else {
106839 UA_StatusCode retval =
106840 addEndpoint(conf: config, securityPolicy: &config->securityPolicies[i], securityMode: UA_MESSAGESECURITYMODE_SIGN);
106841 if(retval != UA_STATUSCODE_GOOD)
106842 return retval;
106843 retval = addEndpoint(conf: config, securityPolicy: &config->securityPolicies[i],
106844 securityMode: UA_MESSAGESECURITYMODE_SIGNANDENCRYPT);
106845 if(retval != UA_STATUSCODE_GOOD)
106846 return retval;
106847 }
106848 }
106849
106850 return UA_STATUSCODE_GOOD;
106851}
106852
106853UA_EXPORT UA_StatusCode
106854UA_ServerConfig_addAllSecureEndpoints(UA_ServerConfig *config) {
106855 UA_String noneuri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#None");
106856 UA_String basic128uri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15");
106857 UA_String basic256uri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Basic256");
106858
106859 /* Delete all predefined endpoints. */
106860 if(config->endpointsSize > 0) {
106861 for(size_t i = 0; i < config->endpointsSize; ++i)
106862 UA_EndpointDescription_clear(p: &config->endpoints[i]);
106863
106864 UA_free(ptr: config->endpoints);
106865 config->endpoints = NULL;
106866 config->endpointsSize = 0;
106867 }
106868
106869 /* Populate the endpoints */
106870 for(size_t i = 0; i < config->securityPoliciesSize; ++i) {
106871 /* Skip the None and all deprecated policies */
106872 if(UA_String_equal(p1: &config->securityPolicies[i].policyUri, p2: &noneuri) ||
106873 UA_String_equal(p1: &config->securityPolicies[i].policyUri, p2: &basic128uri) ||
106874 UA_String_equal(p1: &config->securityPolicies[i].policyUri, p2: &basic256uri)) {
106875 continue;
106876 }
106877 UA_StatusCode retval =
106878 addEndpoint(conf: config, securityPolicy: &config->securityPolicies[i], securityMode: UA_MESSAGESECURITYMODE_SIGN);
106879 if(retval != UA_STATUSCODE_GOOD)
106880 return retval;
106881 retval = addEndpoint(conf: config, securityPolicy: &config->securityPolicies[i],
106882 securityMode: UA_MESSAGESECURITYMODE_SIGNANDENCRYPT);
106883 if(retval != UA_STATUSCODE_GOOD)
106884 return retval;
106885 }
106886
106887 return UA_STATUSCODE_GOOD;
106888}
106889
106890UA_EXPORT UA_StatusCode
106891UA_ServerConfig_setMinimalCustomBuffer(UA_ServerConfig *config, UA_UInt16 portNumber,
106892 const UA_ByteString *certificate,
106893 UA_UInt32 sendBufferSize,
106894 UA_UInt32 recvBufferSize) {
106895 if(!config)
106896 return UA_STATUSCODE_BADINVALIDARGUMENT;
106897
106898 UA_StatusCode retval = setDefaultConfig(conf: config, portNumber);
106899 if(retval != UA_STATUSCODE_GOOD) {
106900 UA_ServerConfig_clean(config);
106901 return retval;
106902 }
106903
106904 /* Set the TCP settings */
106905 config->tcpBufSize = recvBufferSize;
106906
106907 /* Allocate the SecurityPolicies */
106908 retval = UA_ServerConfig_addSecurityPolicyNone(config, certificate);
106909 if(retval != UA_STATUSCODE_GOOD) {
106910 UA_ServerConfig_clean(config);
106911 return retval;
106912 }
106913
106914 /* Initialize the Access Control plugin */
106915 retval = UA_AccessControl_default(config, true, NULL, usernamePasswordLoginSize: 0, NULL);
106916 if(retval != UA_STATUSCODE_GOOD) {
106917 UA_ServerConfig_clean(config);
106918 return retval;
106919 }
106920
106921 /* Allocate the endpoint */
106922 retval = UA_ServerConfig_addEndpoint(config, securityPolicyUri: UA_SECURITY_POLICY_NONE_URI,
106923 securityMode: UA_MESSAGESECURITYMODE_NONE);
106924 if(retval != UA_STATUSCODE_GOOD) {
106925 UA_ServerConfig_clean(config);
106926 return retval;
106927 }
106928
106929 return UA_STATUSCODE_GOOD;
106930}
106931
106932#ifdef UA_ENABLE_ENCRYPTION
106933
106934UA_EXPORT UA_StatusCode
106935UA_ServerConfig_addSecurityPolicyBasic128Rsa15(UA_ServerConfig *config,
106936 const UA_ByteString *certificate,
106937 const UA_ByteString *privateKey) {
106938 /* Allocate the SecurityPolicies */
106939 UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
106940 UA_realloc(ptr: config->securityPolicies,
106941 size: sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
106942 if(!tmp)
106943 return UA_STATUSCODE_BADOUTOFMEMORY;
106944 config->securityPolicies = tmp;
106945
106946 /* Populate the SecurityPolicies */
106947 UA_ByteString localCertificate = UA_BYTESTRING_NULL;
106948 UA_ByteString localPrivateKey = UA_BYTESTRING_NULL;
106949 if(certificate)
106950 localCertificate = *certificate;
106951 if(privateKey)
106952 localPrivateKey = *privateKey;
106953 UA_StatusCode retval =
106954 UA_SecurityPolicy_Basic128Rsa15(policy: &config->securityPolicies[config->securityPoliciesSize],
106955 localCertificate, localPrivateKey, logger: config->logging);
106956 if(retval != UA_STATUSCODE_GOOD) {
106957 if(config->securityPoliciesSize == 0) {
106958 UA_free(ptr: config->securityPolicies);
106959 config->securityPolicies = NULL;
106960 }
106961 return retval;
106962 }
106963
106964 config->securityPoliciesSize++;
106965 return UA_STATUSCODE_GOOD;
106966}
106967
106968UA_EXPORT UA_StatusCode
106969UA_ServerConfig_addSecurityPolicyBasic256(UA_ServerConfig *config,
106970 const UA_ByteString *certificate,
106971 const UA_ByteString *privateKey) {
106972 /* Allocate the SecurityPolicies */
106973 UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
106974 UA_realloc(ptr: config->securityPolicies,
106975 size: sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
106976 if(!tmp)
106977 return UA_STATUSCODE_BADOUTOFMEMORY;
106978 config->securityPolicies = tmp;
106979
106980 /* Populate the SecurityPolicies */
106981 UA_ByteString localCertificate = UA_BYTESTRING_NULL;
106982 UA_ByteString localPrivateKey = UA_BYTESTRING_NULL;
106983 if(certificate)
106984 localCertificate = *certificate;
106985 if(privateKey)
106986 localPrivateKey = *privateKey;
106987 UA_StatusCode retval =
106988 UA_SecurityPolicy_Basic256(policy: &config->securityPolicies[config->securityPoliciesSize],
106989 localCertificate, localPrivateKey, logger: config->logging);
106990 if(retval != UA_STATUSCODE_GOOD) {
106991 if(config->securityPoliciesSize == 0) {
106992 UA_free(ptr: config->securityPolicies);
106993 config->securityPolicies = NULL;
106994 }
106995 return retval;
106996 }
106997
106998 config->securityPoliciesSize++;
106999 return UA_STATUSCODE_GOOD;
107000}
107001
107002UA_EXPORT UA_StatusCode
107003UA_ServerConfig_addSecurityPolicyBasic256Sha256(UA_ServerConfig *config,
107004 const UA_ByteString *certificate,
107005 const UA_ByteString *privateKey) {
107006 /* Allocate the SecurityPolicies */
107007 UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
107008 UA_realloc(ptr: config->securityPolicies,
107009 size: sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
107010 if(!tmp)
107011 return UA_STATUSCODE_BADOUTOFMEMORY;
107012 config->securityPolicies = tmp;
107013
107014 /* Populate the SecurityPolicies */
107015 UA_ByteString localCertificate = UA_BYTESTRING_NULL;
107016 UA_ByteString localPrivateKey = UA_BYTESTRING_NULL;
107017 if(certificate)
107018 localCertificate = *certificate;
107019 if(privateKey)
107020 localPrivateKey = *privateKey;
107021 UA_StatusCode retval =
107022 UA_SecurityPolicy_Basic256Sha256(policy: &config->securityPolicies[config->securityPoliciesSize],
107023 localCertificate, localPrivateKey, logger: config->logging);
107024 if(retval != UA_STATUSCODE_GOOD) {
107025 if(config->securityPoliciesSize == 0) {
107026 UA_free(ptr: config->securityPolicies);
107027 config->securityPolicies = NULL;
107028 }
107029 return retval;
107030 }
107031
107032 config->securityPoliciesSize++;
107033 return UA_STATUSCODE_GOOD;
107034}
107035
107036UA_EXPORT UA_StatusCode
107037UA_ServerConfig_addSecurityPolicyAes128Sha256RsaOaep(UA_ServerConfig *config,
107038 const UA_ByteString *certificate,
107039 const UA_ByteString *privateKey) {
107040 /* Allocate the SecurityPolicies */
107041 UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
107042 UA_realloc(ptr: config->securityPolicies,
107043 size: sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
107044 if(!tmp)
107045 return UA_STATUSCODE_BADOUTOFMEMORY;
107046 config->securityPolicies = tmp;
107047
107048 /* Populate the SecurityPolicies */
107049 UA_ByteString localCertificate = UA_BYTESTRING_NULL;
107050 UA_ByteString localPrivateKey = UA_BYTESTRING_NULL;
107051 if(certificate)
107052 localCertificate = *certificate;
107053 if(privateKey)
107054 localPrivateKey = *privateKey;
107055 UA_StatusCode retval =
107056 UA_SecurityPolicy_Aes128Sha256RsaOaep(policy: &config->securityPolicies[config->securityPoliciesSize],
107057 localCertificate, localPrivateKey, logger: config->logging);
107058 if(retval != UA_STATUSCODE_GOOD) {
107059 if(config->securityPoliciesSize == 0) {
107060 UA_free(ptr: config->securityPolicies);
107061 config->securityPolicies = NULL;
107062 }
107063 return retval;
107064 }
107065
107066 config->securityPoliciesSize++;
107067 return UA_STATUSCODE_GOOD;
107068}
107069
107070UA_EXPORT UA_StatusCode
107071UA_ServerConfig_addSecurityPolicyAes256Sha256RsaPss(UA_ServerConfig *config,
107072 const UA_ByteString *certificate,
107073 const UA_ByteString *privateKey) {
107074 /* Allocate the SecurityPolicies */
107075 UA_SecurityPolicy *tmp = (UA_SecurityPolicy *)
107076 UA_realloc(ptr: config->securityPolicies,
107077 size: sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize));
107078 if(!tmp)
107079 return UA_STATUSCODE_BADOUTOFMEMORY;
107080 config->securityPolicies = tmp;
107081
107082 /* Populate the SecurityPolicies */
107083 UA_ByteString localCertificate = UA_BYTESTRING_NULL;
107084 UA_ByteString localPrivateKey = UA_BYTESTRING_NULL;
107085 if(certificate)
107086 localCertificate = *certificate;
107087 if(privateKey)
107088 localPrivateKey = *privateKey;
107089 UA_StatusCode retval =
107090 UA_SecurityPolicy_Aes256Sha256RsaPss(policy: &config->securityPolicies[config->securityPoliciesSize],
107091 localCertificate, localPrivateKey, logger: config->logging);
107092 if(retval != UA_STATUSCODE_GOOD) {
107093 if(config->securityPoliciesSize == 0) {
107094 UA_free(ptr: config->securityPolicies);
107095 config->securityPolicies = NULL;
107096 }
107097 return retval;
107098 }
107099
107100 config->securityPoliciesSize++;
107101 return UA_STATUSCODE_GOOD;
107102}
107103
107104/* Always returns UA_STATUSCODE_GOOD. Logs a warning if policies could not be added. */
107105static UA_StatusCode
107106addAllSecurityPolicies(UA_ServerConfig *config, const UA_ByteString *certificate,
107107 const UA_ByteString *privateKey, UA_Boolean onlySecure) {
107108 /* Populate the SecurityPolicies */
107109 UA_ByteString localCertificate = UA_BYTESTRING_NULL;
107110 UA_ByteString localPrivateKey = UA_BYTESTRING_NULL;
107111 UA_StatusCode retval = UA_STATUSCODE_GOOD;
107112 if(certificate)
107113 localCertificate = *certificate;
107114 if(privateKey)
107115 localPrivateKey = *privateKey;
107116
107117 /* Load the private key and convert to the DER format. Use an empty password
107118 * on the first try -- maybe the key does not require a password. */
107119 UA_ByteString decryptedPrivateKey = UA_BYTESTRING_NULL;
107120 UA_ByteString keyPassword = UA_BYTESTRING_NULL;
107121 UA_StatusCode keySuccess = UA_STATUSCODE_GOOD;
107122
107123 if (privateKey && privateKey->length > 0)
107124 keySuccess = UA_PKI_decryptPrivateKey(privateKey: localPrivateKey, password: keyPassword,
107125 outDerKey: &decryptedPrivateKey);
107126
107127 /* Get the password and decrypt. An application might want to loop / retry
107128 * here to allow users to correct their entry. */
107129 if(keySuccess != UA_STATUSCODE_GOOD) {
107130 if(config->privateKeyPasswordCallback)
107131 keySuccess = config->privateKeyPasswordCallback(config, &keyPassword);
107132 else
107133 keySuccess = readPrivateKeyPassword(password: &keyPassword);
107134 if(keySuccess != UA_STATUSCODE_GOOD)
107135 return keySuccess;
107136 keySuccess = UA_PKI_decryptPrivateKey(privateKey: localPrivateKey, password: keyPassword,
107137 outDerKey: &decryptedPrivateKey);
107138 UA_ByteString_memZero(bs: &keyPassword);
107139 UA_ByteString_clear(p: &keyPassword);
107140 }
107141 if(keySuccess != UA_STATUSCODE_GOOD)
107142 return keySuccess;
107143
107144 /* Basic256Sha256 */
107145 retval = UA_ServerConfig_addSecurityPolicyBasic256Sha256(config, certificate: &localCertificate,
107146 privateKey: &decryptedPrivateKey);
107147 if(retval != UA_STATUSCODE_GOOD) {
107148 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
107149 msg: "Could not add SecurityPolicy#Basic256Sha256 with error code %s",
107150 UA_StatusCode_name(code: retval));
107151 }
107152
107153 /* Aes256Sha256RsaPss */
107154 retval = UA_ServerConfig_addSecurityPolicyAes256Sha256RsaPss(config, certificate: &localCertificate,
107155 privateKey: &decryptedPrivateKey);
107156 if(retval != UA_STATUSCODE_GOOD) {
107157 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
107158 msg: "Could not add SecurityPolicy#Aes256Sha256RsaPss with error code %s",
107159 UA_StatusCode_name(code: retval));
107160 }
107161
107162 /* Aes128Sha256RsaOaep */
107163 retval = UA_ServerConfig_addSecurityPolicyAes128Sha256RsaOaep(config, certificate: &localCertificate,
107164 privateKey: &decryptedPrivateKey);
107165 if(retval != UA_STATUSCODE_GOOD) {
107166 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
107167 msg: "Could not add SecurityPolicy#Aes128Sha256RsaOaep with error code %s",
107168 UA_StatusCode_name(code: retval));
107169 }
107170
107171 if(onlySecure) {
107172 UA_ByteString_memZero(bs: &decryptedPrivateKey);
107173 UA_ByteString_clear(p: &decryptedPrivateKey);
107174 return UA_STATUSCODE_GOOD;
107175 }
107176
107177 /* None */
107178 retval = UA_ServerConfig_addSecurityPolicyNone(config, certificate: &localCertificate);
107179 if(retval != UA_STATUSCODE_GOOD) {
107180 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
107181 msg: "Could not add SecurityPolicy#None with error code %s",
107182 UA_StatusCode_name(code: retval));
107183 }
107184
107185#ifdef UA_INCLUDE_INSECURE_POLICIES
107186 /* Basic128Rsa15 should no longer be used */
107187 retval = UA_ServerConfig_addSecurityPolicyBasic128Rsa15(config, &localCertificate,
107188 &decryptedPrivateKey);
107189 if(retval != UA_STATUSCODE_GOOD) {
107190 UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_USERLAND,
107191 "Could not add SecurityPolicy#Basic128Rsa15 with error code %s",
107192 UA_StatusCode_name(retval));
107193 }
107194
107195 /* Basic256 should no longer be used */
107196 retval = UA_ServerConfig_addSecurityPolicyBasic256(config, &localCertificate,
107197 &decryptedPrivateKey);
107198 if(retval != UA_STATUSCODE_GOOD) {
107199 UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_USERLAND,
107200 "Could not add SecurityPolicy#Basic256 with error code %s",
107201 UA_StatusCode_name(retval));
107202 }
107203#endif
107204
107205 UA_ByteString_memZero(bs: &decryptedPrivateKey);
107206 UA_ByteString_clear(p: &decryptedPrivateKey);
107207 return UA_STATUSCODE_GOOD;
107208}
107209
107210UA_StatusCode
107211UA_ServerConfig_addAllSecurityPolicies(UA_ServerConfig *config,
107212 const UA_ByteString *certificate,
107213 const UA_ByteString *privateKey) {
107214 return addAllSecurityPolicies(config, certificate, privateKey, false);
107215}
107216
107217/* Always returns UA_STATUSCODE_GOOD. Logs a warning if policies could not be added. */
107218UA_StatusCode
107219UA_ServerConfig_addAllSecureSecurityPolicies(UA_ServerConfig *config,
107220 const UA_ByteString *certificate,
107221 const UA_ByteString *privateKey) {
107222 return addAllSecurityPolicies(config, certificate, privateKey, true);
107223
107224}
107225
107226UA_EXPORT UA_StatusCode
107227UA_ServerConfig_setDefaultWithSecurityPolicies(UA_ServerConfig *conf,
107228 UA_UInt16 portNumber,
107229 const UA_ByteString *certificate,
107230 const UA_ByteString *privateKey,
107231 const UA_ByteString *trustList,
107232 size_t trustListSize,
107233 const UA_ByteString *issuerList,
107234 size_t issuerListSize,
107235 const UA_ByteString *revocationList,
107236 size_t revocationListSize) {
107237 UA_StatusCode retval = setDefaultConfig(conf, portNumber);
107238 if(retval != UA_STATUSCODE_GOOD) {
107239 UA_ServerConfig_clean(config: conf);
107240 return retval;
107241 }
107242
107243 retval = UA_CertificateVerification_Trustlist(cv: &conf->sessionPKI,
107244 certificateTrustList: trustList, certificateTrustListSize: trustListSize,
107245 certificateIssuerList: issuerList, certificateIssuerListSize: issuerListSize,
107246 certificateRevocationList: revocationList, certificateRevocationListSize: revocationListSize);
107247 if(retval != UA_STATUSCODE_GOOD)
107248 return retval;
107249
107250 retval = UA_CertificateVerification_Trustlist(cv: &conf->secureChannelPKI,
107251 certificateTrustList: trustList, certificateTrustListSize: trustListSize,
107252 certificateIssuerList: issuerList, certificateIssuerListSize: issuerListSize,
107253 certificateRevocationList: revocationList, certificateRevocationListSize: revocationListSize);
107254 if(retval != UA_STATUSCODE_GOOD)
107255 return retval;
107256
107257 retval = UA_ServerConfig_addAllSecurityPolicies(config: conf, certificate, privateKey);
107258
107259 if(retval == UA_STATUSCODE_GOOD) {
107260 retval = UA_AccessControl_default(config: conf, true, NULL, usernamePasswordLoginSize: 0, NULL);
107261 }
107262 if(retval != UA_STATUSCODE_GOOD) {
107263 UA_ServerConfig_clean(config: conf);
107264 return retval;
107265 }
107266
107267 retval = UA_ServerConfig_addAllEndpoints(config: conf);
107268 if(retval != UA_STATUSCODE_GOOD) {
107269 UA_ServerConfig_clean(config: conf);
107270 return retval;
107271 }
107272
107273 return UA_STATUSCODE_GOOD;
107274}
107275
107276UA_EXPORT UA_StatusCode
107277UA_ServerConfig_setDefaultWithSecureSecurityPolicies(UA_ServerConfig *conf,
107278 UA_UInt16 portNumber,
107279 const UA_ByteString *certificate,
107280 const UA_ByteString *privateKey,
107281 const UA_ByteString *trustList,
107282 size_t trustListSize,
107283 const UA_ByteString *issuerList,
107284 size_t issuerListSize,
107285 const UA_ByteString *revocationList,
107286 size_t revocationListSize) {
107287 UA_StatusCode retval = setDefaultConfig(conf, portNumber);
107288 if(retval != UA_STATUSCODE_GOOD) {
107289 UA_ServerConfig_clean(config: conf);
107290 return retval;
107291 }
107292
107293 retval = UA_CertificateVerification_Trustlist(cv: &conf->sessionPKI,
107294 certificateTrustList: trustList, certificateTrustListSize: trustListSize,
107295 certificateIssuerList: issuerList, certificateIssuerListSize: issuerListSize,
107296 certificateRevocationList: revocationList, certificateRevocationListSize: revocationListSize);
107297 if(retval != UA_STATUSCODE_GOOD)
107298 return retval;
107299
107300 retval = UA_CertificateVerification_Trustlist(cv: &conf->secureChannelPKI,
107301 certificateTrustList: trustList, certificateTrustListSize: trustListSize,
107302 certificateIssuerList: issuerList, certificateIssuerListSize: issuerListSize,
107303 certificateRevocationList: revocationList, certificateRevocationListSize: revocationListSize);
107304 if(retval != UA_STATUSCODE_GOOD)
107305 return retval;
107306
107307 retval = UA_ServerConfig_addAllSecureSecurityPolicies(config: conf, certificate, privateKey);
107308
107309 if(retval == UA_STATUSCODE_GOOD) {
107310 retval = UA_AccessControl_default(config: conf, false, NULL, usernamePasswordLoginSize: 0, NULL);
107311 }
107312 if(retval != UA_STATUSCODE_GOOD) {
107313 UA_ServerConfig_clean(config: conf);
107314 return retval;
107315 }
107316
107317 retval = UA_ServerConfig_addAllSecureEndpoints(config: conf);
107318 if(retval != UA_STATUSCODE_GOOD) {
107319 UA_ServerConfig_clean(config: conf);
107320 return retval;
107321 }
107322 conf->securityPolicyNoneDiscoveryOnly = true;
107323
107324 return UA_STATUSCODE_GOOD;
107325}
107326
107327#endif
107328
107329/***************************/
107330/* Default Client Settings */
107331/***************************/
107332
107333UA_Client * UA_Client_new(void) {
107334 UA_ClientConfig config;
107335 memset(s: &config, c: 0, n: sizeof(UA_ClientConfig));
107336 /* Set up basic usable config including logger and event loop */
107337 UA_StatusCode res = UA_ClientConfig_setDefault(config: &config);
107338 if(res != UA_STATUSCODE_GOOD)
107339 return NULL;
107340 return UA_Client_newWithConfig(config: &config);
107341}
107342
107343UA_StatusCode
107344UA_ClientConfig_setDefault(UA_ClientConfig *config) {
107345 /* The following fields are untouched and OK to leave as NULL or 0:
107346 * clientContext
107347 * userIdentityToken
107348 * securityMode
107349 * securityPolicyUri
107350 * endpoint
107351 * userTokenPolicy
107352 * customDataTypes
107353 * connectivityCheckInterval
107354 * stateCallback
107355 * inactivityCallback
107356 * outStandingPublishRequests
107357 * subscriptionInactivityCallback
107358 * sessionLocaleIds
107359 * sessionLocaleIdsSize */
107360
107361 if(config->timeout == 0)
107362 config->timeout = 5 * 1000; /* 5 seconds */
107363 if(config->secureChannelLifeTime == 0)
107364 config->secureChannelLifeTime = 10 * 60 * 1000; /* 10 minutes */
107365
107366 if(config->logging == NULL)
107367 config->logging = UA_Log_Stdout_new(minlevel: UA_LOGLEVEL_INFO);
107368
107369 /* EventLoop */
107370 if(config->eventLoop == NULL) {
107371 config->eventLoop = UA_EventLoop_new_POSIX(logger: config->logging);
107372 config->externalEventLoop = false;
107373
107374 /* Add the TCP connection manager */
107375 UA_ConnectionManager *tcpCM =
107376 UA_ConnectionManager_new_POSIX_TCP(eventSourceName: UA_STRING(chars: "tcp connection manager"));
107377 config->eventLoop->registerEventSource(config->eventLoop, (UA_EventSource *)tcpCM);
107378
107379 /* Add the UDP connection manager */
107380 UA_ConnectionManager *udpCM =
107381 UA_ConnectionManager_new_POSIX_UDP(eventSourceName: UA_STRING(chars: "udp connection manager"));
107382 config->eventLoop->registerEventSource(config->eventLoop, (UA_EventSource *)udpCM);
107383 }
107384
107385 if(config->localConnectionConfig.recvBufferSize == 0)
107386 config->localConnectionConfig = UA_ConnectionConfig_default;
107387
107388 if(!config->certificateVerification.logging) {
107389 config->certificateVerification.logging = config->logging;
107390 }
107391
107392 if(!config->certificateVerification.verifyCertificate) {
107393 /* Certificate Verification that accepts every certificate. Can be
107394 * overwritten when the policy is specialized. */
107395 UA_CertificateVerification_AcceptAll(cv: &config->certificateVerification);
107396 }
107397
107398 /* With encryption enabled, the applicationUri needs to match the URI from
107399 * the certificate */
107400 if(!config->clientDescription.applicationUri.data)
107401 config->clientDescription.applicationUri = UA_STRING_ALLOC(APPLICATION_URI);
107402 if(config->clientDescription.applicationType == 0)
107403 config->clientDescription.applicationType = UA_APPLICATIONTYPE_CLIENT;
107404
107405 if(config->securityPoliciesSize == 0) {
107406 config->securityPolicies = (UA_SecurityPolicy*)UA_malloc(size: sizeof(UA_SecurityPolicy));
107407 if(!config->securityPolicies)
107408 return UA_STATUSCODE_BADOUTOFMEMORY;
107409 UA_StatusCode retval = UA_SecurityPolicy_None(policy: config->securityPolicies,
107410 localCertificate: UA_BYTESTRING_NULL, logger: config->logging);
107411 if(retval != UA_STATUSCODE_GOOD) {
107412 UA_free(ptr: config->securityPolicies);
107413 config->securityPolicies = NULL;
107414 return retval;
107415 }
107416 config->securityPoliciesSize = 1;
107417 }
107418
107419 if(config->requestedSessionTimeout == 0)
107420 config->requestedSessionTimeout = 1200000;
107421
107422#ifdef UA_ENABLE_SUBSCRIPTIONS
107423 if(config->outStandingPublishRequests == 0)
107424 config->outStandingPublishRequests = 10;
107425#endif
107426
107427 return UA_STATUSCODE_GOOD;
107428}
107429
107430#ifdef UA_ENABLE_ENCRYPTION
107431
107432static UA_StatusCode
107433securityPolicies_addAll(UA_SecurityPolicy *sp, size_t *length,
107434 UA_ByteString certificate, UA_ByteString privateKey, UA_Logger *logging) {
107435 UA_StatusCode retval;
107436 size_t size = *length;
107437
107438#ifdef UA_INCLUDE_INSECURE_POLICIES
107439 /* Basic128Rsa15 is unsecure and should not be used */
107440 retval = UA_SecurityPolicy_Basic128Rsa15(&sp[size], certificate, privateKey, logging);
107441 if(retval == UA_STATUSCODE_GOOD) {
107442 size++;
107443 } else {
107444 UA_LOG_WARNING(logging, UA_LOGCATEGORY_USERLAND,
107445 "Could not add SecurityPolicy#Basic128Rsa15 with error code %s",
107446 UA_StatusCode_name(retval));
107447 }
107448
107449 /* Basic256 is unsecure and should not be used */
107450 retval = UA_SecurityPolicy_Basic256(&sp[size], certificate, privateKey, logging);
107451 if(retval == UA_STATUSCODE_GOOD) {
107452 size++;
107453 } else {
107454 UA_LOG_WARNING(logging, UA_LOGCATEGORY_USERLAND,
107455 "Could not add SecurityPolicy#Basic256 with error code %s",
107456 UA_StatusCode_name(retval));
107457 }
107458#endif
107459 retval = UA_SecurityPolicy_Aes256Sha256RsaPss(policy: &sp[size], localCertificate: certificate, localPrivateKey: privateKey, logger: logging);
107460 if(retval == UA_STATUSCODE_GOOD) {
107461 size++;
107462 } else {
107463 UA_LOG_WARNING(logger: logging, category: UA_LOGCATEGORY_USERLAND,
107464 msg: "Could not add SecurityPolicy#Aes256Sha256RsaPss with error code %s",
107465 UA_StatusCode_name(code: retval));
107466 }
107467
107468 retval = UA_SecurityPolicy_Basic256Sha256(policy: &sp[size], localCertificate: certificate, localPrivateKey: privateKey, logger: logging);
107469 if(retval == UA_STATUSCODE_GOOD) {
107470 size++;
107471 } else {
107472 UA_LOG_WARNING(logger: logging, category: UA_LOGCATEGORY_USERLAND,
107473 msg: "Could not add SecurityPolicy#Basic256Sha256 with error code %s",
107474 UA_StatusCode_name(code: retval));
107475 }
107476
107477 retval = UA_SecurityPolicy_Aes128Sha256RsaOaep(policy: &sp[size], localCertificate: certificate, localPrivateKey: privateKey, logger: logging);
107478 if(retval == UA_STATUSCODE_GOOD) {
107479 size++;
107480 } else {
107481 UA_LOG_WARNING(logger: logging, category: UA_LOGCATEGORY_USERLAND,
107482 msg: "Could not add SecurityPolicy#Aes128Sha256RsaOaep with error code %s",
107483 UA_StatusCode_name(code: retval));
107484 }
107485 *length = size;
107486 return retval;
107487}
107488
107489static UA_StatusCode
107490clientConfig_setAuthenticationSecurityPolicies(UA_ClientConfig *config,
107491 UA_ByteString certificateAuth,
107492 UA_ByteString privateKeyAuth) {
107493 UA_SecurityPolicy *sp = (UA_SecurityPolicy*)
107494 UA_realloc(ptr: config->authSecurityPolicies, size: sizeof(UA_SecurityPolicy) * SECURITY_POLICY_SIZE);
107495 if(!sp)
107496 return UA_STATUSCODE_BADOUTOFMEMORY;
107497 config->authSecurityPolicies = sp;
107498
107499 /* Clean up old SecurityPolicies */
107500 for(size_t i = 0; i < config->authSecurityPoliciesSize; i++) {
107501 config->authSecurityPolicies[i].clear(&config->authSecurityPolicies[i]);
107502 }
107503 config->authSecurityPoliciesSize = 0;
107504
107505 UA_StatusCode retval = securityPolicies_addAll(sp, length: &config->authSecurityPoliciesSize,
107506 certificate: certificateAuth, privateKey: privateKeyAuth, logging: config->logging);
107507
107508 if(config->authSecurityPoliciesSize == 0) {
107509 UA_free(ptr: config->authSecurityPolicies);
107510 config->authSecurityPolicies = NULL;
107511 }
107512
107513 return retval;
107514}
107515
107516UA_StatusCode
107517UA_ClientConfig_setDefaultEncryption(UA_ClientConfig *config,
107518 UA_ByteString localCertificate, UA_ByteString privateKey,
107519 const UA_ByteString *trustList, size_t trustListSize,
107520 const UA_ByteString *revocationList, size_t revocationListSize) {
107521 UA_StatusCode retval = UA_ClientConfig_setDefault(config);
107522 if(retval != UA_STATUSCODE_GOOD)
107523 return retval;
107524
107525 if(trustListSize || revocationListSize) {
107526 retval = UA_CertificateVerification_Trustlist(cv: &config->certificateVerification,
107527 certificateTrustList: trustList, certificateTrustListSize: trustListSize,
107528 NULL, certificateIssuerListSize: 0,
107529 certificateRevocationList: revocationList, certificateRevocationListSize: revocationListSize);
107530 if(retval != UA_STATUSCODE_GOOD)
107531 return retval;
107532 } else {
107533 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_SECURITYPOLICY,
107534 msg: "Empty trustlist and revocationlist passed, leaving the previously configured certificate verification in place");
107535 }
107536
107537 /* Populate SecurityPolicies, append to pre existing and don't overwrite */
107538 UA_SecurityPolicy *sp = (UA_SecurityPolicy*)
107539 UA_realloc(ptr: config->securityPolicies, size: sizeof(UA_SecurityPolicy) * (config->securityPoliciesSize + SECURITY_POLICY_SIZE));
107540 if(!sp)
107541 return UA_STATUSCODE_BADOUTOFMEMORY;
107542 config->securityPolicies = sp;
107543
107544 /* Load the private key and convert to the DER format. Use an empty password
107545 * on the first try -- maybe the key does not require a password. */
107546 UA_ByteString decryptedPrivateKey = UA_BYTESTRING_NULL;
107547 UA_ByteString keyPassword = UA_BYTESTRING_NULL;
107548 UA_StatusCode keySuccess = UA_STATUSCODE_GOOD;
107549
107550 if (privateKey.length > 0)
107551 keySuccess = UA_PKI_decryptPrivateKey(privateKey, password: keyPassword,
107552 outDerKey: &decryptedPrivateKey);
107553
107554 /* Get the password and decrypt. An application might want to loop / retry
107555 * here to allow users to correct their entry. */
107556 if(keySuccess != UA_STATUSCODE_GOOD) {
107557 if(config->privateKeyPasswordCallback)
107558 keySuccess = config->privateKeyPasswordCallback(config, &keyPassword);
107559 else
107560 keySuccess = readPrivateKeyPassword(password: &keyPassword);
107561 if(keySuccess != UA_STATUSCODE_GOOD)
107562 return keySuccess;
107563 keySuccess = UA_PKI_decryptPrivateKey(privateKey, password: keyPassword, outDerKey: &decryptedPrivateKey);
107564 UA_ByteString_memZero(bs: &keyPassword);
107565 UA_ByteString_clear(p: &keyPassword);
107566 }
107567 if(keySuccess != UA_STATUSCODE_GOOD)
107568 return keySuccess;
107569
107570 securityPolicies_addAll(sp, length: &config->securityPoliciesSize,
107571 certificate: localCertificate, privateKey: decryptedPrivateKey, logging: config->logging);
107572
107573 /* Set the same certificate also for authentication.
107574 * Can be overridden with a different certificate. */
107575 if(config->authSecurityPoliciesSize == 0)
107576 clientConfig_setAuthenticationSecurityPolicies(config, certificateAuth: localCertificate,
107577 privateKeyAuth: decryptedPrivateKey);
107578
107579 UA_ByteString_memZero(bs: &decryptedPrivateKey);
107580 UA_ByteString_clear(p: &decryptedPrivateKey);
107581
107582 if(config->securityPoliciesSize == 0) {
107583 UA_free(ptr: config->securityPolicies);
107584 config->securityPolicies = NULL;
107585 }
107586
107587 return UA_STATUSCODE_GOOD;
107588}
107589#endif
107590
107591#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_MBEDTLS)
107592UA_StatusCode
107593UA_ClientConfig_setAuthenticationCert(UA_ClientConfig *config,
107594 UA_ByteString certificateAuth,
107595 UA_ByteString privateKeyAuth) {
107596#ifdef UA_ENABLE_ENCRYPTION_LIBRESSL
107597 UA_LOG_WARNING(config->logging, UA_LOGCATEGORY_USERLAND,
107598 "Certificate authentication with LibreSSL as crypto backend is not supported.");
107599 return UA_STATUSCODE_BADNOTIMPLEMENTED;
107600#endif
107601
107602 /* Create UserIdentityToken */
107603 UA_X509IdentityToken* identityToken = UA_X509IdentityToken_new();
107604 if(!identityToken)
107605 return UA_STATUSCODE_BADOUTOFMEMORY;
107606 /* Don't set identityToken->policyId. This is taken from the appropriate
107607 * endpoint at runtime. */
107608 UA_StatusCode retval = UA_ByteString_copy(src: &certificateAuth, dst: &identityToken->certificateData);
107609 if(retval != UA_STATUSCODE_GOOD)
107610 return retval;
107611 UA_ExtensionObject_clear(p: &config->userIdentityToken);
107612 config->userIdentityToken.encoding = UA_EXTENSIONOBJECT_DECODED;
107613 config->userIdentityToken.content.decoded.type = &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN];
107614 config->userIdentityToken.content.decoded.data = identityToken;
107615
107616 /* Populate SecurityPolicies */
107617 return clientConfig_setAuthenticationSecurityPolicies(config, certificateAuth, privateKeyAuth);
107618}
107619#endif
107620
107621/**** amalgamated original file "/plugins/ua_config_json.c" ****/
107622
107623/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
107624 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
107625 *
107626 * Copyright 2023 (c) Fraunhofer IOSB (Author: Noel Graf)
107627 */
107628
107629#ifdef UA_ENABLE_ENCRYPTION
107630#endif
107631
107632#define MAX_TOKENS 256
107633
107634typedef struct {
107635 const char *json;
107636 const cj5_token *tokens;
107637 cj5_result result;
107638 unsigned int tokensSize;
107639 size_t index;
107640 UA_Byte depth;
107641} ParsingCtx;
107642
107643static UA_ByteString
107644getJsonPart(cj5_token tok, const char *json) {
107645 UA_ByteString bs;
107646 UA_ByteString_init(p: &bs);
107647 if(tok.type == CJ5_TOKEN_STRING) {
107648 bs.data = (UA_Byte*)(uintptr_t)(json + tok.start - 1);
107649 bs.length = (tok.end - tok.start) + 3;
107650 return bs;
107651 } else {
107652 bs.data = (UA_Byte*)(uintptr_t)(json + tok.start);
107653 bs.length = (tok.end - tok.start) + 1;
107654 return bs;
107655 }
107656}
107657
107658/* Forward declarations*/
107659#define PARSE_JSON(TYPE) static UA_StatusCode \
107660 TYPE##_parseJson(ParsingCtx *ctx, void *configField, size_t *configFieldSize)
107661
107662typedef UA_StatusCode
107663(*parseJsonSignature)(ParsingCtx *ctx, void *configField, size_t *configFieldSize);
107664
107665#ifdef UA_ENABLE_ENCRYPTION
107666static UA_ByteString
107667loadCertificateFile(const char *const path);
107668#endif
107669
107670/* The DataType "kind" is an internal type classification. It is used to
107671 * dispatch handling to the correct routines. */
107672#define UA_SERVERCONFIGFIELDKINDS 25
107673typedef enum {
107674 /* Basic Types */
107675 UA_SERVERCONFIGFIELD_INT64 = 0,
107676 UA_SERVERCONFIGFIELD_UINT16,
107677 UA_SERVERCONFIGFIELD_UINT32,
107678 UA_SERVERCONFIGFIELD_UINT64,
107679 UA_SERVERCONFIGFIELD_STRING,
107680 UA_SERVERCONFIGFIELD_LOCALIZEDTEXT,
107681 UA_SERVERCONFIGFIELD_DOUBLE,
107682 UA_SERVERCONFIGFIELD_BOOLEAN,
107683 UA_SERVERCONFIGFIELD_DURATION,
107684 UA_SERVERCONFIGFIELD_DURATIONRANGE,
107685 UA_SERVERCONFIGFIELD_UINT32RANGE,
107686
107687 /* Advanced Types */
107688 UA_SERVERCONFIGFIELD_BUILDINFO,
107689 UA_SERVERCONFIGFIELD_APPLICATIONDESCRIPTION,
107690 UA_SERVERCONFIGFIELD_STRINGARRAY,
107691 UA_SERVERCONFIGFIELD_UINT32ARRAY,
107692 UA_SERVERCONFIGFIELD_DATETIME,
107693 UA_SERVERCONFIGFIELD_SUBSCRIPTIONCONFIGURATION,
107694 UA_SERVERCONFIGFIELD_TCPCONFIGURATION,
107695 UA_SERVERCONFIGFIELD_PUBSUBCONFIGURATION,
107696 UA_SERVERCONFIGFIELD_HISTORIZINGCONFIGURATION,
107697 UA_SERVERCONFIGFIELD_MDNSCONFIGURATION,
107698 UA_SERVERCONFIGFIELD_SECURITYPOLICIES,
107699 UA_SERVERCONFIGFIELD_SECURITYPKI,
107700
107701 /* Enumerations */
107702 UA_SERVERCONFIGFIELD_APPLICATIONTYPE,
107703 UA_SERVERCONFIGFIELD_RULEHANDLING
107704} UA_ServerConfigFieldKind;
107705
107706extern const parseJsonSignature parseJsonJumpTable[UA_SERVERCONFIGFIELDKINDS];
107707
107708/*----------------------Basic Types------------------------*/
107709PARSE_JSON(Int64Field) {
107710 cj5_token tok = ctx->tokens[++ctx->index];
107711 UA_ByteString buf = getJsonPart(tok, json: ctx->json);
107712 UA_Int64 out;
107713 UA_StatusCode retval = UA_decodeJson(src: &buf, dst: &out, type: &UA_TYPES[UA_TYPES_INT64], NULL);
107714 if(retval != UA_STATUSCODE_GOOD)
107715 return retval;
107716 UA_Int64 *field = (UA_Int64*)configField;
107717 *field = out;
107718 return retval;
107719}
107720PARSE_JSON(UInt16Field) {
107721 cj5_token tok = ctx->tokens[++ctx->index];
107722 UA_ByteString buf = getJsonPart(tok, json: ctx->json);
107723 UA_UInt16 out;
107724 UA_StatusCode retval = UA_decodeJson(src: &buf, dst: &out, type: &UA_TYPES[UA_TYPES_UINT16], NULL);
107725 if(retval != UA_STATUSCODE_GOOD)
107726 return retval;
107727 UA_UInt16 *field = (UA_UInt16*)configField;
107728 *field = out;
107729 return retval;
107730}
107731PARSE_JSON(UInt32Field) {
107732 cj5_token tok = ctx->tokens[++ctx->index];
107733 UA_ByteString buf = getJsonPart(tok, json: ctx->json);
107734 UA_UInt32 out;
107735 UA_StatusCode retval = UA_decodeJson(src: &buf, dst: &out, type: &UA_TYPES[UA_TYPES_UINT32], NULL);
107736 if(retval != UA_STATUSCODE_GOOD)
107737 return retval;
107738 UA_UInt32 *field = (UA_UInt32*)configField;
107739 *field = out;
107740 return retval;
107741}
107742PARSE_JSON(UInt64Field) {
107743 cj5_token tok = ctx->tokens[++ctx->index];
107744 UA_ByteString buf = getJsonPart(tok, json: ctx->json);
107745 UA_UInt64 out;
107746 UA_StatusCode retval = UA_decodeJson(src: &buf, dst: &out, type: &UA_TYPES[UA_TYPES_UINT64], NULL);
107747 if(retval != UA_STATUSCODE_GOOD)
107748 return retval;
107749 UA_UInt64 *field = (UA_UInt64*)configField;
107750 *field = out;
107751 return retval;
107752}
107753PARSE_JSON(StringField) {
107754 cj5_token tok = ctx->tokens[++ctx->index];
107755 UA_ByteString buf = getJsonPart(tok, json: ctx->json);
107756 UA_String out;
107757 UA_StatusCode retval = UA_decodeJson(src: &buf, dst: &out, type: &UA_TYPES[UA_TYPES_STRING], NULL);
107758 if(retval != UA_STATUSCODE_GOOD)
107759 return retval;
107760 UA_String *field = (UA_String*)configField;
107761 if(field != NULL) {
107762 UA_String_clear(p: field);
107763 *field = out;
107764 }
107765 return retval;
107766}
107767PARSE_JSON(LocalizedTextField) {
107768 /*
107769 applicationName: {
107770 locale: "de-DE",
107771 text: "Test text"
107772 }
107773 */
107774 cj5_token tok = ctx->tokens[++ctx->index];
107775 UA_StatusCode retval = UA_STATUSCODE_GOOD;
107776 UA_String locale;
107777 UA_String text;
107778 for(size_t j = tok.size/2; j > 0; j--) {
107779 tok = ctx->tokens[++ctx->index];
107780 switch (tok.type) {
107781 case CJ5_TOKEN_STRING: {
107782 char *field = (char*)UA_malloc(size: tok.size + 1);
107783 unsigned int str_len = 0;
107784 cj5_get_str(r: &ctx->result, tok_index: (unsigned int)ctx->index, buf: field, buflen: &str_len);
107785
107786 tok = ctx->tokens[++ctx->index];
107787 UA_ByteString buf = getJsonPart(tok, json: ctx->json);
107788 if(strcmp(s1: field, s2: "locale") == 0)
107789 retval |= UA_decodeJson(src: &buf, dst: &locale, type: &UA_TYPES[UA_TYPES_STRING], NULL);
107790 else if(strcmp(s1: field, s2: "text") == 0)
107791 retval |= UA_decodeJson(src: &buf, dst: &text, type: &UA_TYPES[UA_TYPES_STRING], NULL);
107792 else {
107793 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Unknown field name.");
107794 }
107795 UA_free(ptr: field);
107796 break;
107797 }
107798 default:
107799 break;
107800 }
107801 }
107802 UA_LocalizedText out;
107803 out.locale = locale;
107804 out.text = text;
107805 if(retval != UA_STATUSCODE_GOOD)
107806 return retval;
107807 UA_LocalizedText *field = (UA_LocalizedText*)configField;
107808 if(field != NULL) {
107809 UA_LocalizedText_clear(p: field);
107810 *field = out;
107811 }
107812 return retval;
107813}
107814PARSE_JSON(DoubleField) {
107815 cj5_token tok = ctx->tokens[++ctx->index];
107816 UA_ByteString buf = getJsonPart(tok, json: ctx->json);
107817 UA_Double out;
107818 UA_StatusCode retval = UA_decodeJson(src: &buf, dst: &out, type: &UA_TYPES[UA_TYPES_DOUBLE], NULL);
107819 if(retval != UA_STATUSCODE_GOOD)
107820 return retval;
107821 UA_Double *field = (UA_Double *)configField;
107822 *field = out;
107823 return retval;
107824}
107825PARSE_JSON(BooleanField) {
107826 cj5_token tok = ctx->tokens[++ctx->index];
107827 UA_ByteString buf = getJsonPart(tok, json: ctx->json);
107828 UA_Boolean out;
107829 if(tok.type != CJ5_TOKEN_BOOL) {
107830 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Value of type bool expected.");
107831 return UA_STATUSCODE_BADTYPEMISMATCH;
107832 }
107833 UA_String val = UA_STRING(chars: "true");
107834 if(UA_String_equal(p1: &val, p2: &buf)) {
107835 out = true;
107836 }else {
107837 out = false;
107838 }
107839 /* set server config field */
107840 UA_Boolean *field = (UA_Boolean *)configField;
107841 *field = out;
107842 return UA_STATUSCODE_GOOD;
107843}
107844PARSE_JSON(DurationField) {
107845 UA_Double double_value;
107846 UA_StatusCode retval = DoubleField_parseJson(ctx, configField: &double_value, NULL);
107847 if(retval != UA_STATUSCODE_GOOD)
107848 return retval;
107849 UA_Duration *field = (UA_Duration*)configField;
107850 *field = (UA_Duration)double_value;
107851 return retval;
107852}
107853PARSE_JSON(DurationRangeField) {
107854 UA_DurationRange *field = (UA_DurationRange*)configField;
107855 cj5_token tok = ctx->tokens[++ctx->index];
107856 for(size_t j = tok.size/2; j > 0; j--) {
107857 tok = ctx->tokens[++ctx->index];
107858 switch (tok.type) {
107859 case CJ5_TOKEN_STRING: {
107860 char *field_str = (char*)UA_malloc(size: tok.size + 1);
107861 unsigned int str_len = 0;
107862 cj5_get_str(r: &ctx->result, tok_index: (unsigned int)ctx->index, buf: field_str, buflen: &str_len);
107863 if(strcmp(s1: field_str, s2: "min") == 0)
107864 parseJsonJumpTable[UA_SERVERCONFIGFIELD_DURATION](ctx, &field->min, NULL);
107865 else if(strcmp(s1: field_str, s2: "max") == 0)
107866 parseJsonJumpTable[UA_SERVERCONFIGFIELD_DURATION](ctx, &field->max, NULL);
107867 else {
107868 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Unknown field name.");
107869 }
107870 UA_free(ptr: field_str);
107871 break;
107872 }
107873 default:
107874 break;
107875 }
107876 }
107877 return UA_STATUSCODE_GOOD;
107878}
107879PARSE_JSON(UInt32RangeField) {
107880 UA_UInt32Range *field = (UA_UInt32Range*)configField;
107881 cj5_token tok = ctx->tokens[++ctx->index];
107882 for(size_t j = tok.size/2; j > 0; j--) {
107883 tok = ctx->tokens[++ctx->index];
107884 switch (tok.type) {
107885 case CJ5_TOKEN_STRING: {
107886 char *field_str = (char*)UA_malloc(size: tok.size + 1);
107887 unsigned int str_len = 0;
107888 cj5_get_str(r: &ctx->result, tok_index: (unsigned int)ctx->index, buf: field_str, buflen: &str_len);
107889 if(strcmp(s1: field_str, s2: "min") == 0)
107890 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &field->min, NULL);
107891 else if(strcmp(s1: field_str, s2: "max") == 0)
107892 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &field->max, NULL);
107893 else {
107894 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Unknown field name.");
107895 }
107896 UA_free(ptr: field_str);
107897 break;
107898 }
107899 default:
107900 break;
107901 }
107902 }
107903 return UA_STATUSCODE_GOOD;
107904}
107905
107906/*----------------------Advanced Types------------------------*/
107907PARSE_JSON(BuildInfo) {
107908 UA_BuildInfo *field = (UA_BuildInfo*)configField;
107909 cj5_token tok = ctx->tokens[++ctx->index];
107910 for(size_t j = tok.size/2; j > 0; j--) {
107911 tok = ctx->tokens[++ctx->index];
107912 switch (tok.type) {
107913 case CJ5_TOKEN_STRING: {
107914 char *field_str = (char*)UA_malloc(size: tok.size + 1);
107915 unsigned int str_len = 0;
107916 cj5_get_str(r: &ctx->result, tok_index: (unsigned int)ctx->index, buf: field_str, buflen: &str_len);
107917 if(strcmp(s1: field_str, s2: "productUri") == 0)
107918 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &field->productUri, NULL);
107919 else if(strcmp(s1: field_str, s2: "manufacturerName") == 0)
107920 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &field->manufacturerName, NULL);
107921 else if(strcmp(s1: field_str, s2: "productName") == 0)
107922 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &field->productName, NULL);
107923 else if(strcmp(s1: field_str, s2: "softwareVersion") == 0)
107924 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &field->softwareVersion, NULL);
107925 else if(strcmp(s1: field_str, s2: "buildNumber") == 0)
107926 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &field->buildNumber, NULL);
107927 else if(strcmp(s1: field_str, s2: "buildDate") == 0)
107928 parseJsonJumpTable[UA_SERVERCONFIGFIELD_DATETIME](ctx, &field->buildDate, NULL);
107929 else {
107930 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Unknown field name.");
107931 }
107932 UA_free(ptr: field_str);
107933 break;
107934 }
107935 default:
107936 break;
107937 }
107938 }
107939 return UA_STATUSCODE_GOOD;
107940}
107941PARSE_JSON(ApplicationDescriptionField) {
107942 UA_ApplicationDescription *field = (UA_ApplicationDescription*)configField;
107943 cj5_token tok = ctx->tokens[++ctx->index];
107944 for(size_t j = tok.size/2; j > 0; j--) {
107945 tok = ctx->tokens[++ctx->index];
107946 switch (tok.type) {
107947 case CJ5_TOKEN_STRING: {
107948 char *field_str = (char*)UA_malloc(size: tok.size + 1);
107949 unsigned int str_len = 0;
107950 cj5_get_str(r: &ctx->result, tok_index: (unsigned int)ctx->index, buf: field_str, buflen: &str_len);
107951 if(strcmp(s1: field_str, s2: "applicationUri") == 0)
107952 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &field->applicationUri, NULL);
107953 else if(strcmp(s1: field_str, s2: "productUri") == 0)
107954 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &field->productUri, NULL);
107955 else if(strcmp(s1: field_str, s2: "applicationName") == 0)
107956 parseJsonJumpTable[UA_SERVERCONFIGFIELD_LOCALIZEDTEXT](ctx, &field->applicationName, NULL);
107957 else if(strcmp(s1: field_str, s2: "applicationType") == 0)
107958 parseJsonJumpTable[UA_SERVERCONFIGFIELD_APPLICATIONTYPE](ctx, &field->applicationType, NULL);
107959 else if(strcmp(s1: field_str, s2: "gatewayServerUri") == 0)
107960 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &field->gatewayServerUri, NULL);
107961 else if(strcmp(s1: field_str, s2: "discoveryProfileUri") == 0)
107962 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &field->discoveryProfileUri, NULL);
107963 else if(strcmp(s1: field_str, s2: "discoveryUrls") == 0)
107964 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRINGARRAY](ctx, &field->discoveryUrls, &field->discoveryUrlsSize);
107965 else {
107966 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Unknown field name.");
107967 }
107968 UA_free(ptr: field_str);
107969 break;
107970 }
107971 default:
107972 break;
107973 }
107974 }
107975 return UA_STATUSCODE_GOOD;
107976}
107977PARSE_JSON(StringArrayField) {
107978 if(configFieldSize == NULL) {
107979 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Pointer to the array size is not set.");
107980 return UA_STATUSCODE_BADARGUMENTSMISSING;
107981 }
107982 cj5_token tok = ctx->tokens[++ctx->index];
107983 UA_String *stringArray = (UA_String*)UA_malloc(size: sizeof(UA_String) * tok.size);
107984 size_t stringArraySize = 0;
107985 for(size_t j = tok.size; j > 0; j--) {
107986 UA_String out = {.length = 0, .data = NULL};;
107987 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &out, NULL);
107988 UA_String_copy(src: &out, dst: &stringArray[stringArraySize++]);
107989 UA_String_clear(p: &out);
107990 }
107991 /* Add to the config */
107992 UA_String **field = (UA_String**)configField;
107993 if(*configFieldSize > 0) {
107994 UA_Array_delete(p: *field, size: *configFieldSize,
107995 type: &UA_TYPES[UA_TYPES_STRING]);
107996 *field = NULL;
107997 *configFieldSize = 0;
107998 }
107999 UA_StatusCode retval =
108000 UA_Array_copy(src: stringArray, size: stringArraySize,
108001 dst: (void**)field, type: &UA_TYPES[UA_TYPES_STRING]);
108002 *configFieldSize = stringArraySize;
108003
108004 /* Clean up */
108005 UA_Array_delete(p: stringArray, size: stringArraySize, type: &UA_TYPES[UA_TYPES_STRING]);
108006 return retval;
108007}
108008PARSE_JSON(UInt32ArrayField) {
108009 if(configFieldSize == NULL) {
108010 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Pointer to the array size is not set.");
108011 return UA_STATUSCODE_BADARGUMENTSMISSING;
108012 }
108013 cj5_token tok = ctx->tokens[++ctx->index];
108014 UA_UInt32 *numberArray = (UA_UInt32*)UA_malloc(size: sizeof(UA_UInt32) * tok.size);;
108015 size_t numberArraySize = 0;
108016 for(size_t j = tok.size; j > 0; j--) {
108017 UA_UInt32 value;
108018 UA_StatusCode retval = UInt32Field_parseJson(ctx, configField: &value, NULL);
108019 if(retval != UA_STATUSCODE_GOOD)
108020 continue;
108021 numberArray[numberArraySize++] = value;
108022 }
108023 /* Add to the config */
108024 UA_UInt32 **field = (UA_UInt32**)configField;
108025 if(*configFieldSize > 0) {
108026 UA_Array_delete(p: *field, size: *configFieldSize,
108027 type: &UA_TYPES[UA_TYPES_UINT32]);
108028 *field = NULL;
108029 *configFieldSize = 0;
108030 }
108031 UA_StatusCode retval = UA_STATUSCODE_GOOD;
108032 if(numberArraySize > 0) {
108033 retval = UA_Array_copy(src: numberArray, size: numberArraySize,
108034 dst: (void **)field, type: &UA_TYPES[UA_TYPES_UINT32]);
108035 *configFieldSize = numberArraySize;
108036 }
108037 /* Clean up */
108038 UA_Array_delete(p: numberArray, size: numberArraySize, type: &UA_TYPES[UA_TYPES_UINT32]);
108039 return retval;
108040}
108041PARSE_JSON(DateTimeField) {
108042 cj5_token tok = ctx->tokens[++ctx->index];
108043 UA_ByteString buf = getJsonPart(tok, json: ctx->json);
108044 UA_DateTime out;
108045 UA_DateTime_init(p: &out);
108046 UA_StatusCode retval = UA_decodeJson(src: &buf, dst: &out, type: &UA_TYPES[UA_TYPES_DATETIME], NULL);
108047 if(retval != UA_STATUSCODE_GOOD)
108048 return retval;
108049 UA_DateTime *field = (UA_DateTime*)configField;
108050 *field = out;
108051 return retval;
108052}
108053
108054PARSE_JSON(MdnsConfigurationField) {
108055#ifdef UA_ENABLE_DISCOVERY_MULTICAST
108056 UA_ServerConfig *config = (UA_ServerConfig*)configField;
108057 cj5_token tok = ctx->tokens[++ctx->index];
108058 for(size_t j = tok.size/2; j > 0; j--) {
108059 tok = ctx->tokens[++ctx->index];
108060 switch (tok.type) {
108061 case CJ5_TOKEN_STRING: {
108062 char *field_str = (char*)UA_malloc(tok.size + 1);
108063 unsigned int str_len = 0;
108064 cj5_get_str(&ctx->result, (unsigned int)ctx->index, field_str, &str_len);
108065 if(strcmp(field_str, "mdnsServerName") == 0)
108066 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &config->mdnsConfig.mdnsServerName, NULL);
108067 else if(strcmp(field_str, "serverCapabilities") == 0)
108068 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRINGARRAY](ctx, &config->mdnsConfig.serverCapabilities, &config->mdnsConfig.serverCapabilitiesSize);
108069 else if(strcmp(field_str, "mdnsInterfaceIP") == 0)
108070 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &config->mdnsInterfaceIP, NULL);
108071 /* mdnsIpAddressList and mdnsIpAddressListSize are only available if UA_HAS_GETIFADDR is not defined: */
108072# if !defined(UA_HAS_GETIFADDR)
108073 else if(strcmp(field_str, "mdnsIpAddressList") == 0)
108074 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32ARRAY](ctx, &config->mdnsIpAddressList, &config->mdnsIpAddressListSize);
108075# endif
108076 else {
108077 UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Unknown field name.");
108078 }
108079 UA_free(field_str);
108080 break;
108081 }
108082 default:
108083 break;
108084 }
108085 }
108086#endif
108087 return UA_STATUSCODE_GOOD;
108088}
108089
108090PARSE_JSON(SubscriptionConfigurationField) {
108091#ifdef UA_ENABLE_SUBSCRIPTIONS
108092 UA_ServerConfig *config = (UA_ServerConfig*)configField;
108093 cj5_token tok = ctx->tokens[++ctx->index];
108094 for(size_t j = tok.size/2; j > 0; j--) {
108095 tok = ctx->tokens[++ctx->index];
108096 switch (tok.type) {
108097 case CJ5_TOKEN_STRING: {
108098 char *field_str = (char*)UA_malloc(size: tok.size + 1);
108099 unsigned int str_len = 0;
108100 cj5_get_str(r: &ctx->result, tok_index: (unsigned int)ctx->index, buf: field_str, buflen: &str_len);
108101 if(strcmp(s1: field_str, s2: "maxSubscriptions") == 0)
108102 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &config->maxSubscriptions, NULL);
108103 else if(strcmp(s1: field_str, s2: "maxSubscriptionsPerSession") == 0)
108104 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &config->maxSubscriptionsPerSession, NULL);
108105 else if(strcmp(s1: field_str, s2: "publishingIntervalLimits") == 0)
108106 parseJsonJumpTable[UA_SERVERCONFIGFIELD_DURATIONRANGE](ctx, &config->publishingIntervalLimits, NULL);
108107 else if(strcmp(s1: field_str, s2: "lifeTimeCountLimits") == 0)
108108 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32RANGE](ctx, &config->lifeTimeCountLimits, NULL);
108109 else if(strcmp(s1: field_str, s2: "keepAliveCountLimits") == 0)
108110 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32RANGE](ctx, &config->keepAliveCountLimits, NULL);
108111 else if(strcmp(s1: field_str, s2: "maxNotificationsPerPublish") == 0)
108112 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &config->maxNotificationsPerPublish, NULL);
108113 else if(strcmp(s1: field_str, s2: "enableRetransmissionQueue") == 0)
108114 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &config->enableRetransmissionQueue, NULL);
108115 else if(strcmp(s1: field_str, s2: "maxRetransmissionQueueSize") == 0)
108116 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &config->maxRetransmissionQueueSize, NULL);
108117# ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS
108118 else if(strcmp(s1: field_str, s2: "maxEventsPerNode") == 0)
108119 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &config->maxEventsPerNode, NULL);
108120# endif
108121 else if(strcmp(s1: field_str, s2: "maxMonitoredItems") == 0)
108122 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &config->maxMonitoredItems, NULL);
108123 else if(strcmp(s1: field_str, s2: "maxMonitoredItemsPerSubscription") == 0)
108124 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &config->maxMonitoredItemsPerSubscription, NULL);
108125 else if(strcmp(s1: field_str, s2: "samplingIntervalLimits") == 0)
108126 parseJsonJumpTable[UA_SERVERCONFIGFIELD_DURATIONRANGE](ctx, &config->samplingIntervalLimits, NULL);
108127 else if(strcmp(s1: field_str, s2: "queueSizeLimits") == 0)
108128 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32RANGE](ctx, &config->queueSizeLimits, NULL);
108129 else if(strcmp(s1: field_str, s2: "maxPublishReqPerSession") == 0)
108130 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &config->maxPublishReqPerSession, NULL);
108131 else {
108132 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Unknown field name.");
108133 }
108134 UA_free(ptr: field_str);
108135 break;
108136 }
108137 default:
108138 break;
108139 }
108140 }
108141#endif
108142 return UA_STATUSCODE_GOOD;
108143}
108144
108145PARSE_JSON(TcpConfigurationField) {
108146 UA_ServerConfig *config = (UA_ServerConfig*)configField;
108147 cj5_token tok = ctx->tokens[++ctx->index];
108148 for(size_t j = tok.size/2; j > 0; j--) {
108149 tok = ctx->tokens[++ctx->index];
108150 switch (tok.type) {
108151 case CJ5_TOKEN_STRING: {
108152 char *field_str = (char*)UA_malloc(size: tok.size + 1);
108153 unsigned int str_len = 0;
108154 cj5_get_str(r: &ctx->result, tok_index: (unsigned int)ctx->index, buf: field_str, buflen: &str_len);
108155 if(strcmp(s1: field_str, s2: "tcpBufSize") == 0)
108156 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &config->tcpBufSize, NULL);
108157 else if(strcmp(s1: field_str, s2: "tcpMaxMsgSize") == 0)
108158 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &config->tcpMaxMsgSize, NULL);
108159 else if(strcmp(s1: field_str, s2: "tcpMaxChunks") == 0)
108160 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &config->tcpMaxChunks, NULL);
108161 else {
108162 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Unknown field name.");
108163 }
108164 UA_free(ptr: field_str);
108165 break;
108166 }
108167 default:
108168 break;
108169 }
108170 }
108171 return UA_STATUSCODE_GOOD;
108172}
108173
108174PARSE_JSON(PubsubConfigurationField) {
108175#ifdef UA_ENABLE_PUBSUB
108176 UA_PubSubConfiguration *field = (UA_PubSubConfiguration*)configField;
108177 cj5_token tok = ctx->tokens[++ctx->index];
108178 for(size_t j = tok.size/2; j > 0; j--) {
108179 tok = ctx->tokens[++ctx->index];
108180 switch (tok.type) {
108181 case CJ5_TOKEN_STRING: {
108182 char *field_str = (char*)UA_malloc(size: tok.size + 1);
108183 unsigned int str_len = 0;
108184 cj5_get_str(r: &ctx->result, tok_index: (unsigned int)ctx->index, buf: field_str, buflen: &str_len);
108185 if(strcmp(s1: field_str, s2: "enableDeltaFrames") == 0)
108186 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &field->enableDeltaFrames, NULL);
108187#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL
108188 else if(strcmp(s1: field_str, s2: "enableInformationModelMethods") == 0)
108189 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &field->enableInformationModelMethods, NULL);
108190#endif
108191 else {
108192 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Unknown field name.");
108193 }
108194 UA_free(ptr: field_str);
108195 break;
108196 }
108197 default:
108198 break;
108199 }
108200 }
108201#endif
108202 return UA_STATUSCODE_GOOD;
108203}
108204
108205PARSE_JSON(HistorizingConfigurationField) {
108206#ifdef UA_ENABLE_HISTORIZING
108207 UA_ServerConfig *config = (UA_ServerConfig*)configField;
108208 cj5_token tok = ctx->tokens[++ctx->index];
108209 for(size_t j = tok.size/2; j > 0; j--) {
108210 tok = ctx->tokens[++ctx->index];
108211 switch (tok.type) {
108212 case CJ5_TOKEN_STRING: {
108213 char *field_str = (char*)UA_malloc(size: tok.size + 1);
108214 unsigned int str_len = 0;
108215 cj5_get_str(r: &ctx->result, tok_index: (unsigned int)ctx->index, buf: field_str, buflen: &str_len);
108216 if(strcmp(s1: field_str, s2: "accessHistoryDataCapability") == 0)
108217 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &config->accessHistoryDataCapability, NULL);
108218 else if(strcmp(s1: field_str, s2: "maxReturnDataValues") == 0)
108219 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &config->maxReturnDataValues, NULL);
108220 else if(strcmp(s1: field_str, s2: "accessHistoryEventsCapability") == 0)
108221 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &config->accessHistoryEventsCapability, NULL);
108222 else if(strcmp(s1: field_str, s2: "maxReturnEventValues") == 0)
108223 parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](ctx, &config->maxReturnEventValues, NULL);
108224 else if(strcmp(s1: field_str, s2: "insertDataCapability") == 0)
108225 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &config->insertDataCapability, NULL);
108226 else if(strcmp(s1: field_str, s2: "insertEventCapability") == 0)
108227 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &config->insertEventCapability, NULL);
108228 else if(strcmp(s1: field_str, s2: "insertAnnotationsCapability") == 0)
108229 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &config->insertAnnotationsCapability, NULL);
108230 else if(strcmp(s1: field_str, s2: "replaceDataCapability") == 0)
108231 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &config->replaceDataCapability, NULL);
108232 else if(strcmp(s1: field_str, s2: "replaceEventCapability") == 0)
108233 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &config->replaceEventCapability, NULL);
108234 else if(strcmp(s1: field_str, s2: "updateDataCapability") == 0)
108235 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &config->updateDataCapability, NULL);
108236 else if(strcmp(s1: field_str, s2: "updateEventCapability") == 0)
108237 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &config->updateEventCapability, NULL);
108238 else if(strcmp(s1: field_str, s2: "deleteRawCapability") == 0)
108239 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &config->deleteRawCapability, NULL);
108240 else if(strcmp(s1: field_str, s2: "deleteEventCapability") == 0)
108241 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &config->deleteEventCapability, NULL);
108242 else if(strcmp(s1: field_str, s2: "deleteAtTimeDataCapability") == 0)
108243 parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](ctx, &config->deleteAtTimeDataCapability, NULL);
108244 else {
108245 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Unknown field name.");
108246 }
108247 UA_free(ptr: field_str);
108248 break;
108249 }
108250 default:
108251 break;
108252 }
108253 }
108254#endif
108255 return UA_STATUSCODE_GOOD;
108256}
108257
108258PARSE_JSON(SecurityPolciesField) {
108259#ifdef UA_ENABLE_ENCRYPTION
108260 UA_ServerConfig *config = (UA_ServerConfig*)configField;
108261
108262 UA_String noneuri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#None");
108263 UA_String basic128Rsa15uri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15");
108264 UA_String basic256uri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Basic256");
108265 UA_String basic256Sha256uri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256");
108266 UA_String aes128sha256rsaoaepuri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaep");
108267 UA_String aes256sha256rsapssuri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Aes256_Sha256_RsaPss");
108268
108269 cj5_token tok = ctx->tokens[++ctx->index];
108270 for(size_t j = tok.size; j > 0; j--) {
108271
108272 UA_String policy = {.length = 0, .data = NULL};
108273 UA_ByteString certificate = {.length = 0, .data = NULL};
108274 UA_ByteString privateKey = {.length = 0, .data = NULL};
108275
108276 tok = ctx->tokens[++ctx->index];
108277 for(size_t i = tok.size / 2; i > 0; i--) {
108278 tok = ctx->tokens[++ctx->index];
108279 switch(tok.type) {
108280 case CJ5_TOKEN_STRING: {
108281 char *field_str = (char *)UA_malloc(size: tok.size + 1);
108282 unsigned int str_len = 0;
108283 cj5_get_str(r: &ctx->result, tok_index: (unsigned int)ctx->index, buf: field_str, buflen: &str_len);
108284 if(strcmp(s1: field_str, s2: "certificate") == 0) {
108285 UA_String out = {.length = 0, .data = NULL};
108286 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &out, NULL);
108287
108288 if(out.length > 0) {
108289 char *certfile = (char *)UA_malloc(size: out.length + 1);
108290 memcpy(dest: certfile, src: out.data, n: out.length);
108291 certfile[out.length] = '\0';
108292 certificate = loadCertificateFile(path: certfile);
108293 UA_String_clear(p: &out);
108294 UA_free(ptr: certfile);
108295 }
108296 } else if(strcmp(s1: field_str, s2: "privateKey") == 0) {
108297 UA_String out = {.length = 0, .data = NULL};
108298 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &out, NULL);
108299
108300 if(out.length > 0) {
108301 char *keyfile = (char *)UA_malloc(size: out.length + 1);
108302 memcpy(dest: keyfile, src: out.data, n: out.length);
108303 keyfile[out.length] = '\0';
108304 privateKey = loadCertificateFile(path: keyfile);
108305 UA_String_clear(p: &out);
108306 UA_free(ptr: keyfile);
108307 }
108308 } else if(strcmp(s1: field_str, s2: "policy") == 0) {
108309 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &policy, NULL);
108310 } else {
108311 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Unknown field name.");
108312 }
108313 UA_free(ptr: field_str);
108314 break;
108315 }
108316 default:
108317 break;
108318 }
108319 }
108320
108321 if(certificate.length == 0 || privateKey.length == 0) {
108322 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
108323 msg: "Certificate and PrivateKey must be set for every policy.");
108324 if(policy.length > 0)
108325 UA_String_clear(p: &policy);
108326 if(certificate.length > 0)
108327 UA_ByteString_clear(p: &certificate);
108328 if(privateKey.length > 0)
108329 UA_ByteString_clear(p: &privateKey);
108330 return UA_STATUSCODE_BADINTERNALERROR;
108331 }
108332 UA_StatusCode retval = UA_STATUSCODE_GOOD;
108333 if(UA_String_equal(p1: &policy, p2: &noneuri)) {
108334 /* Nothing to do! */
108335 } else if(UA_String_equal(p1: &policy, p2: &basic128Rsa15uri)) {
108336 retval = UA_ServerConfig_addSecurityPolicyBasic128Rsa15(config, certificate: &certificate, privateKey: &privateKey);
108337 if(retval != UA_STATUSCODE_GOOD) {
108338 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
108339 msg: "Could not add SecurityPolicy#Basic128Rsa15 with error code %s",
108340 UA_StatusCode_name(code: retval));
108341 }
108342 } else if(UA_String_equal(p1: &policy, p2: &basic256uri)) {
108343 retval = UA_ServerConfig_addSecurityPolicyBasic256(config, certificate: &certificate, privateKey: &privateKey);
108344 if(retval != UA_STATUSCODE_GOOD) {
108345 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
108346 msg: "Could not add SecurityPolicy#Basic256 with error code %s",
108347 UA_StatusCode_name(code: retval));
108348 }
108349 } else if(UA_String_equal(p1: &policy, p2: &basic256Sha256uri)) {
108350 retval = UA_ServerConfig_addSecurityPolicyBasic256Sha256(config, certificate: &certificate, privateKey: &privateKey);
108351 if(retval != UA_STATUSCODE_GOOD) {
108352 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
108353 msg: "Could not add SecurityPolicy#Basic256Sha256 with error code %s",
108354 UA_StatusCode_name(code: retval));
108355 }
108356 } else if(UA_String_equal(p1: &policy, p2: &aes128sha256rsaoaepuri)) {
108357 retval = UA_ServerConfig_addSecurityPolicyAes128Sha256RsaOaep(config, certificate: &certificate, privateKey: &privateKey);
108358 if(retval != UA_STATUSCODE_GOOD) {
108359 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
108360 msg: "Could not add SecurityPolicy#Aes128Sha256RsaOaep with error code %s",
108361 UA_StatusCode_name(code: retval));
108362 }
108363 } else if(UA_String_equal(p1: &policy, p2: &aes256sha256rsapssuri)) {
108364 retval = UA_ServerConfig_addSecurityPolicyAes256Sha256RsaPss(config, certificate: &certificate, privateKey: &privateKey);
108365 if(retval != UA_STATUSCODE_GOOD) {
108366 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_USERLAND,
108367 msg: "Could not add SecurityPolicy#Aes256Sha256RsaPss with error code %s",
108368 UA_StatusCode_name(code: retval));
108369 }
108370 } else {
108371 UA_LOG_WARNING(logger: config->logging, category: UA_LOGCATEGORY_USERLAND, msg: "Unknown Security Policy.");
108372 }
108373
108374 /* Add all Endpoints */
108375 UA_ServerConfig_addAllEndpoints(config);
108376
108377 if(policy.length > 0)
108378 UA_String_clear(p: &policy);
108379 if(certificate.length > 0)
108380 UA_ByteString_clear(p: &certificate);
108381 if(privateKey.length > 0)
108382 UA_ByteString_clear(p: &privateKey);
108383 }
108384#endif
108385 return UA_STATUSCODE_GOOD;
108386}
108387
108388PARSE_JSON(SecurityPkiField) {
108389#ifdef UA_ENABLE_ENCRYPTION
108390 UA_CertificateVerification *field = (UA_CertificateVerification*)configField;
108391 UA_String trustListFolder = {.length = 0, .data = NULL};
108392 UA_String issuerListFolder = {.length = 0, .data = NULL};
108393 UA_String revocationListFolder = {.length = 0, .data = NULL};
108394
108395 cj5_token tok = ctx->tokens[++ctx->index];
108396 for(size_t i = tok.size/2; i > 0; i--) {
108397 tok = ctx->tokens[++ctx->index];
108398 switch(tok.type) {
108399 case CJ5_TOKEN_STRING: {
108400 char *field_str = (char*)UA_malloc(size: tok.size + 1);
108401 unsigned int str_len = 0;
108402 cj5_get_str(r: &ctx->result, tok_index: (unsigned int)ctx->index, buf: field_str, buflen: &str_len);
108403 if(strcmp(s1: field_str, s2: "trustListFolder") == 0) {
108404 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &trustListFolder, NULL);
108405 } else if(strcmp(s1: field_str, s2: "issuerListFolder") == 0) {
108406 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &issuerListFolder, NULL);
108407 } else if(strcmp(s1: field_str, s2: "revocationListFolder") == 0) {
108408 parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRING](ctx, &revocationListFolder, NULL);
108409 } else {
108410 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Unknown field name.");
108411 }
108412 UA_free(ptr: field_str);
108413 break;
108414 }
108415 default:
108416 break;
108417 }
108418 }
108419#ifndef __linux__
108420 /* Currently not supported! */
108421 (void)field;
108422 return UA_STATUSCODE_GOOD;
108423#else
108424 /* set server config field */
108425 char *sTrustListFolder = NULL;
108426 char *sIssuerListFolder = NULL;
108427 char *sRevocationListFolder = NULL;
108428 if(trustListFolder.length > 0) {
108429 sTrustListFolder = (char*)UA_malloc(size: trustListFolder.length+1);
108430 memcpy(dest: sTrustListFolder, src: trustListFolder.data, n: trustListFolder.length);
108431 sTrustListFolder[trustListFolder.length] = '\0';
108432 }
108433 if(issuerListFolder.length > 0) {
108434 sIssuerListFolder = (char*)UA_malloc(size: issuerListFolder.length+1);
108435 memcpy(dest: sIssuerListFolder, src: issuerListFolder.data, n: issuerListFolder.length);
108436 sIssuerListFolder[issuerListFolder.length] = '\0';
108437 }
108438 if(revocationListFolder.length > 0) {
108439 sRevocationListFolder = (char*)UA_malloc(size: revocationListFolder.length+1);
108440 memcpy(dest: sRevocationListFolder, src: revocationListFolder.data, n: revocationListFolder.length);
108441 sRevocationListFolder[revocationListFolder.length] = '\0';
108442 }
108443 if(field && field->clear)
108444 field->clear(field);
108445#ifdef UA_ENABLE_CERT_REJECTED_DIR
108446 UA_StatusCode retval = UA_CertificateVerification_CertFolders(field, sTrustListFolder,
108447 sIssuerListFolder, sRevocationListFolder, NULL);
108448#else
108449 UA_StatusCode retval = UA_CertificateVerification_CertFolders(cv: field, trustListFolder: sTrustListFolder,
108450 issuerListFolder: sIssuerListFolder, revocationListFolder: sRevocationListFolder);
108451#endif
108452 /* Clean up */
108453 if(sTrustListFolder)
108454 UA_free(ptr: sTrustListFolder);
108455 if(sIssuerListFolder)
108456 UA_free(ptr: sIssuerListFolder);
108457 if(sRevocationListFolder)
108458 UA_free(ptr: sRevocationListFolder);
108459 UA_String_clear(p: &trustListFolder);
108460 UA_String_clear(p: &issuerListFolder);
108461 UA_String_clear(p: &revocationListFolder);
108462
108463 return retval;
108464#endif
108465#endif
108466 return UA_STATUSCODE_GOOD;
108467}
108468
108469/*----------------------Enumerations------------------------*/
108470PARSE_JSON(ApplicationTypeField) {
108471 UA_UInt32 enum_value;
108472 UA_StatusCode retval = UInt32Field_parseJson(ctx, configField: &enum_value, NULL);
108473 if(retval != UA_STATUSCODE_GOOD)
108474 return retval;
108475 UA_ApplicationType *field = (UA_ApplicationType*)configField;
108476 *field = (UA_ApplicationType)enum_value;
108477 return retval;
108478}
108479PARSE_JSON(RuleHandlingField) {
108480 UA_UInt32 enum_value;
108481 UA_StatusCode retval = UInt32Field_parseJson(ctx, configField: &enum_value, NULL);
108482 if(retval != UA_STATUSCODE_GOOD)
108483 return retval;
108484 UA_RuleHandling *field = (UA_RuleHandling*)configField;
108485 *field = (UA_RuleHandling)enum_value;
108486 return retval;
108487}
108488
108489const parseJsonSignature parseJsonJumpTable[UA_SERVERCONFIGFIELDKINDS] = {
108490 /* Basic Types */
108491 (parseJsonSignature)Int64Field_parseJson,
108492 (parseJsonSignature)UInt16Field_parseJson,
108493 (parseJsonSignature)UInt32Field_parseJson,
108494 (parseJsonSignature)UInt64Field_parseJson,
108495 (parseJsonSignature)StringField_parseJson,
108496 (parseJsonSignature)LocalizedTextField_parseJson,
108497 (parseJsonSignature)DoubleField_parseJson,
108498 (parseJsonSignature)BooleanField_parseJson,
108499 (parseJsonSignature)DurationField_parseJson,
108500 (parseJsonSignature)DurationRangeField_parseJson,
108501 (parseJsonSignature)UInt32RangeField_parseJson,
108502
108503 /* Advanced Types */
108504 (parseJsonSignature)BuildInfo_parseJson,
108505 (parseJsonSignature)ApplicationDescriptionField_parseJson,
108506 (parseJsonSignature)StringArrayField_parseJson,
108507 (parseJsonSignature)UInt32ArrayField_parseJson,
108508 (parseJsonSignature)DateTimeField_parseJson,
108509 (parseJsonSignature)SubscriptionConfigurationField_parseJson,
108510 (parseJsonSignature)TcpConfigurationField_parseJson,
108511 (parseJsonSignature)PubsubConfigurationField_parseJson,
108512 (parseJsonSignature)HistorizingConfigurationField_parseJson,
108513 (parseJsonSignature)MdnsConfigurationField_parseJson,
108514 (parseJsonSignature)SecurityPolciesField_parseJson,
108515 (parseJsonSignature)SecurityPkiField_parseJson,
108516
108517 /* Enumerations */
108518 (parseJsonSignature)ApplicationTypeField_parseJson,
108519 (parseJsonSignature)RuleHandlingField_parseJson,
108520};
108521
108522static UA_StatusCode
108523parseJSONConfig(UA_ServerConfig *config, UA_ByteString json_config) {
108524 // Parsing json config
108525 const char *json = (const char*)json_config.data;
108526 cj5_token tokens[MAX_TOKENS];
108527 cj5_result r = cj5_parse(json5: json, len: (unsigned int)json_config.length, tokens, MAX_TOKENS, NULL);
108528
108529 ParsingCtx ctx;
108530 ctx.json = json;
108531 ctx.result = r;
108532 ctx.tokens = r.tokens;
108533 ctx.tokensSize = r.num_tokens;
108534 ctx.index = 1; // The first token is ignored because it is known and not needed.
108535
108536 size_t serverConfigSize = 0;
108537 if(ctx.tokens)
108538 serverConfigSize = (ctx.tokens[ctx.index-1].size/2);
108539 UA_StatusCode retval = UA_STATUSCODE_GOOD;
108540 for (size_t j = serverConfigSize; j > 0; j--) {
108541 cj5_token tok = ctx.tokens[ctx.index];
108542 switch (tok.type) {
108543 case CJ5_TOKEN_STRING: {
108544 char *field = (char*)UA_malloc(size: tok.size + 1);
108545 unsigned int str_len = 0;
108546 cj5_get_str(r: &ctx.result, tok_index: (unsigned int)ctx.index, buf: field, buflen: &str_len);
108547 if(strcmp(s1: field, s2: "buildInfo") == 0)
108548 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_BUILDINFO](&ctx, &config->buildInfo, NULL);
108549 else if(strcmp(s1: field, s2: "applicationDescription") == 0)
108550 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_APPLICATIONDESCRIPTION](&ctx, &config->applicationDescription, NULL);
108551 else if(strcmp(s1: field, s2: "shutdownDelay") == 0)
108552 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_DOUBLE](&ctx, &config->shutdownDelay, NULL);
108553 else if(strcmp(s1: field, s2: "verifyRequestTimestamp") == 0)
108554 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_RULEHANDLING](&ctx, &config->verifyRequestTimestamp, NULL);
108555 else if(strcmp(s1: field, s2: "allowEmptyVariables") == 0)
108556 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_RULEHANDLING](&ctx, &config->allowEmptyVariables, NULL);
108557 else if(strcmp(s1: field, s2: "serverUrls") == 0)
108558 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_STRINGARRAY](&ctx, &config->serverUrls, &config->serverUrlsSize);
108559 else if(strcmp(s1: field, s2: "tcpEnabled") == 0)
108560 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](&ctx, &config->tcpEnabled, NULL);
108561 else if(strcmp(s1: field, s2: "tcp") == 0)
108562 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_TCPCONFIGURATION](&ctx, config, NULL);
108563 else if(strcmp(s1: field, s2: "securityPolicyNoneDiscoveryOnly") == 0)
108564 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](&ctx, &config->securityPolicyNoneDiscoveryOnly, NULL);
108565 else if(strcmp(s1: field, s2: "modellingRulesOnInstances") == 0)
108566 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](&ctx, &config->modellingRulesOnInstances, NULL);
108567 else if(strcmp(s1: field, s2: "maxSecureChannels") == 0)
108568 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT16](&ctx, &config->maxSecureChannels, NULL);
108569 else if(strcmp(s1: field, s2: "maxSecurityTokenLifetime") == 0)
108570 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](&ctx, &config->maxSecurityTokenLifetime, NULL);
108571 else if(strcmp(s1: field, s2: "maxSessions") == 0)
108572 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT16](&ctx, &config->maxSessions, NULL);
108573 else if(strcmp(s1: field, s2: "maxSessionTimeout") == 0)
108574 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_DOUBLE](&ctx, &config->maxSessionTimeout, NULL);
108575 else if(strcmp(s1: field, s2: "maxNodesPerRead") == 0)
108576 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](&ctx, &config->maxNodesPerRead, NULL);
108577 else if(strcmp(s1: field, s2: "maxNodesPerWrite") == 0)
108578 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](&ctx, &config->maxNodesPerWrite, NULL);
108579 else if(strcmp(s1: field, s2: "maxNodesPerMethodCall") == 0)
108580 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](&ctx, &config->maxNodesPerMethodCall, NULL);
108581 else if(strcmp(s1: field, s2: "maxNodesPerBrowse") == 0)
108582 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](&ctx, &config->maxNodesPerBrowse, NULL);
108583 else if(strcmp(s1: field, s2: "maxNodesPerRegisterNodes") == 0)
108584 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](&ctx, &config->maxNodesPerRegisterNodes, NULL);
108585 else if(strcmp(s1: field, s2: "maxNodesPerTranslateBrowsePathsToNodeIds") == 0)
108586 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](&ctx, &config->maxNodesPerTranslateBrowsePathsToNodeIds, NULL);
108587 else if(strcmp(s1: field, s2: "maxNodesPerNodeManagement") == 0)
108588 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](&ctx, &config->maxNodesPerNodeManagement, NULL);
108589 else if(strcmp(s1: field, s2: "maxMonitoredItemsPerCall") == 0)
108590 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](&ctx, &config->maxMonitoredItemsPerCall, NULL);
108591 else if(strcmp(s1: field, s2: "maxReferencesPerNode") == 0)
108592 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](&ctx, &config->maxReferencesPerNode, NULL);
108593 else if(strcmp(s1: field, s2: "reverseReconnectInterval") == 0)
108594 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](&ctx, &config->reverseReconnectInterval, NULL);
108595
108596#if UA_MULTITHREADING >= 100
108597 else if(strcmp(field, "asyncOperationTimeout") == 0)
108598 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_DOUBLE](&ctx, &config->asyncOperationTimeout, NULL);
108599 else if(strcmp(field, "maxAsyncOperationQueueSize") == 0)
108600 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT64](&ctx, &config->maxAsyncOperationQueueSize, NULL);
108601#endif
108602
108603#ifdef UA_ENABLE_DISCOVERY
108604 else if(strcmp(s1: field, s2: "discoveryCleanupTimeout") == 0)
108605 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32](&ctx, &config->discoveryCleanupTimeout, NULL);
108606#ifdef UA_ENABLE_DISCOVERY_MULTICAST
108607 else if(strcmp(field, "mdnsEnabled") == 0)
108608 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](&ctx, &config->mdnsEnabled, NULL);
108609 else if(strcmp(field, "mdns") == 0)
108610 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_MDNSCONFIGURATION](&ctx, config, NULL);
108611#if !defined(UA_HAS_GETIFADDR)
108612 else if(strcmp(field, "mdnsIpAddressList") == 0)
108613 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_UINT32ARRAY](&ctx, &config->mdnsIpAddressList, &config->mdnsIpAddressListSize);
108614#endif
108615#endif
108616#endif
108617
108618#ifdef UA_ENABLE_SUBSCRIPTIONS
108619 else if(strcmp(s1: field, s2: "subscriptionsEnabled") == 0)
108620 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](&ctx, &config->subscriptionsEnabled, NULL);
108621 else if(strcmp(s1: field, s2: "subscriptions") == 0)
108622 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_SUBSCRIPTIONCONFIGURATION](&ctx, config, NULL);
108623# endif
108624
108625#ifdef UA_ENABLE_HISTORIZING
108626 else if(strcmp(s1: field, s2: "historizingEnabled") == 0)
108627 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](&ctx, &config->historizingEnabled, NULL);
108628 else if(strcmp(s1: field, s2: "historizing") == 0)
108629 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_HISTORIZINGCONFIGURATION](&ctx, config, NULL);
108630#endif
108631
108632#ifdef UA_ENABLE_PUBSUB
108633 else if(strcmp(s1: field, s2: "pubsubEnabled") == 0)
108634 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_BOOLEAN](&ctx, &config->pubsubEnabled, NULL);
108635 else if(strcmp(s1: field, s2: "pubsub") == 0)
108636 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_PUBSUBCONFIGURATION](&ctx, config, NULL);
108637#endif
108638#ifdef UA_ENABLE_ENCRYPTION
108639 else if(strcmp(s1: field, s2: "securityPolicies") == 0)
108640 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_SECURITYPOLICIES](&ctx, config, NULL);
108641 else if(strcmp(s1: field, s2: "secureChannelPKI") == 0)
108642 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_SECURITYPKI](&ctx, &config->secureChannelPKI, NULL);
108643 else if(strcmp(s1: field, s2: "sessionPKI") == 0)
108644 retval = parseJsonJumpTable[UA_SERVERCONFIGFIELD_SECURITYPKI](&ctx, &config->sessionPKI, NULL);
108645#endif
108646 else {
108647 UA_LOG_WARNING(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "Field name '%s' unknown or misspelled. Maybe the feature is not enabled either.", field);
108648 }
108649 UA_free(ptr: field);
108650 if(retval != UA_STATUSCODE_GOOD) {
108651 UA_LOG_ERROR(logger: UA_Log_Stdout, category: UA_LOGCATEGORY_USERLAND, msg: "An error occurred while parsing the configuration file.");
108652 return retval;
108653 }
108654 break;
108655 }
108656 default:
108657 break;
108658 }
108659 ctx.index += 1;
108660 }
108661 return retval;
108662}
108663
108664UA_Server *
108665UA_Server_newFromFile(const UA_ByteString json_config) {
108666 UA_ServerConfig config;
108667 memset(s: &config, c: 0, n: sizeof(UA_ServerConfig));
108668 UA_StatusCode res = UA_ServerConfig_setDefault(config: &config);
108669 res |= parseJSONConfig(config: &config, json_config);
108670 if(res != UA_STATUSCODE_GOOD)
108671 return NULL;
108672 return UA_Server_newWithConfig(config: &config);
108673}
108674
108675UA_StatusCode
108676UA_ServerConfig_updateFromFile(UA_ServerConfig *config, const UA_ByteString json_config) {
108677 UA_StatusCode res = parseJSONConfig(config, json_config);
108678 return res;
108679}
108680
108681#ifdef UA_ENABLE_ENCRYPTION
108682static UA_ByteString
108683loadCertificateFile(const char *const path) {
108684 UA_ByteString fileContents = UA_STRING_NULL;
108685
108686 /* Open the file */
108687 FILE *fp = fopen(filename: path, modes: "rb");
108688 if(!fp) {
108689 errno = 0; /* We read errno also from the tcp layer... */
108690 return fileContents;
108691 }
108692
108693 /* Get the file length, allocate the data and read */
108694 fseek(stream: fp, off: 0, SEEK_END);
108695 fileContents.length = (size_t)ftell(stream: fp);
108696 fileContents.data = (UA_Byte *)UA_malloc(size: fileContents.length * sizeof(UA_Byte));
108697 if(fileContents.data) {
108698 fseek(stream: fp, off: 0, SEEK_SET);
108699 size_t read = fread(ptr: fileContents.data, size: sizeof(UA_Byte), n: fileContents.length, stream: fp);
108700 if(read != fileContents.length)
108701 UA_ByteString_clear(p: &fileContents);
108702 } else {
108703 fileContents.length = 0;
108704 }
108705 fclose(stream: fp);
108706
108707 return fileContents;
108708}
108709#endif
108710
108711/**** amalgamated original file "/plugins/historydata/ua_history_data_backend_memory.c" ****/
108712
108713/* This Source Code Form is subject to the terms of the Mozilla Public
108714 * License, v. 2.0. If a copy of the MPL was not distributed with this
108715 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
108716 *
108717 * Copyright 2018 (c) basysKom GmbH <opensource@basyskom.com> (Author: Peter Rustler)
108718 * Copyright 2021 (c) luibass92 <luibass92@live.it> (Author: Luigi Bassetta)
108719 */
108720
108721
108722#include <limits.h>
108723#include <string.h>
108724
108725typedef struct {
108726 UA_DateTime timestamp;
108727 UA_DataValue value;
108728} UA_DataValueMemoryStoreItem;
108729
108730static void
108731UA_DataValueMemoryStoreItem_clear(UA_DataValueMemoryStoreItem* item) {
108732 UA_DateTime_clear(p: &item->timestamp);
108733 UA_DataValue_clear(p: &item->value);
108734}
108735
108736typedef struct {
108737 UA_NodeId nodeId;
108738 UA_DataValueMemoryStoreItem **dataStore;
108739 size_t storeEnd;
108740 size_t storeSize;
108741 /* New field useful for circular buffer management */
108742 size_t lastInserted;
108743} UA_NodeIdStoreContextItem_backend_memory;
108744
108745static void
108746UA_NodeIdStoreContextItem_clear(UA_NodeIdStoreContextItem_backend_memory* item) {
108747 UA_NodeId_clear(p: &item->nodeId);
108748 for (size_t i = 0; i < item->storeEnd; ++i) {
108749 UA_DataValueMemoryStoreItem_clear(item: item->dataStore[i]);
108750 UA_free(ptr: item->dataStore[i]);
108751 }
108752 UA_free(ptr: item->dataStore);
108753}
108754
108755typedef struct {
108756 UA_NodeIdStoreContextItem_backend_memory *dataStore;
108757 size_t storeEnd;
108758 size_t storeSize;
108759 size_t initialStoreSize;
108760} UA_MemoryStoreContext;
108761
108762static void
108763UA_MemoryStoreContext_clear(UA_MemoryStoreContext* ctx) {
108764 for (size_t i = 0; i < ctx->storeEnd; ++i) {
108765 UA_NodeIdStoreContextItem_clear(item: &ctx->dataStore[i]);
108766 }
108767 UA_free(ptr: ctx->dataStore);
108768 memset(s: ctx, c: 0, n: sizeof(UA_MemoryStoreContext));
108769}
108770
108771static UA_NodeIdStoreContextItem_backend_memory *
108772getNewNodeIdContext_backend_memory(UA_MemoryStoreContext* context,
108773 UA_Server *server,
108774 const UA_NodeId *nodeId) {
108775 UA_MemoryStoreContext *ctx = (UA_MemoryStoreContext*)context;
108776 if (ctx->storeEnd >= ctx->storeSize) {
108777 size_t newStoreSize = ctx->storeSize * 2;
108778 if (newStoreSize == 0)
108779 return NULL;
108780 ctx->dataStore = (UA_NodeIdStoreContextItem_backend_memory*)UA_realloc(ptr: ctx->dataStore, size: (newStoreSize * sizeof(UA_NodeIdStoreContextItem_backend_memory)));
108781 if (!ctx->dataStore) {
108782 ctx->storeSize = 0;
108783 return NULL;
108784 }
108785 ctx->storeSize = newStoreSize;
108786 }
108787 UA_NodeIdStoreContextItem_backend_memory *item = &ctx->dataStore[ctx->storeEnd];
108788 UA_NodeId_copy(src: nodeId, dst: &item->nodeId);
108789 UA_DataValueMemoryStoreItem ** store = (UA_DataValueMemoryStoreItem **)UA_calloc(nmemb: ctx->initialStoreSize, size: sizeof(UA_DataValueMemoryStoreItem*));
108790 if (!store) {
108791 UA_NodeIdStoreContextItem_clear(item);
108792 return NULL;
108793 }
108794 item->dataStore = store;
108795 item->storeSize = ctx->initialStoreSize;
108796 item->storeEnd = 0;
108797 ++ctx->storeEnd;
108798 return item;
108799}
108800
108801static UA_NodeIdStoreContextItem_backend_memory *
108802getNodeIdStoreContextItem_backend_memory(UA_MemoryStoreContext* context,
108803 UA_Server *server,
108804 const UA_NodeId *nodeId)
108805{
108806 for (size_t i = 0; i < context->storeEnd; ++i) {
108807 if (UA_NodeId_equal(p1: nodeId, p2: &context->dataStore[i].nodeId)) {
108808 return &context->dataStore[i];
108809 }
108810 }
108811 return getNewNodeIdContext_backend_memory(context, server, nodeId);
108812}
108813
108814static UA_Boolean
108815binarySearch_backend_memory(const UA_NodeIdStoreContextItem_backend_memory* item,
108816 const UA_DateTime timestamp,
108817 size_t *index) {
108818 if (item->storeEnd == 0) {
108819 *index = item->storeEnd;
108820 return false;
108821 }
108822 size_t min = 0;
108823 size_t max = item->storeEnd - 1;
108824 while (min <= max) {
108825 *index = (min + max) / 2;
108826 if (item->dataStore[*index]->timestamp == timestamp) {
108827 return true;
108828 } else if (item->dataStore[*index]->timestamp < timestamp) {
108829 if (*index == item->storeEnd - 1) {
108830 *index = item->storeEnd;
108831 return false;
108832 }
108833 min = *index + 1;
108834 } else {
108835 if (*index == 0)
108836 return false;
108837 max = *index - 1;
108838 }
108839 }
108840 *index = min;
108841 return false;
108842
108843}
108844
108845static size_t
108846resultSize_backend_memory(UA_Server *server,
108847 void *context,
108848 const UA_NodeId *sessionId,
108849 void *sessionContext,
108850 const UA_NodeId * nodeId,
108851 size_t startIndex,
108852 size_t endIndex) {
108853 const UA_NodeIdStoreContextItem_backend_memory* item = getNodeIdStoreContextItem_backend_memory(context: (UA_MemoryStoreContext*)context, server, nodeId);
108854 if (item->storeEnd == 0
108855 || startIndex == item->storeEnd
108856 || endIndex == item->storeEnd)
108857 return 0;
108858 return endIndex - startIndex + 1;
108859}
108860
108861static size_t
108862getDateTimeMatch_backend_memory(UA_Server *server,
108863 void *context,
108864 const UA_NodeId *sessionId,
108865 void *sessionContext,
108866 const UA_NodeId * nodeId,
108867 const UA_DateTime timestamp,
108868 const MatchStrategy strategy) {
108869 const UA_NodeIdStoreContextItem_backend_memory* item = getNodeIdStoreContextItem_backend_memory(context: (UA_MemoryStoreContext*)context, server, nodeId);
108870 size_t current;
108871 UA_Boolean retval = binarySearch_backend_memory(item, timestamp, index: &current);
108872
108873 if ((strategy == MATCH_EQUAL
108874 || strategy == MATCH_EQUAL_OR_AFTER
108875 || strategy == MATCH_EQUAL_OR_BEFORE)
108876 && retval)
108877 return current;
108878 switch (strategy) {
108879 case MATCH_AFTER:
108880 if (retval)
108881 return current+1;
108882 return current;
108883 case MATCH_EQUAL_OR_AFTER:
108884 return current;
108885 case MATCH_EQUAL_OR_BEFORE:
108886 // retval == true aka "equal" is handled before
108887 // Fall through if !retval
108888 case MATCH_BEFORE:
108889 if (current > 0)
108890 return current-1;
108891 else
108892 return item->storeEnd;
108893 default:
108894 break;
108895 }
108896 return item->storeEnd;
108897}
108898
108899
108900static UA_StatusCode
108901serverSetHistoryData_backend_memory(UA_Server *server,
108902 void *context,
108903 const UA_NodeId *sessionId,
108904 void *sessionContext,
108905 const UA_NodeId * nodeId,
108906 UA_Boolean historizing,
108907 const UA_DataValue *value)
108908{
108909 UA_NodeIdStoreContextItem_backend_memory *item = getNodeIdStoreContextItem_backend_memory(context: (UA_MemoryStoreContext*)context, server, nodeId);
108910
108911 if (item->storeEnd >= item->storeSize) {
108912 size_t newStoreSize = item->storeSize == 0 ? INITIAL_MEMORY_STORE_SIZE : item->storeSize * 2;
108913 item->dataStore = (UA_DataValueMemoryStoreItem **)UA_realloc(ptr: item->dataStore, size: (newStoreSize * sizeof(UA_DataValueMemoryStoreItem*)));
108914 if (!item->dataStore) {
108915 item->storeSize = 0;
108916 return UA_STATUSCODE_BADOUTOFMEMORY;
108917 }
108918 item->storeSize = newStoreSize;
108919 }
108920 UA_DateTime timestamp = 0;
108921 if (value->hasSourceTimestamp) {
108922 timestamp = value->sourceTimestamp;
108923 } else if (value->hasServerTimestamp) {
108924 timestamp = value->serverTimestamp;
108925 } else {
108926 timestamp = UA_DateTime_now();
108927 }
108928 UA_DataValueMemoryStoreItem *newItem = (UA_DataValueMemoryStoreItem *)UA_calloc(nmemb: 1, size: sizeof(UA_DataValueMemoryStoreItem));
108929 newItem->timestamp = timestamp;
108930 UA_DataValue_copy(src: value, dst: &newItem->value);
108931 if(!newItem->value.hasServerTimestamp) {
108932 newItem->value.serverTimestamp = timestamp;
108933 newItem->value.hasServerTimestamp = true;
108934 }
108935 size_t index = getDateTimeMatch_backend_memory(server,
108936 context,
108937 NULL,
108938 NULL,
108939 nodeId,
108940 timestamp,
108941 strategy: MATCH_EQUAL_OR_AFTER);
108942 if (item->storeEnd > 0 && index < item->storeEnd) {
108943 memmove(dest: &item->dataStore[index+1], src: &item->dataStore[index], n: sizeof(UA_DataValueMemoryStoreItem*) * (item->storeEnd - index));
108944 }
108945 item->dataStore[index] = newItem;
108946 ++item->storeEnd;
108947 return UA_STATUSCODE_GOOD;
108948}
108949
108950static void
108951UA_MemoryStoreContext_delete(UA_MemoryStoreContext* ctx) {
108952 UA_MemoryStoreContext_clear(ctx);
108953 UA_free(ptr: ctx);
108954}
108955
108956static size_t
108957getEnd_backend_memory(UA_Server *server,
108958 void *context,
108959 const UA_NodeId *sessionId,
108960 void *sessionContext,
108961 const UA_NodeId * nodeId) {
108962 const UA_NodeIdStoreContextItem_backend_memory* item = getNodeIdStoreContextItem_backend_memory(context: (UA_MemoryStoreContext*)context, server, nodeId);
108963 return item->storeEnd;
108964}
108965
108966static size_t
108967lastIndex_backend_memory(UA_Server *server,
108968 void *context,
108969 const UA_NodeId *sessionId,
108970 void *sessionContext,
108971 const UA_NodeId * nodeId) {
108972 const UA_NodeIdStoreContextItem_backend_memory* item = getNodeIdStoreContextItem_backend_memory(context: (UA_MemoryStoreContext*)context, server, nodeId);
108973 if (item->storeEnd == 0)
108974 return 0;
108975 return item->storeEnd - 1;
108976}
108977
108978static size_t
108979firstIndex_backend_memory(UA_Server *server,
108980 void *context,
108981 const UA_NodeId *sessionId,
108982 void *sessionContext,
108983 const UA_NodeId * nodeId) {
108984 return 0;
108985}
108986
108987static UA_Boolean
108988boundSupported_backend_memory(UA_Server *server,
108989 void *context,
108990 const UA_NodeId *sessionId,
108991 void *sessionContext,
108992 const UA_NodeId * nodeId) {
108993 return true;
108994}
108995
108996static UA_Boolean
108997timestampsToReturnSupported_backend_memory(UA_Server *server,
108998 void *context,
108999 const UA_NodeId *sessionId,
109000 void *sessionContext,
109001 const UA_NodeId *nodeId,
109002 const UA_TimestampsToReturn timestampsToReturn) {
109003 const UA_NodeIdStoreContextItem_backend_memory* item = getNodeIdStoreContextItem_backend_memory(context: (UA_MemoryStoreContext*)context, server, nodeId);
109004 if (item->storeEnd == 0) {
109005 return true;
109006 }
109007 if (timestampsToReturn == UA_TIMESTAMPSTORETURN_NEITHER
109008 || timestampsToReturn == UA_TIMESTAMPSTORETURN_INVALID
109009 || (timestampsToReturn == UA_TIMESTAMPSTORETURN_SERVER
109010 && !item->dataStore[0]->value.hasServerTimestamp)
109011 || (timestampsToReturn == UA_TIMESTAMPSTORETURN_SOURCE
109012 && !item->dataStore[0]->value.hasSourceTimestamp)
109013 || (timestampsToReturn == UA_TIMESTAMPSTORETURN_BOTH
109014 && !(item->dataStore[0]->value.hasSourceTimestamp
109015 && item->dataStore[0]->value.hasServerTimestamp))) {
109016 return false;
109017 }
109018 return true;
109019}
109020
109021static const UA_DataValue*
109022getDataValue_backend_memory(UA_Server *server,
109023 void *context,
109024 const UA_NodeId *sessionId,
109025 void *sessionContext,
109026 const UA_NodeId * nodeId, size_t index) {
109027 const UA_NodeIdStoreContextItem_backend_memory* item = getNodeIdStoreContextItem_backend_memory(context: (UA_MemoryStoreContext*)context, server, nodeId);
109028 return &item->dataStore[index]->value;
109029}
109030
109031static UA_StatusCode
109032UA_DataValue_backend_copyRange(const UA_DataValue *src, UA_DataValue *dst,
109033 const UA_NumericRange range)
109034{
109035 memcpy(dest: dst, src: src, n: sizeof(UA_DataValue));
109036 if (src->hasValue)
109037 return UA_Variant_copyRange(src: &src->value, dst: &dst->value, range);
109038 return UA_STATUSCODE_BADDATAUNAVAILABLE;
109039}
109040
109041static UA_StatusCode
109042copyDataValues_backend_memory(UA_Server *server,
109043 void *context,
109044 const UA_NodeId *sessionId,
109045 void *sessionContext,
109046 const UA_NodeId * nodeId,
109047 size_t startIndex,
109048 size_t endIndex,
109049 UA_Boolean reverse,
109050 size_t maxValues,
109051 UA_NumericRange range,
109052 UA_Boolean releaseContinuationPoints,
109053 const UA_ByteString *continuationPoint,
109054 UA_ByteString *outContinuationPoint,
109055 size_t * providedValues,
109056 UA_DataValue * values)
109057{
109058 size_t skip = 0;
109059 if (continuationPoint->length > 0) {
109060 if (continuationPoint->length == sizeof(size_t)) {
109061 skip = *((size_t*)(continuationPoint->data));
109062 } else {
109063 return UA_STATUSCODE_BADCONTINUATIONPOINTINVALID;
109064 }
109065 }
109066 const UA_NodeIdStoreContextItem_backend_memory* item = getNodeIdStoreContextItem_backend_memory(context: (UA_MemoryStoreContext*)context, server, nodeId);
109067 size_t index = startIndex;
109068 size_t counter = 0;
109069 size_t skipedValues = 0;
109070 if (reverse) {
109071 while (index >= endIndex && index < item->storeEnd && counter < maxValues) {
109072 if (skipedValues++ >= skip) {
109073 if (range.dimensionsSize > 0) {
109074 UA_DataValue_backend_copyRange(src: &item->dataStore[index]->value, dst: &values[counter], range);
109075 } else {
109076 UA_DataValue_copy(src: &item->dataStore[index]->value, dst: &values[counter]);
109077 }
109078 ++counter;
109079 }
109080 --index;
109081 }
109082 } else {
109083 while (index <= endIndex && counter < maxValues) {
109084 if (skipedValues++ >= skip) {
109085 if (range.dimensionsSize > 0) {
109086 UA_DataValue_backend_copyRange(src: &item->dataStore[index]->value, dst: &values[counter], range);
109087 } else {
109088 UA_DataValue_copy(src: &item->dataStore[index]->value, dst: &values[counter]);
109089 }
109090 ++counter;
109091 }
109092 ++index;
109093 }
109094 }
109095
109096 if (providedValues)
109097 *providedValues = counter;
109098
109099 if ((!reverse && (endIndex-startIndex-skip+1) > counter) || (reverse && (startIndex-endIndex-skip+1) > counter)) {
109100 outContinuationPoint->length = sizeof(size_t);
109101 size_t t = sizeof(size_t);
109102 outContinuationPoint->data = (UA_Byte*)UA_malloc(size: t);
109103 *((size_t*)(outContinuationPoint->data)) = skip + counter;
109104 }
109105
109106 return UA_STATUSCODE_GOOD;
109107}
109108
109109static UA_StatusCode
109110insertDataValue_backend_memory(UA_Server *server,
109111 void *hdbContext,
109112 const UA_NodeId *sessionId,
109113 void *sessionContext,
109114 const UA_NodeId *nodeId,
109115 const UA_DataValue *value)
109116{
109117 if (!value->hasSourceTimestamp && !value->hasServerTimestamp)
109118 return UA_STATUSCODE_BADINVALIDTIMESTAMP;
109119 const UA_DateTime timestamp = value->hasSourceTimestamp ? value->sourceTimestamp : value->serverTimestamp;
109120 UA_NodeIdStoreContextItem_backend_memory* item = getNodeIdStoreContextItem_backend_memory(context: (UA_MemoryStoreContext*)hdbContext, server, nodeId);
109121
109122 size_t index = getDateTimeMatch_backend_memory(server,
109123 context: hdbContext,
109124 sessionId,
109125 sessionContext,
109126 nodeId,
109127 timestamp,
109128 strategy: MATCH_EQUAL_OR_AFTER);
109129 if (item->storeEnd != index && item->dataStore[index]->timestamp == timestamp)
109130 return UA_STATUSCODE_BADENTRYEXISTS;
109131
109132 if (item->storeEnd >= item->storeSize) {
109133 size_t newStoreSize = item->storeSize == 0 ? INITIAL_MEMORY_STORE_SIZE : item->storeSize * 2;
109134 item->dataStore = (UA_DataValueMemoryStoreItem **)UA_realloc(ptr: item->dataStore, size: (newStoreSize * sizeof(UA_DataValueMemoryStoreItem*)));
109135 if (!item->dataStore) {
109136 item->storeSize = 0;
109137 return UA_STATUSCODE_BADOUTOFMEMORY;
109138 }
109139 item->storeSize = newStoreSize;
109140 }
109141 UA_DataValueMemoryStoreItem *newItem = (UA_DataValueMemoryStoreItem *)UA_calloc(nmemb: 1, size: sizeof(UA_DataValueMemoryStoreItem));
109142 newItem->timestamp = timestamp;
109143 UA_DataValue_copy(src: value, dst: &newItem->value);
109144 if(!newItem->value.hasServerTimestamp) {
109145 newItem->value.serverTimestamp = timestamp;
109146 newItem->value.hasServerTimestamp = true;
109147 }
109148
109149 if (item->storeEnd > 0 && index < item->storeEnd) {
109150 memmove(dest: &item->dataStore[index+1], src: &item->dataStore[index], n: sizeof(UA_DataValueMemoryStoreItem*) * (item->storeEnd - index));
109151 }
109152 item->dataStore[index] = newItem;
109153 ++item->storeEnd;
109154 return UA_STATUSCODE_GOOD;
109155}
109156
109157static UA_StatusCode
109158replaceDataValue_backend_memory(UA_Server *server,
109159 void *hdbContext,
109160 const UA_NodeId *sessionId,
109161 void *sessionContext,
109162 const UA_NodeId *nodeId,
109163 const UA_DataValue *value)
109164{
109165 if (!value->hasSourceTimestamp && !value->hasServerTimestamp)
109166 return UA_STATUSCODE_BADINVALIDTIMESTAMP;
109167 const UA_DateTime timestamp = value->hasSourceTimestamp ? value->sourceTimestamp : value->serverTimestamp;
109168 UA_NodeIdStoreContextItem_backend_memory* item = getNodeIdStoreContextItem_backend_memory(context: (UA_MemoryStoreContext*)hdbContext, server, nodeId);
109169
109170 size_t index = getDateTimeMatch_backend_memory(server,
109171 context: hdbContext,
109172 sessionId,
109173 sessionContext,
109174 nodeId,
109175 timestamp,
109176 strategy: MATCH_EQUAL);
109177 if (index == item->storeEnd)
109178 return UA_STATUSCODE_BADNOENTRYEXISTS;
109179 UA_DataValue_clear(p: &item->dataStore[index]->value);
109180 UA_DataValue_copy(src: value, dst: &item->dataStore[index]->value);
109181 if(!item->dataStore[index]->value.hasServerTimestamp) {
109182 item->dataStore[index]->value.serverTimestamp = timestamp;
109183 item->dataStore[index]->value.hasServerTimestamp = true;
109184 }
109185 return UA_STATUSCODE_GOOD;
109186}
109187
109188static UA_StatusCode
109189updateDataValue_backend_memory(UA_Server *server,
109190 void *hdbContext,
109191 const UA_NodeId *sessionId,
109192 void *sessionContext,
109193 const UA_NodeId *nodeId,
109194 const UA_DataValue *value)
109195{
109196 // we first try to replace, because it is cheap
109197 UA_StatusCode ret = replaceDataValue_backend_memory(server,
109198 hdbContext,
109199 sessionId,
109200 sessionContext,
109201 nodeId,
109202 value);
109203 if (ret == UA_STATUSCODE_GOOD)
109204 return UA_STATUSCODE_GOODENTRYREPLACED;
109205
109206 ret = insertDataValue_backend_memory(server,
109207 hdbContext,
109208 sessionId,
109209 sessionContext,
109210 nodeId,
109211 value);
109212 if (ret == UA_STATUSCODE_GOOD)
109213 return UA_STATUSCODE_GOODENTRYINSERTED;
109214
109215 return ret;
109216}
109217
109218static UA_StatusCode
109219removeDataValue_backend_memory(UA_Server *server,
109220 void *hdbContext,
109221 const UA_NodeId *sessionId,
109222 void *sessionContext,
109223 const UA_NodeId *nodeId,
109224 UA_DateTime startTimestamp,
109225 UA_DateTime endTimestamp)
109226{
109227 UA_NodeIdStoreContextItem_backend_memory* item = getNodeIdStoreContextItem_backend_memory(context: (UA_MemoryStoreContext*)hdbContext, server, nodeId);
109228 size_t storeEnd = item->storeEnd;
109229 // The first index which will be deleted
109230 size_t index1;
109231 // the first index which is not deleted
109232 size_t index2;
109233 if (startTimestamp > endTimestamp) {
109234 return UA_STATUSCODE_BADTIMESTAMPNOTSUPPORTED;
109235 }
109236 if (startTimestamp == endTimestamp) {
109237 index1 = getDateTimeMatch_backend_memory(server,
109238 context: hdbContext,
109239 sessionId,
109240 sessionContext,
109241 nodeId,
109242 timestamp: startTimestamp,
109243 strategy: MATCH_EQUAL);
109244 if (index1 == storeEnd)
109245 return UA_STATUSCODE_BADNODATA;
109246 index2 = index1 + 1;
109247 } else {
109248 index1 = getDateTimeMatch_backend_memory(server,
109249 context: hdbContext,
109250 sessionId,
109251 sessionContext,
109252 nodeId,
109253 timestamp: startTimestamp,
109254 strategy: MATCH_EQUAL_OR_AFTER);
109255 index2 = getDateTimeMatch_backend_memory(server,
109256 context: hdbContext,
109257 sessionId,
109258 sessionContext,
109259 nodeId,
109260 timestamp: endTimestamp,
109261 strategy: MATCH_BEFORE);
109262 if (index2 == storeEnd || index1 == storeEnd || index1 > index2 )
109263 return UA_STATUSCODE_BADNODATA;
109264 ++index2;
109265 }
109266#ifndef __clang_analyzer__
109267 for (size_t i = index1; i < index2; ++i) {
109268 UA_DataValueMemoryStoreItem_clear(item: item->dataStore[i]);
109269 UA_free(ptr: item->dataStore[i]);
109270 }
109271 memmove(dest: &item->dataStore[index1], src: &item->dataStore[index2], n: sizeof(UA_DataValueMemoryStoreItem*) * (item->storeEnd - index2));
109272 item->storeEnd -= index2 - index1;
109273#else
109274 (void)index1;
109275 (void)index2;
109276#endif
109277 return UA_STATUSCODE_GOOD;
109278}
109279
109280static void
109281deleteMembers_backend_memory(UA_HistoryDataBackend *backend)
109282{
109283 if (backend == NULL || backend->context == NULL)
109284 return;
109285 UA_MemoryStoreContext_clear(ctx: (UA_MemoryStoreContext*)backend->context);
109286 UA_free(ptr: backend->context);
109287}
109288
109289
109290
109291UA_HistoryDataBackend
109292UA_HistoryDataBackend_Memory(size_t initialNodeIdStoreSize, size_t initialDataStoreSize) {
109293 if (initialNodeIdStoreSize == 0)
109294 initialNodeIdStoreSize = 1;
109295 if (initialDataStoreSize == 0)
109296 initialDataStoreSize = 1;
109297 UA_HistoryDataBackend result;
109298 memset(s: &result, c: 0, n: sizeof(UA_HistoryDataBackend));
109299 UA_MemoryStoreContext *ctx = (UA_MemoryStoreContext *)UA_calloc(nmemb: 1, size: sizeof(UA_MemoryStoreContext));
109300 if (!ctx)
109301 return result;
109302 ctx->dataStore = (UA_NodeIdStoreContextItem_backend_memory*)UA_calloc(nmemb: initialNodeIdStoreSize, size: sizeof(UA_NodeIdStoreContextItem_backend_memory));
109303 ctx->initialStoreSize = initialDataStoreSize;
109304 ctx->storeSize = initialNodeIdStoreSize;
109305 ctx->storeEnd = 0;
109306 result.serverSetHistoryData = &serverSetHistoryData_backend_memory;
109307 result.resultSize = &resultSize_backend_memory;
109308 result.getEnd = &getEnd_backend_memory;
109309 result.lastIndex = &lastIndex_backend_memory;
109310 result.firstIndex = &firstIndex_backend_memory;
109311 result.getDateTimeMatch = &getDateTimeMatch_backend_memory;
109312 result.copyDataValues = &copyDataValues_backend_memory;
109313 result.getDataValue = &getDataValue_backend_memory;
109314 result.boundSupported = &boundSupported_backend_memory;
109315 result.timestampsToReturnSupported = &timestampsToReturnSupported_backend_memory;
109316 result.insertDataValue = &insertDataValue_backend_memory;
109317 result.updateDataValue = &updateDataValue_backend_memory;
109318 result.replaceDataValue = &replaceDataValue_backend_memory;
109319 result.removeDataValue = &removeDataValue_backend_memory;
109320 result.deleteMembers = &deleteMembers_backend_memory;
109321 result.getHistoryData = NULL;
109322 result.context = ctx;
109323 return result;
109324}
109325
109326void
109327UA_HistoryDataBackend_Memory_clear(UA_HistoryDataBackend *backend)
109328{
109329 UA_MemoryStoreContext *ctx = (UA_MemoryStoreContext*)backend->context;
109330 UA_MemoryStoreContext_delete(ctx);
109331 memset(s: backend, c: 0, n: sizeof(UA_HistoryDataBackend));
109332}
109333
109334/* Circular buffer implementation */
109335
109336static UA_NodeIdStoreContextItem_backend_memory *
109337getNewNodeIdContext_backend_memory_Circular(UA_MemoryStoreContext *context,
109338 UA_Server *server,
109339 const UA_NodeId *nodeId) {
109340 UA_MemoryStoreContext *ctx = (UA_MemoryStoreContext *)context;
109341 if(ctx->storeEnd >= ctx->storeSize) {
109342 return NULL;
109343 }
109344 UA_NodeIdStoreContextItem_backend_memory *item = &ctx->dataStore[ctx->storeEnd];
109345 UA_NodeId_copy(src: nodeId, dst: &item->nodeId);
109346 UA_DataValueMemoryStoreItem **store = (UA_DataValueMemoryStoreItem **)UA_calloc(nmemb: ctx->initialStoreSize, size: sizeof(UA_DataValueMemoryStoreItem *));
109347 if(!store) {
109348 UA_NodeIdStoreContextItem_clear(item);
109349 return NULL;
109350 }
109351 item->dataStore = store;
109352 item->storeSize = ctx->initialStoreSize;
109353 item->storeEnd = 0;
109354 ++ctx->storeEnd;
109355 return item;
109356}
109357
109358static UA_NodeIdStoreContextItem_backend_memory *
109359getNodeIdStoreContextItem_backend_memory_Circular(UA_MemoryStoreContext *context,
109360 UA_Server *server,
109361 const UA_NodeId *nodeId) {
109362 for(size_t i = 0; i < context->storeEnd; ++i) {
109363 if(UA_NodeId_equal(p1: nodeId, p2: &context->dataStore[i].nodeId)) {
109364 return &context->dataStore[i];
109365 }
109366 }
109367 return getNewNodeIdContext_backend_memory_Circular(context, server, nodeId);
109368}
109369
109370static UA_StatusCode
109371serverSetHistoryData_backend_memory_Circular(UA_Server *server,
109372 void *context,
109373 const UA_NodeId *sessionId,
109374 void *sessionContext,
109375 const UA_NodeId *nodeId,
109376 UA_Boolean historizing,
109377 const UA_DataValue *value) {
109378 UA_NodeIdStoreContextItem_backend_memory *item = getNodeIdStoreContextItem_backend_memory_Circular(context: (UA_MemoryStoreContext *)context, server, nodeId);
109379 if(item == NULL) {
109380 return UA_STATUSCODE_BADOUTOFMEMORY;
109381 }
109382 if(item->lastInserted >= item->storeSize) {
109383 /* If the buffer size is overcomed, push new elements from the start of the buffer */
109384 item->lastInserted = 0;
109385 }
109386 UA_DateTime timestamp = 0;
109387 if(value->hasSourceTimestamp) {
109388 timestamp = value->sourceTimestamp;
109389 } else if(value->hasServerTimestamp) {
109390 timestamp = value->serverTimestamp;
109391 } else {
109392 timestamp = UA_DateTime_now();
109393 }
109394 UA_DataValueMemoryStoreItem *newItem = (UA_DataValueMemoryStoreItem *)UA_calloc(nmemb: 1, size: sizeof(UA_DataValueMemoryStoreItem));
109395 newItem->timestamp = timestamp;
109396 UA_DataValue_copy(src: value, dst: &newItem->value);
109397 if(!newItem->value.hasServerTimestamp) {
109398 newItem->value.serverTimestamp = timestamp;
109399 newItem->value.hasServerTimestamp = true;
109400 }
109401
109402
109403 /* This implementation does NOT sort values by timestamp */
109404
109405 if(item->dataStore[item->lastInserted] != NULL) {
109406 UA_DataValueMemoryStoreItem_clear(item: item->dataStore[item->lastInserted]);
109407 UA_free(ptr: item->dataStore[item->lastInserted]);
109408 }
109409 item->dataStore[item->lastInserted] = newItem;
109410 ++item->lastInserted;
109411
109412 if(item->storeEnd < item->storeSize) {
109413 ++item->storeEnd;
109414 }
109415
109416 return UA_STATUSCODE_GOOD;
109417}
109418
109419static size_t
109420getResultSize_service_Circular(const UA_HistoryDataBackend *backend, UA_Server *server,
109421 const UA_NodeId *sessionId, void *sessionContext,
109422 const UA_NodeId *nodeId, UA_DateTime start,
109423 UA_DateTime end, UA_UInt32 numValuesPerNode,
109424 UA_Boolean returnBounds, size_t *startIndex,
109425 size_t *endIndex, UA_Boolean *addFirst,
109426 UA_Boolean *addLast, UA_Boolean *reverse) {
109427 *startIndex = 0;
109428 *endIndex = backend->lastIndex(server, backend->context, sessionId, sessionContext, nodeId);
109429 *addFirst = false;
109430 *addLast = false;
109431 if(end == LLONG_MIN) {
109432 *reverse = false;
109433 } else if(start == LLONG_MIN) {
109434 *reverse = true;
109435 } else {
109436 *reverse = end < start;
109437 }
109438
109439 size_t size = 0;
109440 const UA_NodeIdStoreContextItem_backend_memory *item = getNodeIdStoreContextItem_backend_memory_Circular(context: (UA_MemoryStoreContext *)backend->context, server, nodeId);
109441 if(item == NULL) {
109442 size = 0;
109443 } else {
109444 size = item->storeEnd;
109445 }
109446 return size;
109447}
109448
109449static UA_StatusCode
109450getHistoryData_service_Circular(UA_Server *server,
109451 const UA_NodeId *sessionId,
109452 void *sessionContext,
109453 const UA_HistoryDataBackend *backend,
109454 const UA_DateTime start,
109455 const UA_DateTime end,
109456 const UA_NodeId *nodeId,
109457 size_t maxSize,
109458 UA_UInt32 numValuesPerNode,
109459 UA_Boolean returnBounds,
109460 UA_TimestampsToReturn timestampsToReturn,
109461 UA_NumericRange range,
109462 UA_Boolean releaseContinuationPoints,
109463 const UA_ByteString *continuationPoint,
109464 UA_ByteString *outContinuationPoint,
109465 UA_HistoryData *historyData) {
109466 size_t *resultSize = &historyData->dataValuesSize;
109467 UA_DataValue **result = &historyData->dataValues;
109468 size_t skip = 0;
109469 UA_ByteString backendContinuationPoint;
109470 UA_ByteString_init(p: &backendContinuationPoint);
109471 if(continuationPoint->length > 0) {
109472 if(continuationPoint->length < sizeof(size_t))
109473 return UA_STATUSCODE_BADCONTINUATIONPOINTINVALID;
109474 skip = *((size_t *)(continuationPoint->data));
109475 backendContinuationPoint.length = continuationPoint->length - sizeof(size_t);
109476 backendContinuationPoint.data = continuationPoint->data + sizeof(size_t);
109477 }
109478 size_t storeEnd = backend->getEnd(server, backend->context, sessionId, sessionContext, nodeId);
109479 size_t startIndex;
109480 size_t endIndex;
109481 UA_Boolean addFirst;
109482 UA_Boolean addLast;
109483 UA_Boolean reverse;
109484 size_t _resultSize = getResultSize_service_Circular(backend,
109485 server,
109486 sessionId,
109487 sessionContext,
109488 nodeId,
109489 start,
109490 end,
109491 numValuesPerNode: numValuesPerNode == 0 ? 0 : numValuesPerNode + (UA_UInt32)skip,
109492 returnBounds,
109493 startIndex: &startIndex,
109494 endIndex: &endIndex,
109495 addFirst: &addFirst,
109496 addLast: &addLast,
109497 reverse: &reverse);
109498 *resultSize = _resultSize - skip;
109499 if(*resultSize > maxSize) {
109500 *resultSize = maxSize;
109501 }
109502 UA_DataValue *outResult = (UA_DataValue *)UA_Array_new(size: *resultSize, type: &UA_TYPES[UA_TYPES_DATAVALUE]);
109503 if(!outResult) {
109504 *resultSize = 0;
109505 return UA_STATUSCODE_BADOUTOFMEMORY;
109506 }
109507 *result = outResult;
109508 size_t counter = 0;
109509 if(addFirst) {
109510 if(skip == 0) {
109511 outResult[counter].hasStatus = true;
109512 outResult[counter].status = UA_STATUSCODE_BADBOUNDNOTFOUND;
109513 outResult[counter].hasSourceTimestamp = true;
109514 if(start == LLONG_MIN) {
109515 outResult[counter].sourceTimestamp = end;
109516 } else {
109517 outResult[counter].sourceTimestamp = start;
109518 }
109519 ++counter;
109520 }
109521 }
109522 UA_ByteString backendOutContinuationPoint;
109523 UA_ByteString_init(p: &backendOutContinuationPoint);
109524 if(endIndex != storeEnd && startIndex != storeEnd) {
109525 size_t retval = 0;
109526 size_t valueSize = *resultSize - counter;
109527 if(valueSize + skip > _resultSize - addFirst - addLast) {
109528 if(skip == 0) {
109529 valueSize = _resultSize - addFirst - addLast;
109530 } else {
109531 valueSize = _resultSize - skip - addLast;
109532 }
109533 }
109534 UA_StatusCode ret = UA_STATUSCODE_GOOD;
109535 if(valueSize > 0)
109536 ret = backend->copyDataValues(server,
109537 backend->context,
109538 sessionId,
109539 sessionContext,
109540 nodeId,
109541 startIndex,
109542 endIndex,
109543 reverse,
109544 valueSize,
109545 range,
109546 releaseContinuationPoints,
109547 &backendContinuationPoint,
109548 &backendOutContinuationPoint,
109549 &retval,
109550 &outResult[counter]);
109551 if(ret != UA_STATUSCODE_GOOD) {
109552 UA_Array_delete(p: outResult, size: *resultSize, type: &UA_TYPES[UA_TYPES_DATAVALUE]);
109553 *result = NULL;
109554 *resultSize = 0;
109555 return ret;
109556 }
109557 counter += retval;
109558 }
109559 if(addLast && counter < *resultSize) {
109560 outResult[counter].hasStatus = true;
109561 outResult[counter].status = UA_STATUSCODE_BADBOUNDNOTFOUND;
109562 outResult[counter].hasSourceTimestamp = true;
109563 if(start == LLONG_MIN && storeEnd != backend->firstIndex(server, backend->context, sessionId, sessionContext, nodeId)) {
109564 outResult[counter].sourceTimestamp = backend->getDataValue(server, backend->context, sessionId, sessionContext, nodeId, endIndex)->sourceTimestamp - UA_DATETIME_SEC;
109565 } else if(end == LLONG_MIN && storeEnd != backend->firstIndex(server, backend->context, sessionId, sessionContext, nodeId)) {
109566 outResult[counter].sourceTimestamp = backend->getDataValue(server, backend->context, sessionId, sessionContext, nodeId, endIndex)->sourceTimestamp + UA_DATETIME_SEC;
109567 } else {
109568 outResult[counter].sourceTimestamp = end;
109569 }
109570 }
109571 // there are more values
109572 if(skip + *resultSize < _resultSize
109573 // there are not more values for this request, but there are more values in
109574 // database
109575 || (backendOutContinuationPoint.length > 0 && numValuesPerNode != 0)
109576 // we deliver just one value which is a FIRST/LAST value
109577 || (skip == 0 && addFirst == true && *resultSize == 1)) {
109578 if(UA_ByteString_allocBuffer(bs: outContinuationPoint, length: backendOutContinuationPoint.length + sizeof(size_t)) != UA_STATUSCODE_GOOD) {
109579 return UA_STATUSCODE_BADOUTOFMEMORY;
109580 }
109581 *((size_t *)(outContinuationPoint->data)) = skip + *resultSize;
109582 if(backendOutContinuationPoint.length > 0)
109583 memcpy(dest: outContinuationPoint->data + sizeof(size_t), src: backendOutContinuationPoint.data, n: backendOutContinuationPoint.length);
109584 }
109585 UA_ByteString_clear(p: &backendOutContinuationPoint);
109586 return UA_STATUSCODE_GOOD;
109587}
109588
109589UA_HistoryDataBackend
109590UA_HistoryDataBackend_Memory_Circular(size_t initialNodeIdStoreSize, size_t initialDataStoreSize) {
109591 UA_HistoryDataBackend result = UA_HistoryDataBackend_Memory(initialNodeIdStoreSize, initialDataStoreSize);
109592 result.serverSetHistoryData = &serverSetHistoryData_backend_memory_Circular;
109593 result.getHistoryData = &getHistoryData_service_Circular;
109594 return result;
109595}
109596
109597/**** amalgamated original file "/plugins/historydata/ua_history_data_gathering_default.c" ****/
109598
109599/* This Source Code Form is subject to the terms of the Mozilla Public
109600 * License, v. 2.0. If a copy of the MPL was not distributed with this
109601 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
109602 *
109603 * Copyright 2018 (c) basysKom GmbH <opensource@basyskom.com> (Author: Peter Rustler)
109604 * Copyright 2021 (c) luibass92 <luibass92@live.it> (Author: Luigi Bassetta)
109605 */
109606
109607
109608#include <string.h>
109609
109610typedef struct {
109611 UA_NodeId nodeId;
109612 UA_HistorizingNodeIdSettings setting;
109613 UA_MonitoredItemCreateResult monitoredResult;
109614} UA_NodeIdStoreContextItem_gathering_default;
109615
109616typedef struct {
109617 UA_NodeIdStoreContextItem_gathering_default *dataStore;
109618 size_t storeEnd;
109619 size_t storeSize;
109620} UA_NodeIdStoreContext;
109621
109622static void
109623dataChangeCallback_gathering_default(UA_Server *server,
109624 UA_UInt32 monitoredItemId,
109625 void *monitoredItemContext,
109626 const UA_NodeId *nodeId,
109627 void *nodeContext,
109628 UA_UInt32 attributeId,
109629 const UA_DataValue *value)
109630{
109631 UA_NodeIdStoreContextItem_gathering_default *context = (UA_NodeIdStoreContextItem_gathering_default*)monitoredItemContext;
109632 context->setting.historizingBackend.serverSetHistoryData(server,
109633 context->setting.historizingBackend.context,
109634 NULL,
109635 NULL,
109636 nodeId,
109637 UA_TRUE,
109638 value);
109639}
109640
109641static UA_NodeIdStoreContextItem_gathering_default*
109642getNodeIdStoreContextItem_gathering_default(UA_NodeIdStoreContext *context,
109643 const UA_NodeId *nodeId)
109644{
109645 for (size_t i = 0; i < context->storeEnd; ++i) {
109646 if (UA_NodeId_equal(p1: &context->dataStore[i].nodeId, p2: nodeId)) {
109647 return &context->dataStore[i];
109648 }
109649 }
109650 return NULL;
109651}
109652
109653static UA_StatusCode
109654startPoll(UA_Server *server, UA_NodeIdStoreContextItem_gathering_default *item)
109655{
109656 UA_MonitoredItemCreateRequest monitorRequest =
109657 UA_MonitoredItemCreateRequest_default(nodeId: item->nodeId);
109658 monitorRequest.requestedParameters.samplingInterval = (double)item->setting.pollingInterval;
109659 monitorRequest.monitoringMode = UA_MONITORINGMODE_REPORTING;
109660 item->monitoredResult =
109661 UA_Server_createDataChangeMonitoredItem(server,
109662 timestampsToReturn: UA_TIMESTAMPSTORETURN_BOTH,
109663 item: monitorRequest,
109664 monitoredItemContext: item,
109665 callback: &dataChangeCallback_gathering_default);
109666 return item->monitoredResult.statusCode;
109667}
109668
109669static UA_StatusCode
109670stopPoll(UA_Server *server, UA_NodeIdStoreContextItem_gathering_default *item)
109671{
109672 UA_StatusCode retval = UA_Server_deleteMonitoredItem(server, monitoredItemId: item->monitoredResult.monitoredItemId);
109673 UA_MonitoredItemCreateResult_init(p: &item->monitoredResult);
109674 return retval;
109675}
109676
109677static UA_StatusCode
109678stopPoll_gathering_default(UA_Server *server,
109679 void *context,
109680 const UA_NodeId *nodeId)
109681{
109682 UA_NodeIdStoreContext *ctx = (UA_NodeIdStoreContext *)context;
109683 UA_NodeIdStoreContextItem_gathering_default *item = getNodeIdStoreContextItem_gathering_default(context: ctx, nodeId);
109684 if (!item) {
109685 return UA_STATUSCODE_BADNODEIDUNKNOWN;
109686 }
109687 if (item->setting.historizingUpdateStrategy != UA_HISTORIZINGUPDATESTRATEGY_POLL)
109688 return UA_STATUSCODE_BADNODEIDINVALID;
109689 if (item->monitoredResult.monitoredItemId == 0)
109690 return UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
109691 return stopPoll(server, item);
109692}
109693
109694static UA_StatusCode
109695startPoll_gathering_default(UA_Server *server,
109696 void *context,
109697 const UA_NodeId *nodeId)
109698{
109699 UA_NodeIdStoreContext *ctx = (UA_NodeIdStoreContext *)context;
109700 UA_NodeIdStoreContextItem_gathering_default *item = getNodeIdStoreContextItem_gathering_default(context: ctx, nodeId);
109701 if (!item) {
109702 return UA_STATUSCODE_BADNODEIDUNKNOWN;
109703 }
109704 if (item->setting.historizingUpdateStrategy != UA_HISTORIZINGUPDATESTRATEGY_POLL)
109705 return UA_STATUSCODE_BADNODEIDINVALID;
109706 if (item->monitoredResult.monitoredItemId > 0)
109707 return UA_STATUSCODE_BADMONITOREDITEMIDINVALID;
109708 return startPoll(server, item);
109709}
109710
109711static UA_StatusCode
109712registerNodeId_gathering_default(UA_Server *server,
109713 void *context,
109714 const UA_NodeId *nodeId,
109715 const UA_HistorizingNodeIdSettings setting)
109716{
109717 UA_NodeIdStoreContext *ctx = (UA_NodeIdStoreContext*)context;
109718 if (getNodeIdStoreContextItem_gathering_default(context: ctx, nodeId)) {
109719 return UA_STATUSCODE_BADNODEIDEXISTS;
109720 }
109721 if (ctx->storeEnd >= ctx->storeSize) {
109722 size_t newStoreSize = ctx->storeSize * 2;
109723 ctx->dataStore = (UA_NodeIdStoreContextItem_gathering_default*)UA_realloc(ptr: ctx->dataStore, size: (newStoreSize * sizeof(UA_NodeIdStoreContextItem_gathering_default)));
109724 if (!ctx->dataStore) {
109725 ctx->storeSize = 0;
109726 return UA_STATUSCODE_BADOUTOFMEMORY;
109727 }
109728 memset(s: &ctx->dataStore[ctx->storeSize], c: 0, n: (newStoreSize - ctx->storeSize) * sizeof(UA_NodeIdStoreContextItem_gathering_default));
109729 ctx->storeSize = newStoreSize;
109730 }
109731 UA_NodeId_copy(src: nodeId, dst: &ctx->dataStore[ctx->storeEnd].nodeId);
109732 size_t current = ctx->storeEnd;
109733 ctx->dataStore[current].setting = setting;
109734 ++ctx->storeEnd;
109735 return UA_STATUSCODE_GOOD;
109736}
109737
109738static const UA_HistorizingNodeIdSettings*
109739getHistorizingSetting_gathering_default(UA_Server *server,
109740 void *context,
109741 const UA_NodeId *nodeId)
109742{
109743 UA_NodeIdStoreContext *ctx = (UA_NodeIdStoreContext*)context;
109744 UA_NodeIdStoreContextItem_gathering_default *item = getNodeIdStoreContextItem_gathering_default(context: ctx, nodeId);
109745 if (item) {
109746 return &item->setting;
109747 }
109748 return NULL;
109749}
109750
109751static void
109752deleteMembers_gathering_default(UA_HistoryDataGathering *gathering)
109753{
109754 if (gathering == NULL || gathering->context == NULL)
109755 return;
109756 UA_NodeIdStoreContext *ctx = (UA_NodeIdStoreContext*)gathering->context;
109757 for (size_t i = 0; i < ctx->storeEnd; ++i) {
109758 UA_NodeId_clear(p: &ctx->dataStore[i].nodeId);
109759 // There is still a monitored item present for this gathering
109760 // You need to remove it with UA_Server_deleteMonitoredItem
109761 UA_assert(ctx->dataStore[i].monitoredResult.monitoredItemId == 0);
109762 }
109763 UA_free(ptr: ctx->dataStore);
109764 UA_free(ptr: gathering->context);
109765}
109766
109767static UA_Boolean
109768updateNodeIdSetting_gathering_default(UA_Server *server,
109769 void *context,
109770 const UA_NodeId *nodeId,
109771 const UA_HistorizingNodeIdSettings setting)
109772{
109773 UA_NodeIdStoreContext *ctx = (UA_NodeIdStoreContext*)context;
109774 UA_NodeIdStoreContextItem_gathering_default *item = getNodeIdStoreContextItem_gathering_default(context: ctx, nodeId);
109775 if (!item) {
109776 return false;
109777 }
109778 stopPoll_gathering_default(server, context, nodeId);
109779 item->setting = setting;
109780 return true;
109781}
109782
109783static void
109784setValue_gathering_default(UA_Server *server,
109785 void *context,
109786 const UA_NodeId *sessionId,
109787 void *sessionContext,
109788 const UA_NodeId *nodeId,
109789 UA_Boolean historizing,
109790 const UA_DataValue *value)
109791{
109792 UA_NodeIdStoreContext *ctx = (UA_NodeIdStoreContext*)context;
109793 UA_NodeIdStoreContextItem_gathering_default *item = getNodeIdStoreContextItem_gathering_default(context: ctx, nodeId);
109794 if (!item) {
109795 return;
109796 }
109797 if (item->setting.historizingUpdateStrategy == UA_HISTORIZINGUPDATESTRATEGY_VALUESET) {
109798 item->setting.historizingBackend.serverSetHistoryData(server,
109799 item->setting.historizingBackend.context,
109800 sessionId,
109801 sessionContext,
109802 nodeId,
109803 historizing,
109804 value);
109805 }
109806}
109807
109808UA_HistoryDataGathering
109809UA_HistoryDataGathering_Default(size_t initialNodeIdStoreSize)
109810{
109811 UA_HistoryDataGathering gathering;
109812 memset(s: &gathering, c: 0, n: sizeof(UA_HistoryDataGathering));
109813 gathering.setValue = &setValue_gathering_default;
109814 gathering.getHistorizingSetting = &getHistorizingSetting_gathering_default;
109815 gathering.registerNodeId = &registerNodeId_gathering_default;
109816 gathering.startPoll = &startPoll_gathering_default;
109817 gathering.stopPoll = &stopPoll_gathering_default;
109818 gathering.deleteMembers = &deleteMembers_gathering_default;
109819 gathering.updateNodeIdSetting = &updateNodeIdSetting_gathering_default;
109820 UA_NodeIdStoreContext *context = (UA_NodeIdStoreContext*)UA_calloc(nmemb: 1, size: sizeof(UA_NodeIdStoreContext));
109821 context->storeEnd = 0;
109822 context->storeSize = initialNodeIdStoreSize;
109823 context->dataStore = (UA_NodeIdStoreContextItem_gathering_default*)UA_calloc(nmemb: initialNodeIdStoreSize, size: sizeof(UA_NodeIdStoreContextItem_gathering_default));
109824 gathering.context = context;
109825 return gathering;
109826}
109827
109828/* Circular buffer implementation */
109829
109830static UA_StatusCode
109831registerNodeId_gathering_circular(UA_Server *server, void *context,
109832 const UA_NodeId *nodeId,
109833 const UA_HistorizingNodeIdSettings setting) {
109834 UA_NodeIdStoreContext *ctx = (UA_NodeIdStoreContext *)context;
109835 if(getNodeIdStoreContextItem_gathering_default(context: ctx, nodeId)) {
109836 return UA_STATUSCODE_BADNODEIDEXISTS;
109837 }
109838 if(ctx->storeEnd >= ctx->storeSize || !ctx->dataStore) {
109839 return UA_STATUSCODE_BADOUTOFMEMORY;
109840 }
109841 UA_NodeId_copy(src: nodeId, dst: &ctx->dataStore[ctx->storeEnd].nodeId);
109842 size_t current = ctx->storeEnd;
109843 ctx->dataStore[current].setting = setting;
109844 ++ctx->storeEnd;
109845 return UA_STATUSCODE_GOOD;
109846}
109847
109848UA_HistoryDataGathering
109849UA_HistoryDataGathering_Circular(size_t initialNodeIdStoreSize) {
109850 UA_HistoryDataGathering gathering = UA_HistoryDataGathering_Default(initialNodeIdStoreSize);
109851 gathering.registerNodeId = &registerNodeId_gathering_circular;
109852 return gathering;
109853}
109854
109855/**** amalgamated original file "/plugins/historydata/ua_history_database_default.c" ****/
109856
109857/* This Source Code Form is subject to the terms of the Mozilla Public
109858 * License, v. 2.0. If a copy of the MPL was not distributed with this
109859 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
109860 *
109861 * Copyright 2018 (c) basysKom GmbH <opensource@basyskom.com> (Author: Peter Rustler)
109862 */
109863
109864
109865#include <limits.h>
109866
109867typedef struct {
109868 UA_HistoryDataGathering gathering;
109869} UA_HistoryDatabaseContext_default;
109870
109871static size_t
109872getResultSize_service_default(const UA_HistoryDataBackend* backend,
109873 UA_Server *server,
109874 const UA_NodeId *sessionId,
109875 void* sessionContext,
109876 const UA_NodeId *nodeId,
109877 UA_DateTime start,
109878 UA_DateTime end,
109879 UA_UInt32 numValuesPerNode,
109880 UA_Boolean returnBounds,
109881 size_t *startIndex,
109882 size_t *endIndex,
109883 UA_Boolean *addFirst,
109884 UA_Boolean *addLast,
109885 UA_Boolean *reverse)
109886{
109887 size_t storeEnd = backend->getEnd(server, backend->context, sessionId, sessionContext, nodeId);
109888 size_t firstIndex = backend->firstIndex(server, backend->context, sessionId, sessionContext, nodeId);
109889 size_t lastIndex = backend->lastIndex(server, backend->context, sessionId, sessionContext, nodeId);
109890 *startIndex = storeEnd;
109891 *endIndex = storeEnd;
109892 *addFirst = false;
109893 *addLast = false;
109894 if (end == LLONG_MIN) {
109895 *reverse = false;
109896 } else if (start == LLONG_MIN) {
109897 *reverse = true;
109898 } else {
109899 *reverse = end < start;
109900 }
109901 UA_Boolean equal = start == end;
109902 size_t size = 0;
109903 if (lastIndex != storeEnd) {
109904 if (equal) {
109905 if (returnBounds) {
109906 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, start, MATCH_EQUAL_OR_BEFORE);
109907 if (*startIndex == storeEnd) {
109908 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, start, MATCH_AFTER);
109909 *addFirst = true;
109910 }
109911 *endIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, start, MATCH_AFTER);
109912 size = backend->resultSize(server, backend->context, sessionId, sessionContext, nodeId, *startIndex, *endIndex);
109913 } else {
109914 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, start, MATCH_EQUAL);
109915 *endIndex = *startIndex;
109916 if (*startIndex == storeEnd)
109917 size = 0;
109918 else
109919 size = 1;
109920 }
109921 } else if (start == LLONG_MIN) {
109922 *endIndex = firstIndex;
109923 if (returnBounds) {
109924 *addLast = true;
109925 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, end, MATCH_EQUAL_OR_AFTER);
109926 if (*startIndex == storeEnd) {
109927 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, end, MATCH_EQUAL_OR_BEFORE);
109928 *addFirst = true;
109929 }
109930 } else {
109931 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, end, MATCH_EQUAL_OR_BEFORE);
109932 }
109933 size = backend->resultSize(server, backend->context, sessionId, sessionContext, nodeId, *endIndex, *startIndex);
109934 } else if (end == LLONG_MIN) {
109935 *endIndex = lastIndex;
109936 if (returnBounds) {
109937 *addLast = true;
109938 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, start, MATCH_EQUAL_OR_BEFORE);
109939 if (*startIndex == storeEnd) {
109940 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, start, MATCH_AFTER);
109941 *addFirst = true;
109942 }
109943 } else {
109944 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, start, MATCH_EQUAL_OR_AFTER);
109945 }
109946 size = backend->resultSize(server, backend->context, sessionId, sessionContext, nodeId, *startIndex, *endIndex);
109947 } else if (*reverse) {
109948 if (returnBounds) {
109949 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, start, MATCH_EQUAL_OR_AFTER);
109950 if (*startIndex == storeEnd) {
109951 *addFirst = true;
109952 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, start, MATCH_BEFORE);
109953 }
109954 *endIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, end, MATCH_EQUAL_OR_BEFORE);
109955 if (*endIndex == storeEnd) {
109956 *addLast = true;
109957 *endIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, end, MATCH_AFTER);
109958 }
109959 } else {
109960 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, start, MATCH_EQUAL_OR_BEFORE);
109961 *endIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, end, MATCH_AFTER);
109962 }
109963 size = backend->resultSize(server, backend->context, sessionId, sessionContext, nodeId, *endIndex, *startIndex);
109964 } else {
109965 if (returnBounds) {
109966 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, start, MATCH_EQUAL_OR_BEFORE);
109967 if (*startIndex == storeEnd) {
109968 *addFirst = true;
109969 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, start, MATCH_AFTER);
109970 }
109971 *endIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, end, MATCH_EQUAL_OR_AFTER);
109972 if (*endIndex == storeEnd) {
109973 *addLast = true;
109974 *endIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, end, MATCH_BEFORE);
109975 }
109976 } else {
109977 *startIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, start, MATCH_EQUAL_OR_AFTER);
109978 *endIndex = backend->getDateTimeMatch(server, backend->context, sessionId, sessionContext, nodeId, end, MATCH_BEFORE);
109979 }
109980 size = backend->resultSize(server, backend->context, sessionId, sessionContext, nodeId, *startIndex, *endIndex);
109981 }
109982 } else if (returnBounds) {
109983 *addLast = true;
109984 *addFirst = true;
109985 }
109986
109987 if (*addLast)
109988 ++size;
109989 if (*addFirst)
109990 ++size;
109991
109992 if (numValuesPerNode > 0 && size > numValuesPerNode) {
109993 size = numValuesPerNode;
109994 *addLast = false;
109995 }
109996 return size;
109997}
109998
109999static UA_StatusCode
110000getHistoryData_service_default(const UA_HistoryDataBackend* backend,
110001 const UA_DateTime start,
110002 const UA_DateTime end,
110003 UA_Server *server,
110004 const UA_NodeId *sessionId,
110005 void *sessionContext,
110006 const UA_NodeId* nodeId,
110007 size_t maxSize,
110008 UA_UInt32 numValuesPerNode,
110009 UA_Boolean returnBounds,
110010 UA_TimestampsToReturn timestampsToReturn,
110011 UA_NumericRange range,
110012 UA_Boolean releaseContinuationPoints,
110013 const UA_ByteString *continuationPoint,
110014 UA_ByteString *outContinuationPoint,
110015 size_t *resultSize,
110016 UA_DataValue ** result)
110017{
110018 size_t skip = 0;
110019 UA_ByteString backendContinuationPoint;
110020 UA_ByteString_init(p: &backendContinuationPoint);
110021 if (continuationPoint->length > 0) {
110022 if (continuationPoint->length >= sizeof(size_t)) {
110023 skip = *((size_t*)(continuationPoint->data));
110024 if (continuationPoint->length > 0) {
110025 backendContinuationPoint.length = continuationPoint->length - sizeof(size_t);
110026 backendContinuationPoint.data = continuationPoint->data + sizeof(size_t);
110027 }
110028 } else {
110029 return UA_STATUSCODE_BADCONTINUATIONPOINTINVALID;
110030 }
110031 }
110032
110033 size_t storeEnd = backend->getEnd(server, backend->context, sessionId, sessionContext, nodeId);
110034 size_t startIndex;
110035 size_t endIndex;
110036 UA_Boolean addFirst;
110037 UA_Boolean addLast;
110038 UA_Boolean reverse;
110039 size_t _resultSize = getResultSize_service_default(backend,
110040 server,
110041 sessionId,
110042 sessionContext,
110043 nodeId,
110044 start,
110045 end,
110046 numValuesPerNode: numValuesPerNode == 0 ? 0 : numValuesPerNode + (UA_UInt32)skip,
110047 returnBounds,
110048 startIndex: &startIndex,
110049 endIndex: &endIndex,
110050 addFirst: &addFirst,
110051 addLast: &addLast,
110052 reverse: &reverse);
110053 *resultSize = _resultSize - skip;
110054 if (*resultSize > maxSize) {
110055 *resultSize = maxSize;
110056 }
110057 UA_DataValue *outResult= (UA_DataValue*)UA_Array_new(size: *resultSize, type: &UA_TYPES[UA_TYPES_DATAVALUE]);
110058 if (!outResult) {
110059 *resultSize = 0;
110060 return UA_STATUSCODE_BADOUTOFMEMORY;
110061 }
110062 *result = outResult;
110063
110064 size_t counter = 0;
110065 if (addFirst) {
110066 if (skip == 0) {
110067 outResult[counter].hasStatus = true;
110068 outResult[counter].status = UA_STATUSCODE_BADBOUNDNOTFOUND;
110069 outResult[counter].hasSourceTimestamp = true;
110070 if (start == LLONG_MIN) {
110071 outResult[counter].sourceTimestamp = end;
110072 } else {
110073 outResult[counter].sourceTimestamp = start;
110074 }
110075 ++counter;
110076 }
110077 }
110078 UA_ByteString backendOutContinuationPoint;
110079 UA_ByteString_init(p: &backendOutContinuationPoint);
110080 if (endIndex != storeEnd && startIndex != storeEnd) {
110081 size_t retval = 0;
110082
110083 size_t valueSize = *resultSize - counter;
110084 if (valueSize + skip > _resultSize - addFirst - addLast) {
110085 if (skip == 0) {
110086 valueSize = _resultSize - addFirst - addLast;
110087 } else {
110088 valueSize = _resultSize - skip - addLast;
110089 }
110090
110091 }
110092
110093 UA_StatusCode ret = UA_STATUSCODE_GOOD;
110094 if (valueSize > 0)
110095 ret = backend->copyDataValues(server,
110096 backend->context,
110097 sessionId,
110098 sessionContext,
110099 nodeId,
110100 startIndex,
110101 endIndex,
110102 reverse,
110103 valueSize,
110104 range,
110105 releaseContinuationPoints,
110106 &backendContinuationPoint,
110107 &backendOutContinuationPoint,
110108 &retval,
110109 &outResult[counter]);
110110 if (ret != UA_STATUSCODE_GOOD) {
110111 UA_Array_delete(p: outResult, size: *resultSize, type: &UA_TYPES[UA_TYPES_DATAVALUE]);
110112 *result = NULL;
110113 *resultSize = 0;
110114 return ret;
110115 }
110116 counter += retval;
110117 }
110118 if (addLast && counter < *resultSize) {
110119 outResult[counter].hasStatus = true;
110120 outResult[counter].status = UA_STATUSCODE_BADBOUNDNOTFOUND;
110121 outResult[counter].hasSourceTimestamp = true;
110122 if (start == LLONG_MIN && storeEnd != backend->firstIndex(server, backend->context, sessionId, sessionContext, nodeId)) {
110123 outResult[counter].sourceTimestamp = backend->getDataValue(server, backend->context, sessionId, sessionContext, nodeId, endIndex)->sourceTimestamp - UA_DATETIME_SEC;
110124 } else if (end == LLONG_MIN && storeEnd != backend->firstIndex(server, backend->context, sessionId, sessionContext, nodeId)) {
110125 outResult[counter].sourceTimestamp = backend->getDataValue(server, backend->context, sessionId, sessionContext, nodeId, endIndex)->sourceTimestamp + UA_DATETIME_SEC;
110126 } else {
110127 outResult[counter].sourceTimestamp = end;
110128 }
110129 }
110130 // there are more values
110131 if (skip + *resultSize < _resultSize
110132 // there are not more values for this request, but there are more values in database
110133 || (backendOutContinuationPoint.length > 0
110134 && numValuesPerNode != 0)
110135 // we deliver just one value which is a FIRST/LAST value
110136 || (skip == 0
110137 && addFirst == true
110138 && *resultSize == 1)) {
110139 if(UA_ByteString_allocBuffer(bs: outContinuationPoint, length: backendOutContinuationPoint.length + sizeof(size_t))
110140 != UA_STATUSCODE_GOOD) {
110141 return UA_STATUSCODE_BADOUTOFMEMORY;
110142 }
110143 *((size_t*)(outContinuationPoint->data)) = skip + *resultSize;
110144 if(backendOutContinuationPoint.length > 0)
110145 memcpy(dest: outContinuationPoint->data + sizeof(size_t), src: backendOutContinuationPoint.data, n: backendOutContinuationPoint.length);
110146 }
110147 UA_ByteString_clear(p: &backendOutContinuationPoint);
110148 return UA_STATUSCODE_GOOD;
110149}
110150
110151static void
110152updateData_service_default(UA_Server *server,
110153 void *hdbContext,
110154 const UA_NodeId *sessionId,
110155 void *sessionContext,
110156 const UA_RequestHeader *requestHeader,
110157 const UA_UpdateDataDetails *details,
110158 UA_HistoryUpdateResult *result)
110159{
110160 UA_HistoryDatabaseContext_default *ctx = (UA_HistoryDatabaseContext_default*)hdbContext;
110161 UA_Byte accessLevel = 0;
110162 UA_Server_readAccessLevel(server,
110163 nodeId: details->nodeId,
110164 outAccessLevel: &accessLevel);
110165 if (!(accessLevel & UA_ACCESSLEVELMASK_HISTORYWRITE)) {
110166 result->statusCode = UA_STATUSCODE_BADUSERACCESSDENIED;
110167 return;
110168 }
110169
110170 UA_Boolean historizing = false;
110171 UA_Server_readHistorizing(server,
110172 nodeId: details->nodeId,
110173 outHistorizing: &historizing);
110174 if (!historizing) {
110175 result->statusCode = UA_STATUSCODE_BADHISTORYOPERATIONINVALID;
110176 return;
110177 }
110178 const UA_HistorizingNodeIdSettings *setting = ctx->gathering.getHistorizingSetting(
110179 server,
110180 ctx->gathering.context,
110181 &details->nodeId);
110182
110183 if (!setting) {
110184 result->statusCode = UA_STATUSCODE_BADHISTORYOPERATIONINVALID;
110185 return;
110186 }
110187
110188 UA_ServerConfig *config = UA_Server_getConfig(server);
110189 result->operationResultsSize = details->updateValuesSize;
110190 result->operationResults = (UA_StatusCode*)UA_Array_new(size: result->operationResultsSize, type: &UA_TYPES[UA_TYPES_STATUSCODE]);
110191 for (size_t i = 0; i < details->updateValuesSize; ++i) {
110192 if (config->accessControl.allowHistoryUpdateUpdateData &&
110193 !config->accessControl.allowHistoryUpdateUpdateData(server, &config->accessControl, sessionId, sessionContext,
110194 &details->nodeId, details->performInsertReplace,
110195 &details->updateValues[i])) {
110196 result->operationResults[i] = UA_STATUSCODE_BADUSERACCESSDENIED;
110197 continue;
110198 }
110199 switch (details->performInsertReplace) {
110200 case UA_PERFORMUPDATETYPE_INSERT:
110201 if (!setting->historizingBackend.insertDataValue) {
110202 result->operationResults[i] = UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED;
110203 continue;
110204 }
110205 result->operationResults[i]
110206 = setting->historizingBackend.insertDataValue(server,
110207 setting->historizingBackend.context,
110208 sessionId,
110209 sessionContext,
110210 &details->nodeId,
110211 &details->updateValues[i]);
110212 continue;
110213 case UA_PERFORMUPDATETYPE_REPLACE:
110214 if (!setting->historizingBackend.replaceDataValue) {
110215 result->operationResults[i] = UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED;
110216 continue;
110217 }
110218 result->operationResults[i]
110219 = setting->historizingBackend.replaceDataValue(server,
110220 setting->historizingBackend.context,
110221 sessionId,
110222 sessionContext,
110223 &details->nodeId,
110224 &details->updateValues[i]);
110225 continue;
110226 case UA_PERFORMUPDATETYPE_UPDATE:
110227 if (!setting->historizingBackend.updateDataValue) {
110228 result->operationResults[i] = UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED;
110229 continue;
110230 }
110231 result->operationResults[i]
110232 = setting->historizingBackend.updateDataValue(server,
110233 setting->historizingBackend.context,
110234 sessionId,
110235 sessionContext,
110236 &details->nodeId,
110237 &details->updateValues[i]);
110238 continue;
110239 default:
110240 result->operationResults[i] = UA_STATUSCODE_BADHISTORYOPERATIONINVALID;
110241 continue;
110242 }
110243 }
110244}
110245
110246
110247static void
110248deleteRawModified_service_default(UA_Server *server,
110249 void *hdbContext,
110250 const UA_NodeId *sessionId,
110251 void *sessionContext,
110252 const UA_RequestHeader *requestHeader,
110253 const UA_DeleteRawModifiedDetails *details,
110254 UA_HistoryUpdateResult *result)
110255{
110256 if (details->isDeleteModified) {
110257 result->statusCode = UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED;
110258 return;
110259 }
110260 UA_HistoryDatabaseContext_default *ctx = (UA_HistoryDatabaseContext_default*)hdbContext;
110261 UA_Byte accessLevel = 0;
110262 UA_Server_readAccessLevel(server,
110263 nodeId: details->nodeId,
110264 outAccessLevel: &accessLevel);
110265 if (!(accessLevel & UA_ACCESSLEVELMASK_HISTORYWRITE)) {
110266 result->statusCode = UA_STATUSCODE_BADUSERACCESSDENIED;
110267 return;
110268 }
110269
110270 UA_Boolean historizing = false;
110271 UA_Server_readHistorizing(server,
110272 nodeId: details->nodeId,
110273 outHistorizing: &historizing);
110274 if (!historizing) {
110275 result->statusCode = UA_STATUSCODE_BADHISTORYOPERATIONINVALID;
110276 return;
110277 }
110278 const UA_HistorizingNodeIdSettings *setting = ctx->gathering.getHistorizingSetting(
110279 server,
110280 ctx->gathering.context,
110281 &details->nodeId);
110282
110283 if (!setting) {
110284 result->statusCode = UA_STATUSCODE_BADHISTORYOPERATIONINVALID;
110285 return;
110286 }
110287 if (!setting->historizingBackend.removeDataValue) {
110288 result->statusCode = UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED;
110289 return;
110290 }
110291
110292 UA_ServerConfig *config = UA_Server_getConfig(server);
110293 if (config->accessControl.allowHistoryUpdateDeleteRawModified &&
110294 !config->accessControl.allowHistoryUpdateDeleteRawModified(server,
110295 &config->accessControl, sessionId, sessionContext, &details->nodeId,
110296 details->startTime, details->endTime, details->isDeleteModified)) {
110297 result->statusCode = UA_STATUSCODE_BADUSERACCESSDENIED;
110298 return;
110299 }
110300
110301 result->statusCode
110302 = setting->historizingBackend.removeDataValue(server,
110303 setting->historizingBackend.context,
110304 sessionId,
110305 sessionContext,
110306 &details->nodeId,
110307 details->startTime,
110308 details->endTime);
110309}
110310
110311static void
110312readRaw_service_default(UA_Server *server,
110313 void *context,
110314 const UA_NodeId *sessionId,
110315 void *sessionContext,
110316 const UA_RequestHeader *requestHeader,
110317 const UA_ReadRawModifiedDetails *historyReadDetails,
110318 UA_TimestampsToReturn timestampsToReturn,
110319 UA_Boolean releaseContinuationPoints,
110320 size_t nodesToReadSize,
110321 const UA_HistoryReadValueId *nodesToRead,
110322 UA_HistoryReadResponse *response,
110323 UA_HistoryData * const * const historyData)
110324{
110325 UA_HistoryDatabaseContext_default *ctx = (UA_HistoryDatabaseContext_default*)context;
110326 for (size_t i = 0; i < nodesToReadSize; ++i) {
110327 UA_Byte accessLevel = 0;
110328 UA_Server_readAccessLevel(server,
110329 nodeId: nodesToRead[i].nodeId,
110330 outAccessLevel: &accessLevel);
110331 if (!(accessLevel & UA_ACCESSLEVELMASK_HISTORYREAD)) {
110332 response->results[i].statusCode = UA_STATUSCODE_BADUSERACCESSDENIED;
110333 continue;
110334 }
110335
110336 UA_Boolean historizing = false;
110337 UA_Server_readHistorizing(server,
110338 nodeId: nodesToRead[i].nodeId,
110339 outHistorizing: &historizing);
110340 if (!historizing) {
110341 response->results[i].statusCode = UA_STATUSCODE_BADHISTORYOPERATIONINVALID;
110342 continue;
110343 }
110344
110345 const UA_HistorizingNodeIdSettings *setting = ctx->gathering.getHistorizingSetting(
110346 server,
110347 ctx->gathering.context,
110348 &nodesToRead[i].nodeId);
110349
110350 if (!setting) {
110351 response->results[i].statusCode = UA_STATUSCODE_BADHISTORYOPERATIONINVALID;
110352 continue;
110353 }
110354
110355 if (historyReadDetails->returnBounds && !setting->historizingBackend.boundSupported(
110356 server,
110357 setting->historizingBackend.context,
110358 sessionId,
110359 sessionContext,
110360 &nodesToRead[i].nodeId)) {
110361 response->results[i].statusCode = UA_STATUSCODE_BADBOUNDNOTSUPPORTED;
110362 continue;
110363 }
110364
110365 if (!setting->historizingBackend.timestampsToReturnSupported(
110366 server,
110367 setting->historizingBackend.context,
110368 sessionId,
110369 sessionContext,
110370 &nodesToRead[i].nodeId,
110371 timestampsToReturn)) {
110372 response->results[i].statusCode = UA_STATUSCODE_BADTIMESTAMPNOTSUPPORTED;
110373 continue;
110374 }
110375
110376 UA_NumericRange range;
110377 range.dimensionsSize = 0;
110378 range.dimensions = NULL;
110379 if (nodesToRead[i].indexRange.length > 0) {
110380 UA_StatusCode rangeParseResult = UA_NumericRange_parse(range: &range, str: nodesToRead[i].indexRange);
110381 if (rangeParseResult != UA_STATUSCODE_GOOD) {
110382 response->results[i].statusCode = rangeParseResult;
110383 continue;
110384 }
110385 }
110386
110387 UA_StatusCode getHistoryDataStatusCode;
110388 if (setting->historizingBackend.getHistoryData) {
110389 getHistoryDataStatusCode = setting->historizingBackend.getHistoryData(
110390 server,
110391 sessionId,
110392 sessionContext,
110393 &setting->historizingBackend,
110394 historyReadDetails->startTime,
110395 historyReadDetails->endTime,
110396 &nodesToRead[i].nodeId,
110397 setting->maxHistoryDataResponseSize,
110398 historyReadDetails->numValuesPerNode,
110399 historyReadDetails->returnBounds,
110400 timestampsToReturn,
110401 range,
110402 releaseContinuationPoints,
110403 &nodesToRead[i].continuationPoint,
110404 &response->results[i].continuationPoint,
110405 historyData[i]);
110406 } else {
110407 getHistoryDataStatusCode = getHistoryData_service_default(
110408 backend: &setting->historizingBackend,
110409 start: historyReadDetails->startTime,
110410 end: historyReadDetails->endTime,
110411 server,
110412 sessionId,
110413 sessionContext,
110414 nodeId: &nodesToRead[i].nodeId,
110415 maxSize: setting->maxHistoryDataResponseSize,
110416 numValuesPerNode: historyReadDetails->numValuesPerNode,
110417 returnBounds: historyReadDetails->returnBounds,
110418 timestampsToReturn,
110419 range,
110420 releaseContinuationPoints,
110421 continuationPoint: &nodesToRead[i].continuationPoint,
110422 outContinuationPoint: &response->results[i].continuationPoint,
110423 resultSize: &historyData[i]->dataValuesSize,
110424 result: &historyData[i]->dataValues);
110425 }
110426 if (getHistoryDataStatusCode != UA_STATUSCODE_GOOD) {
110427 response->results[i].statusCode = getHistoryDataStatusCode;
110428 continue;
110429 }
110430 }
110431 response->responseHeader.serviceResult = UA_STATUSCODE_GOOD;
110432 return;
110433}
110434
110435static void
110436setValue_service_default(UA_Server *server,
110437 void *context,
110438 const UA_NodeId *sessionId,
110439 void *sessionContext,
110440 const UA_NodeId *nodeId,
110441 UA_Boolean historizing,
110442 const UA_DataValue *value)
110443{
110444 UA_HistoryDatabaseContext_default *ctx = (UA_HistoryDatabaseContext_default*)context;
110445 if (ctx->gathering.setValue)
110446 ctx->gathering.setValue(server,
110447 ctx->gathering.context,
110448 sessionId,
110449 sessionContext,
110450 nodeId,
110451 historizing,
110452 value);
110453}
110454
110455static void
110456clear_service_default(UA_HistoryDatabase *hdb)
110457{
110458 if (hdb == NULL || hdb->context == NULL)
110459 return;
110460 UA_HistoryDatabaseContext_default *ctx = (UA_HistoryDatabaseContext_default*)hdb->context;
110461 ctx->gathering.deleteMembers(&ctx->gathering);
110462 UA_free(ptr: ctx);
110463}
110464
110465UA_HistoryDatabase
110466UA_HistoryDatabase_default(UA_HistoryDataGathering gathering)
110467{
110468 UA_HistoryDatabase hdb;
110469 memset(s: &hdb, c: 0, n: sizeof(UA_HistoryDatabase));
110470 UA_HistoryDatabaseContext_default *context =
110471 (UA_HistoryDatabaseContext_default*)
110472 UA_calloc(nmemb: 1, size: sizeof(UA_HistoryDatabaseContext_default));
110473 context->gathering = gathering;
110474 hdb.context = context;
110475 hdb.readRaw = &readRaw_service_default;
110476 hdb.setValue = &setValue_service_default;
110477 hdb.updateData = &updateData_service_default;
110478 hdb.deleteRawModified = &deleteRawModified_service_default;
110479 hdb.clear = clear_service_default;
110480 return hdb;
110481}
110482
110483/**** amalgamated original file "/plugins/ua_log_syslog.c" ****/
110484
110485/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
110486 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
110487 *
110488 * Copyright 2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
110489 */
110490
110491
110492#if defined(__linux__) || defined(__unix__)
110493
110494#include <syslog.h>
110495#include <stdio.h>
110496
110497const char *syslogLevelNames[6] = {"trace", "debug", "info",
110498 "warn", "error", "fatal"};
110499const char *syslogCategoryNames[UA_LOGCATEGORIES] =
110500 {"network", "channel", "session", "server", "client",
110501 "userland", "securitypolicy", "eventloop", "pubsub", "discovery"};
110502
110503#ifdef __clang__
110504__attribute__((__format__(__printf__, 4 , 0)))
110505#endif
110506static void
110507UA_Log_Syslog_log(void *context, UA_LogLevel level, UA_LogCategory category,
110508 const char *msg, va_list args) {
110509 /* Assume that context is casted to UA_LogLevel */
110510 if(context != NULL && (UA_LogLevel)(uintptr_t)context > level)
110511 return;
110512
110513 int priority = LOG_INFO;
110514 switch(level) {
110515 case UA_LOGLEVEL_DEBUG:
110516 priority = LOG_DEBUG;
110517 break;
110518 case UA_LOGLEVEL_INFO:
110519 priority = LOG_INFO;
110520 break;
110521 case UA_LOGLEVEL_WARNING:
110522 priority = LOG_WARNING;
110523 break;
110524 case UA_LOGLEVEL_ERROR:
110525 priority = LOG_ERR;
110526 break;
110527 case UA_LOGLEVEL_FATAL:
110528 priority = LOG_CRIT;
110529 break;
110530 case UA_LOGLEVEL_TRACE:
110531 default:
110532 return;
110533 }
110534
110535 int logLevelSlot = ((int)level / 100) - 1;
110536 if(logLevelSlot < 0 || logLevelSlot > 5)
110537 logLevelSlot = 5; /* Set to fatal if the level is outside the range */
110538
110539#define LOGBUFSIZE 512
110540 char logbuf[LOGBUFSIZE];
110541 int pos = snprintf(s: logbuf, LOGBUFSIZE, format: "[%s/%s] ",
110542 syslogLevelNames[logLevelSlot],
110543 syslogCategoryNames[category]);
110544 if(pos < 0) {
110545 syslog(LOG_WARNING, fmt: "Log message too long for syslog");
110546 return;
110547 }
110548 pos = vsnprintf(s: &logbuf[pos], LOGBUFSIZE - (size_t)pos, format: msg, arg: args);
110549 if(pos < 0) {
110550 syslog(LOG_WARNING, fmt: "Log message too long for syslog");
110551 return;
110552 }
110553
110554 syslog(pri: priority, fmt: "%s", logbuf);
110555}
110556
110557static void
110558UA_Log_Syslog_clear(UA_Logger *logger) {
110559 /* closelog is optional. We don't use it as several loggers might be
110560 * instantiated in parallel. */
110561 /* closelog(); */
110562 UA_free(ptr: logger);
110563}
110564
110565UA_Logger
110566UA_Log_Syslog(void) {
110567 return UA_Log_Syslog_withLevel(minlevel: UA_LOGLEVEL_TRACE);
110568}
110569
110570UA_Logger
110571UA_Log_Syslog_withLevel(UA_LogLevel minlevel) {
110572 UA_Logger logger = {UA_Log_Syslog_log, (void*)(uintptr_t)minlevel, NULL};
110573 return logger;
110574}
110575
110576UA_Logger *
110577UA_Log_Syslog_new(UA_LogLevel minlevel) {
110578 UA_Logger *logger = (UA_Logger*)UA_malloc(size: sizeof(UA_Logger));
110579 if(!logger)
110580 return NULL;
110581 *logger = UA_Log_Syslog_withLevel(minlevel);
110582 logger->clear = UA_Log_Syslog_clear;
110583 return logger;
110584}
110585
110586#endif
110587
110588/**** amalgamated original file "/plugins/crypto/mbedtls/ua_securitypolicy_basic128rsa15.c" ****/
110589
110590/* This Source Code Form is subject to the terms of the Mozilla Public
110591 * License, v. 2.0. If a copy of the MPL was not distributed with this
110592 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
110593 *
110594 * Copyright 2018-2019 (c) Mark Giraud, Fraunhofer IOSB
110595 * Copyright 2019 (c) Kalycito Infotech Private Limited
110596 * Copyright 2018 (c) HMS Industrial Networks AB (Author: Jonas Green)
110597 * Copyright 2020 (c) Wind River Systems, Inc.
110598 * Copyright 2020 (c) basysKom GmbH
110599 *
110600 */
110601
110602
110603#ifdef UA_ENABLE_ENCRYPTION_MBEDTLS
110604
110605
110606#include <mbedtls/aes.h>
110607#include <mbedtls/ctr_drbg.h>
110608#include <mbedtls/entropy.h>
110609#include <mbedtls/error.h>
110610#include <mbedtls/md.h>
110611#include <mbedtls/sha1.h>
110612#include <mbedtls/version.h>
110613#include <mbedtls/x509_crt.h>
110614
110615/* Notes:
110616 * mbedTLS' AES allows in-place encryption and decryption. Sow we don't have to
110617 * allocate temp buffers.
110618 * https://tls.mbed.org/discussions/generic/in-place-decryption-with-aes256-same-input-output-buffer
110619 */
110620
110621#define UA_SECURITYPOLICY_BASIC128RSA15_RSAPADDING_LEN 11
110622#define UA_SECURITYPOLICY_BASIC128RSA15_SYM_KEY_LENGTH 16
110623#define UA_BASIC128RSA15_SYM_SIGNING_KEY_LENGTH 16
110624#define UA_SECURITYPOLICY_BASIC128RSA15_SYM_ENCRYPTION_BLOCK_SIZE 16
110625#define UA_SECURITYPOLICY_BASIC128RSA15_SYM_PLAIN_TEXT_BLOCK_SIZE 16
110626#define UA_SECURITYPOLICY_BASIC128RSA15_MINASYMKEYLENGTH 128
110627#define UA_SECURITYPOLICY_BASIC128RSA15_MAXASYMKEYLENGTH 512
110628
110629typedef struct {
110630 UA_ByteString localCertThumbprint;
110631
110632 mbedtls_ctr_drbg_context drbgContext;
110633 mbedtls_entropy_context entropyContext;
110634 mbedtls_md_context_t sha1MdContext;
110635 mbedtls_pk_context localPrivateKey;
110636} Basic128Rsa15_PolicyContext;
110637
110638typedef struct {
110639 Basic128Rsa15_PolicyContext *policyContext;
110640
110641 UA_ByteString localSymSigningKey;
110642 UA_ByteString localSymEncryptingKey;
110643 UA_ByteString localSymIv;
110644
110645 UA_ByteString remoteSymSigningKey;
110646 UA_ByteString remoteSymEncryptingKey;
110647 UA_ByteString remoteSymIv;
110648
110649 mbedtls_x509_crt remoteCertificate;
110650} Basic128Rsa15_ChannelContext;
110651
110652/********************/
110653/* AsymmetricModule */
110654/********************/
110655
110656static UA_StatusCode
110657asym_verify_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc,
110658 const UA_ByteString *message,
110659 const UA_ByteString *signature) {
110660 if(message == NULL || signature == NULL || cc == NULL)
110661 return UA_STATUSCODE_BADINTERNALERROR;
110662
110663 return mbedtls_verifySig_sha1(&cc->remoteCertificate, message, signature);
110664}
110665
110666static UA_StatusCode
110667asym_sign_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc,
110668 const UA_ByteString *message,
110669 UA_ByteString *signature) {
110670 if(message == NULL || signature == NULL || cc == NULL)
110671 return UA_STATUSCODE_BADINTERNALERROR;
110672
110673 Basic128Rsa15_PolicyContext *pc = cc->policyContext;
110674 return mbedtls_sign_sha1(&pc->localPrivateKey, &pc->drbgContext,
110675 message, signature);
110676}
110677
110678static size_t
110679asym_getLocalSignatureSize_sp_basic128rsa15(const Basic128Rsa15_ChannelContext *cc) {
110680 if(cc == NULL)
110681 return 0;
110682#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
110683 return mbedtls_pk_rsa(cc->policyContext->localPrivateKey)->len;
110684#else
110685 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->policyContext->localPrivateKey));
110686#endif
110687}
110688
110689static size_t
110690asym_getRemoteSignatureSize_sp_basic128rsa15(const Basic128Rsa15_ChannelContext *cc) {
110691 if(cc == NULL)
110692 return 0;
110693#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
110694 return mbedtls_pk_rsa(cc->remoteCertificate.pk)->len;
110695#else
110696 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
110697#endif
110698}
110699
110700static UA_StatusCode
110701asym_encrypt_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc,
110702 UA_ByteString *data) {
110703 if(cc == NULL || data == NULL)
110704 return UA_STATUSCODE_BADINTERNALERROR;
110705
110706 mbedtls_rsa_context *remoteRsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
110707 mbedtls_rsa_set_padding(remoteRsaContext, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE);
110708
110709#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
110710 size_t keylen = remoteRsaContext->len;
110711#else
110712 size_t keylen = mbedtls_rsa_get_len(remoteRsaContext);
110713#endif
110714 size_t plainTextBlockSize =
110715 keylen - UA_SECURITYPOLICY_BASIC128RSA15_RSAPADDING_LEN;
110716 if(data->length % plainTextBlockSize != 0)
110717 return UA_STATUSCODE_BADINTERNALERROR;
110718
110719 size_t blocks = data->length / plainTextBlockSize;
110720 UA_ByteString encrypted;
110721 UA_StatusCode retval = UA_ByteString_allocBuffer(&encrypted, blocks * keylen);
110722 if(retval != UA_STATUSCODE_GOOD)
110723 return retval;
110724
110725 size_t lenDataToEncrypt = data->length;
110726 size_t inOffset = 0;
110727 size_t offset = 0;
110728 size_t outLength = 0;
110729 Basic128Rsa15_PolicyContext *pc = cc->policyContext;
110730 while(lenDataToEncrypt >= plainTextBlockSize) {
110731 int mbedErr = mbedtls_pk_encrypt(&cc->remoteCertificate.pk,
110732 data->data + inOffset, plainTextBlockSize,
110733 encrypted.data + offset, &outLength,
110734 encrypted.length - offset,
110735 mbedtls_ctr_drbg_random,
110736 &pc->drbgContext);
110737 if(mbedErr) {
110738 UA_ByteString_clear(&encrypted);
110739 return UA_STATUSCODE_BADINTERNALERROR;
110740 }
110741
110742 inOffset += plainTextBlockSize;
110743 offset += outLength;
110744 lenDataToEncrypt -= plainTextBlockSize;
110745 }
110746
110747 memcpy(data->data, encrypted.data, offset);
110748 UA_ByteString_clear(&encrypted);
110749
110750 return UA_STATUSCODE_GOOD;
110751}
110752
110753static UA_StatusCode
110754asym_decrypt_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc,
110755 UA_ByteString *data) {
110756 if(cc == NULL || data == NULL)
110757 return UA_STATUSCODE_BADINTERNALERROR;
110758
110759 Basic128Rsa15_PolicyContext *pc = cc->policyContext;
110760 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(pc->localPrivateKey);
110761 mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE);
110762#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
110763 size_t keylen = rsaContext->len;
110764#else
110765 size_t keylen = mbedtls_rsa_get_len(rsaContext);
110766#endif
110767 if(data->length % keylen != 0)
110768 return UA_STATUSCODE_BADINTERNALERROR;
110769
110770 size_t inOffset = 0;
110771 size_t outOffset = 0;
110772 size_t outLength = 0;
110773 unsigned char buf[512];
110774
110775 while(inOffset < data->length) {
110776 int mbedErr = mbedtls_pk_decrypt(&pc->localPrivateKey,
110777 data->data + inOffset, keylen,
110778 buf, &outLength, 512,
110779 mbedtls_ctr_drbg_random,
110780 &pc->drbgContext);
110781 if(mbedErr)
110782 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
110783
110784 memcpy(data->data + outOffset, buf, outLength);
110785 inOffset += keylen;
110786 outOffset += outLength;
110787 }
110788
110789 data->length = outOffset;
110790 return UA_STATUSCODE_GOOD;
110791}
110792
110793static size_t
110794asym_getLocalEncryptionKeyLength_sp_basic128rsa15(const Basic128Rsa15_ChannelContext *cc) {
110795 if(cc == NULL)
110796 return 0;
110797#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
110798 mbedtls_rsa_context *const rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
110799 return rsaContext->len;
110800#else
110801 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
110802#endif
110803}
110804
110805static size_t
110806asym_getRemoteEncryptionKeyLength_sp_basic128rsa15(const Basic128Rsa15_ChannelContext *cc) {
110807 return mbedtls_pk_get_len(&cc->remoteCertificate.pk) * 8;
110808}
110809
110810static size_t
110811asym_getRemoteBlockSize_sp_basic128rsa15(const Basic128Rsa15_ChannelContext *cc) {
110812#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
110813 mbedtls_rsa_context *const rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
110814 return rsaContext->len;
110815#else
110816 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
110817#endif
110818}
110819
110820static size_t
110821asym_getRemotePlainTextBlockSize_sp_basic128rsa15(const Basic128Rsa15_ChannelContext *cc) {
110822 if(cc == NULL)
110823 return 0;
110824#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
110825 mbedtls_rsa_context *const rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
110826 return rsaContext->len - UA_SECURITYPOLICY_BASIC128RSA15_RSAPADDING_LEN;
110827#else
110828 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk)) -
110829 UA_SECURITYPOLICY_BASIC128RSA15_RSAPADDING_LEN;
110830#endif
110831}
110832
110833static UA_StatusCode
110834asym_makeThumbprint_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
110835 const UA_ByteString *certificate,
110836 UA_ByteString *thumbprint) {
110837 if(securityPolicy == NULL || certificate == NULL || thumbprint == NULL)
110838 return UA_STATUSCODE_BADINTERNALERROR;
110839 return mbedtls_thumbprint_sha1(certificate, thumbprint);
110840}
110841
110842static UA_StatusCode
110843asymmetricModule_compareCertificateThumbprint_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
110844 const UA_ByteString *certificateThumbprint) {
110845 if(securityPolicy == NULL || certificateThumbprint == NULL)
110846 return UA_STATUSCODE_BADINTERNALERROR;
110847
110848 Basic128Rsa15_PolicyContext *pc = (Basic128Rsa15_PolicyContext *)securityPolicy->policyContext;
110849 if(!UA_ByteString_equal(certificateThumbprint, &pc->localCertThumbprint))
110850 return UA_STATUSCODE_BADCERTIFICATEINVALID;
110851
110852 return UA_STATUSCODE_GOOD;
110853}
110854
110855/*******************/
110856/* SymmetricModule */
110857/*******************/
110858
110859static UA_StatusCode
110860sym_verify_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc,
110861 const UA_ByteString *message,
110862 const UA_ByteString *signature) {
110863 if(cc == NULL || message == NULL || signature == NULL)
110864 return UA_STATUSCODE_BADINTERNALERROR;
110865
110866 /* Compute MAC */
110867 if(signature->length != UA_SHA1_LENGTH)
110868 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
110869
110870 Basic128Rsa15_PolicyContext *pc = cc->policyContext;
110871
110872 unsigned char mac[UA_SHA1_LENGTH];
110873 mbedtls_hmac(&pc->sha1MdContext, &cc->remoteSymSigningKey, message, mac);
110874
110875 /* Compare with Signature */
110876 if(!UA_constantTimeEqual(signature->data, mac, UA_SHA1_LENGTH))
110877 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
110878 return UA_STATUSCODE_GOOD;
110879}
110880
110881static UA_StatusCode
110882sym_sign_sp_basic128rsa15(const Basic128Rsa15_ChannelContext *cc,
110883 const UA_ByteString *message,
110884 UA_ByteString *signature) {
110885 if(signature->length != UA_SHA1_LENGTH)
110886 return UA_STATUSCODE_BADINTERNALERROR;
110887
110888 mbedtls_hmac(&cc->policyContext->sha1MdContext, &cc->localSymSigningKey,
110889 message, signature->data);
110890 return UA_STATUSCODE_GOOD;
110891}
110892
110893static size_t
110894sym_getSignatureSize_sp_basic128rsa15(const void *channelContext) {
110895 return UA_SHA1_LENGTH;
110896}
110897
110898static size_t
110899sym_getSigningKeyLength_sp_basic128rsa15(const void *const channelContext) {
110900 return UA_BASIC128RSA15_SYM_SIGNING_KEY_LENGTH;
110901}
110902
110903static size_t
110904sym_getEncryptionKeyLength_sp_basic128rsa15(const void *channelContext) {
110905 return UA_SECURITYPOLICY_BASIC128RSA15_SYM_KEY_LENGTH;
110906}
110907
110908static size_t
110909sym_getEncryptionBlockSize_sp_basic128rsa15(const void *const channelContext) {
110910 return UA_SECURITYPOLICY_BASIC128RSA15_SYM_ENCRYPTION_BLOCK_SIZE;
110911}
110912
110913static size_t
110914sym_getPlainTextBlockSize_sp_basic128rsa15(const void *const channelContext) {
110915 return UA_SECURITYPOLICY_BASIC128RSA15_SYM_PLAIN_TEXT_BLOCK_SIZE;
110916}
110917
110918static UA_StatusCode
110919sym_encrypt_sp_basic128rsa15(const Basic128Rsa15_ChannelContext *cc,
110920 UA_ByteString *data) {
110921 if(cc == NULL || data == NULL)
110922 return UA_STATUSCODE_BADINTERNALERROR;
110923
110924 if(cc->localSymIv.length != UA_SECURITYPOLICY_BASIC128RSA15_SYM_ENCRYPTION_BLOCK_SIZE)
110925 return UA_STATUSCODE_BADINTERNALERROR;
110926
110927 size_t plainTextBlockSize = UA_SECURITYPOLICY_BASIC128RSA15_SYM_PLAIN_TEXT_BLOCK_SIZE;
110928 if(data->length % plainTextBlockSize != 0)
110929 return UA_STATUSCODE_BADINTERNALERROR;
110930
110931 /* Keylength in bits */
110932 unsigned int keylength = (unsigned int)(cc->localSymEncryptingKey.length * 8);
110933 mbedtls_aes_context aesContext;
110934 int mbedErr = mbedtls_aes_setkey_enc(&aesContext, cc->localSymEncryptingKey.data, keylength);
110935 if(mbedErr)
110936 return UA_STATUSCODE_BADINTERNALERROR;
110937
110938 UA_ByteString ivCopy;
110939 UA_StatusCode retval = UA_ByteString_copy(&cc->localSymIv, &ivCopy);
110940 if(retval != UA_STATUSCODE_GOOD)
110941 return retval;
110942
110943 mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_ENCRYPT, data->length,
110944 ivCopy.data, data->data, data->data);
110945 if(mbedErr)
110946 retval = UA_STATUSCODE_BADINTERNALERROR;
110947 UA_ByteString_clear(&ivCopy);
110948 return retval;
110949}
110950
110951static UA_StatusCode
110952sym_decrypt_sp_basic128rsa15(const Basic128Rsa15_ChannelContext *cc,
110953 UA_ByteString *data) {
110954 if(cc == NULL || data == NULL)
110955 return UA_STATUSCODE_BADINTERNALERROR;
110956
110957 size_t encryptionBlockSize = UA_SECURITYPOLICY_BASIC128RSA15_SYM_ENCRYPTION_BLOCK_SIZE;
110958 if(cc->remoteSymIv.length != encryptionBlockSize)
110959 return UA_STATUSCODE_BADINTERNALERROR;
110960
110961 if(data->length % encryptionBlockSize != 0)
110962 return UA_STATUSCODE_BADINTERNALERROR;
110963
110964 unsigned int keylength = (unsigned int)(cc->remoteSymEncryptingKey.length * 8);
110965 mbedtls_aes_context aesContext;
110966 int mbedErr = mbedtls_aes_setkey_dec(&aesContext,
110967 cc->remoteSymEncryptingKey.data, keylength);
110968 if(mbedErr)
110969 return UA_STATUSCODE_BADINTERNALERROR;
110970
110971 UA_ByteString ivCopy;
110972 UA_StatusCode retval = UA_ByteString_copy(&cc->remoteSymIv, &ivCopy);
110973 if(retval != UA_STATUSCODE_GOOD)
110974 return retval;
110975
110976 mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_DECRYPT, data->length,
110977 ivCopy.data, data->data, data->data);
110978 if(mbedErr)
110979 retval = UA_STATUSCODE_BADINTERNALERROR;
110980 UA_ByteString_clear(&ivCopy);
110981 return retval;
110982}
110983
110984static UA_StatusCode
110985sym_generateKey_sp_basic128rsa15(void *policyContext, const UA_ByteString *secret,
110986 const UA_ByteString *seed, UA_ByteString *out) {
110987 if(secret == NULL || seed == NULL || out == NULL)
110988 return UA_STATUSCODE_BADINTERNALERROR;
110989 Basic128Rsa15_PolicyContext *pc = (Basic128Rsa15_PolicyContext *)policyContext;
110990 return mbedtls_generateKey(&pc->sha1MdContext, secret, seed, out);
110991}
110992
110993static UA_StatusCode
110994sym_generateNonce_sp_basic128rsa15(void *policyContext, UA_ByteString *out) {
110995 if(out == NULL)
110996 return UA_STATUSCODE_BADINTERNALERROR;
110997 Basic128Rsa15_PolicyContext *pc = (Basic128Rsa15_PolicyContext *)policyContext;
110998 int mbedErr = mbedtls_ctr_drbg_random(&pc->drbgContext, out->data, out->length);
110999 if(mbedErr)
111000 return UA_STATUSCODE_BADUNEXPECTEDERROR;
111001 return UA_STATUSCODE_GOOD;
111002}
111003
111004/*****************/
111005/* ChannelModule */
111006/*****************/
111007
111008/* Assumes that the certificate has been verified externally */
111009static UA_StatusCode
111010parseRemoteCertificate_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc,
111011 const UA_ByteString *remoteCertificate) {
111012 if(remoteCertificate == NULL || cc == NULL)
111013 return UA_STATUSCODE_BADINTERNALERROR;
111014
111015 /* Parse the certificate */
111016 int mbedErr = mbedtls_x509_crt_parse(&cc->remoteCertificate, remoteCertificate->data,
111017 remoteCertificate->length);
111018 if(mbedErr)
111019 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
111020
111021 /* Check the key length */
111022#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
111023 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
111024 if(rsaContext->len < UA_SECURITYPOLICY_BASIC128RSA15_MINASYMKEYLENGTH ||
111025 rsaContext->len > UA_SECURITYPOLICY_BASIC128RSA15_MAXASYMKEYLENGTH)
111026 return UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED;
111027#else
111028 size_t keylen = mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
111029 if(keylen < UA_SECURITYPOLICY_BASIC128RSA15_MINASYMKEYLENGTH ||
111030 keylen > UA_SECURITYPOLICY_BASIC128RSA15_MAXASYMKEYLENGTH)
111031 return UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED;
111032#endif
111033 return UA_STATUSCODE_GOOD;
111034}
111035
111036static void
111037channelContext_deleteContext_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc) {
111038 UA_ByteString_clear(&cc->localSymSigningKey);
111039 UA_ByteString_clear(&cc->localSymEncryptingKey);
111040 UA_ByteString_clear(&cc->localSymIv);
111041 UA_ByteString_clear(&cc->remoteSymSigningKey);
111042 UA_ByteString_clear(&cc->remoteSymEncryptingKey);
111043 UA_ByteString_clear(&cc->remoteSymIv);
111044 mbedtls_x509_crt_free(&cc->remoteCertificate);
111045 UA_free(cc);
111046}
111047
111048static UA_StatusCode
111049channelContext_newContext_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy,
111050 const UA_ByteString *remoteCertificate,
111051 void **pp_contextData) {
111052 if(securityPolicy == NULL || remoteCertificate == NULL || pp_contextData == NULL)
111053 return UA_STATUSCODE_BADINTERNALERROR;
111054
111055 /* Allocate the channel context */
111056 *pp_contextData = UA_malloc(sizeof(Basic128Rsa15_ChannelContext));
111057 if(*pp_contextData == NULL)
111058 return UA_STATUSCODE_BADOUTOFMEMORY;
111059
111060 Basic128Rsa15_ChannelContext *cc = (Basic128Rsa15_ChannelContext *)*pp_contextData;
111061
111062 /* Initialize the channel context */
111063 cc->policyContext = (Basic128Rsa15_PolicyContext *)securityPolicy->policyContext;
111064
111065 UA_ByteString_init(&cc->localSymSigningKey);
111066 UA_ByteString_init(&cc->localSymEncryptingKey);
111067 UA_ByteString_init(&cc->localSymIv);
111068
111069 UA_ByteString_init(&cc->remoteSymSigningKey);
111070 UA_ByteString_init(&cc->remoteSymEncryptingKey);
111071 UA_ByteString_init(&cc->remoteSymIv);
111072
111073 mbedtls_x509_crt_init(&cc->remoteCertificate);
111074
111075 // TODO: this can be optimized so that we dont allocate memory before parsing the certificate
111076 UA_StatusCode retval = parseRemoteCertificate_sp_basic128rsa15(cc, remoteCertificate);
111077 if(retval != UA_STATUSCODE_GOOD) {
111078 channelContext_deleteContext_sp_basic128rsa15(cc);
111079 *pp_contextData = NULL;
111080 }
111081 return retval;
111082}
111083
111084static UA_StatusCode
111085channelContext_setLocalSymEncryptingKey_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc,
111086 const UA_ByteString *key) {
111087 if(key == NULL || cc == NULL)
111088 return UA_STATUSCODE_BADINTERNALERROR;
111089
111090 UA_ByteString_clear(&cc->localSymEncryptingKey);
111091 return UA_ByteString_copy(key, &cc->localSymEncryptingKey);
111092}
111093
111094static UA_StatusCode
111095channelContext_setLocalSymSigningKey_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc,
111096 const UA_ByteString *key) {
111097 if(key == NULL || cc == NULL)
111098 return UA_STATUSCODE_BADINTERNALERROR;
111099
111100 UA_ByteString_clear(&cc->localSymSigningKey);
111101 return UA_ByteString_copy(key, &cc->localSymSigningKey);
111102}
111103
111104
111105static UA_StatusCode
111106channelContext_setLocalSymIv_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc,
111107 const UA_ByteString *iv) {
111108 if(iv == NULL || cc == NULL)
111109 return UA_STATUSCODE_BADINTERNALERROR;
111110
111111 UA_ByteString_clear(&cc->localSymIv);
111112 return UA_ByteString_copy(iv, &cc->localSymIv);
111113}
111114
111115static UA_StatusCode
111116channelContext_setRemoteSymEncryptingKey_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc,
111117 const UA_ByteString *key) {
111118 if(key == NULL || cc == NULL)
111119 return UA_STATUSCODE_BADINTERNALERROR;
111120
111121 UA_ByteString_clear(&cc->remoteSymEncryptingKey);
111122 return UA_ByteString_copy(key, &cc->remoteSymEncryptingKey);
111123}
111124
111125static UA_StatusCode
111126channelContext_setRemoteSymSigningKey_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc,
111127 const UA_ByteString *key) {
111128 if(key == NULL || cc == NULL)
111129 return UA_STATUSCODE_BADINTERNALERROR;
111130
111131 UA_ByteString_clear(&cc->remoteSymSigningKey);
111132 return UA_ByteString_copy(key, &cc->remoteSymSigningKey);
111133}
111134
111135static UA_StatusCode
111136channelContext_setRemoteSymIv_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc,
111137 const UA_ByteString *iv) {
111138 if(iv == NULL || cc == NULL)
111139 return UA_STATUSCODE_BADINTERNALERROR;
111140
111141 UA_ByteString_clear(&cc->remoteSymIv);
111142 return UA_ByteString_copy(iv, &cc->remoteSymIv);
111143}
111144
111145static UA_StatusCode
111146channelContext_compareCertificate_sp_basic128rsa15(const Basic128Rsa15_ChannelContext *cc,
111147 const UA_ByteString *certificate) {
111148 if(cc == NULL || certificate == NULL)
111149 return UA_STATUSCODE_BADINTERNALERROR;
111150
111151 mbedtls_x509_crt cert;
111152 mbedtls_x509_crt_init(&cert);
111153 int mbedErr = mbedtls_x509_crt_parse(&cert, certificate->data, certificate->length);
111154 if(mbedErr)
111155 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
111156
111157 UA_StatusCode retval = UA_STATUSCODE_GOOD;
111158 if(cert.raw.len != cc->remoteCertificate.raw.len ||
111159 memcmp(cert.raw.p, cc->remoteCertificate.raw.p, cert.raw.len) != 0)
111160 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
111161
111162 mbedtls_x509_crt_free(&cert);
111163 return retval;
111164}
111165
111166static void
111167clear_sp_basic128rsa15(UA_SecurityPolicy *securityPolicy) {
111168 if(securityPolicy == NULL)
111169 return;
111170
111171 UA_ByteString_clear(&securityPolicy->localCertificate);
111172
111173 if(securityPolicy->policyContext == NULL)
111174 return;
111175
111176 /* delete all allocated members in the context */
111177 Basic128Rsa15_PolicyContext *pc = (Basic128Rsa15_PolicyContext *)
111178 securityPolicy->policyContext;
111179
111180 mbedtls_ctr_drbg_free(&pc->drbgContext);
111181 mbedtls_entropy_free(&pc->entropyContext);
111182 mbedtls_pk_free(&pc->localPrivateKey);
111183 mbedtls_md_free(&pc->sha1MdContext);
111184 UA_ByteString_clear(&pc->localCertThumbprint);
111185
111186 UA_LOG_DEBUG(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
111187 "Deleted members of EndpointContext for sp_basic128rsa15");
111188
111189 UA_free(pc);
111190 securityPolicy->policyContext = NULL;
111191}
111192
111193static UA_StatusCode
111194updateCertificateAndPrivateKey_sp_basic128rsa15(UA_SecurityPolicy *securityPolicy,
111195 const UA_ByteString newCertificate,
111196 const UA_ByteString newPrivateKey) {
111197 if(securityPolicy == NULL)
111198 return UA_STATUSCODE_BADINTERNALERROR;
111199
111200 if(securityPolicy->policyContext == NULL)
111201 return UA_STATUSCODE_BADINTERNALERROR;
111202
111203 Basic128Rsa15_PolicyContext *pc = (Basic128Rsa15_PolicyContext *)securityPolicy->policyContext;
111204
111205 UA_ByteString_clear(&securityPolicy->localCertificate);
111206
111207 UA_StatusCode retval = UA_mbedTLS_LoadLocalCertificate(&newCertificate, &securityPolicy->localCertificate);
111208
111209 if (retval != UA_STATUSCODE_GOOD)
111210 return retval;
111211
111212 /* Set the new private key */
111213 mbedtls_pk_free(&pc->localPrivateKey);
111214 mbedtls_pk_init(&pc->localPrivateKey);
111215 int mbedErr = UA_mbedTLS_LoadPrivateKey(&newPrivateKey, &pc->localPrivateKey, &pc->entropyContext);
111216 if(mbedErr) {
111217 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
111218 goto error;
111219 }
111220
111221 retval = asym_makeThumbprint_sp_basic128rsa15(securityPolicy,
111222 &securityPolicy->localCertificate,
111223 &pc->localCertThumbprint);
111224 if(retval != UA_STATUSCODE_GOOD)
111225 goto error;
111226
111227 return retval;
111228
111229 error:
111230 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
111231 "Could not update certificate and private key");
111232 if(securityPolicy->policyContext != NULL)
111233 clear_sp_basic128rsa15(securityPolicy);
111234 return retval;
111235}
111236
111237static UA_StatusCode
111238policyContext_newContext_sp_basic128rsa15(UA_SecurityPolicy *securityPolicy,
111239 const UA_ByteString localPrivateKey) {
111240 UA_StatusCode retval = UA_STATUSCODE_GOOD;
111241 if(securityPolicy == NULL)
111242 return UA_STATUSCODE_BADINTERNALERROR;
111243
111244 if (localPrivateKey.length == 0) {
111245 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
111246 "Can not initialize security policy. Private key is empty.");
111247 return UA_STATUSCODE_BADINVALIDARGUMENT;
111248 }
111249
111250 Basic128Rsa15_PolicyContext *pc = (Basic128Rsa15_PolicyContext *)
111251 UA_malloc(sizeof(Basic128Rsa15_PolicyContext));
111252 securityPolicy->policyContext = (void *)pc;
111253 if(!pc) {
111254 retval = UA_STATUSCODE_BADOUTOFMEMORY;
111255 goto error;
111256 }
111257
111258 /* Initialize the PolicyContext */
111259 memset(pc, 0, sizeof(Basic128Rsa15_PolicyContext));
111260 mbedtls_ctr_drbg_init(&pc->drbgContext);
111261 mbedtls_entropy_init(&pc->entropyContext);
111262 mbedtls_pk_init(&pc->localPrivateKey);
111263 mbedtls_md_init(&pc->sha1MdContext);
111264
111265 /* Initialized the message digest */
111266 const mbedtls_md_info_t *const mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
111267 int mbedErr = mbedtls_md_setup(&pc->sha1MdContext, mdInfo, MBEDTLS_MD_SHA1);
111268 if(mbedErr) {
111269 retval = UA_STATUSCODE_BADOUTOFMEMORY;
111270 goto error;
111271 }
111272
111273 mbedErr = mbedtls_entropy_self_test(0);
111274
111275 if(mbedErr) {
111276 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
111277 goto error;
111278 }
111279
111280 /* Seed the RNG */
111281 char *personalization = "open62541-drbg";
111282 mbedErr = mbedtls_ctr_drbg_seed(&pc->drbgContext, mbedtls_entropy_func,
111283 &pc->entropyContext,
111284 (const unsigned char *)personalization, 14);
111285 if(mbedErr) {
111286 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
111287 goto error;
111288 }
111289
111290 /* Set the private key */
111291 mbedErr = UA_mbedTLS_LoadPrivateKey(&localPrivateKey, &pc->localPrivateKey, &pc->entropyContext);
111292
111293 if(mbedErr) {
111294 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
111295 goto error;
111296 }
111297
111298 /* Set the local certificate thumbprint */
111299 retval = UA_ByteString_allocBuffer(&pc->localCertThumbprint, UA_SHA1_LENGTH);
111300 if(retval != UA_STATUSCODE_GOOD)
111301 goto error;
111302 retval = asym_makeThumbprint_sp_basic128rsa15(securityPolicy,
111303 &securityPolicy->localCertificate,
111304 &pc->localCertThumbprint);
111305 if(retval != UA_STATUSCODE_GOOD)
111306 goto error;
111307
111308 return UA_STATUSCODE_GOOD;
111309
111310error:
111311 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
111312 "Could not create securityContext: %s", UA_StatusCode_name(retval));
111313 if(securityPolicy->policyContext != NULL)
111314 clear_sp_basic128rsa15(securityPolicy);
111315 return retval;
111316}
111317
111318UA_StatusCode
111319UA_SecurityPolicy_Basic128Rsa15(UA_SecurityPolicy *policy, const UA_ByteString localCertificate,
111320 const UA_ByteString localPrivateKey, const UA_Logger *logger) {
111321 memset(policy, 0, sizeof(UA_SecurityPolicy));
111322 policy->logger = logger;
111323
111324 UA_LOG_WARNING(logger, UA_LOGCATEGORY_SECURITYPOLICY,
111325 "!! WARNING !! The Basic128Rsa15 SecurityPolicy is unsecure. "
111326 "There are known attacks that break the encryption.");
111327
111328 policy->policyUri = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15\0");
111329
111330 UA_SecurityPolicyAsymmetricModule *const asymmetricModule = &policy->asymmetricModule;
111331 UA_SecurityPolicySymmetricModule *const symmetricModule = &policy->symmetricModule;
111332 UA_SecurityPolicyChannelModule *const channelModule = &policy->channelModule;
111333
111334 UA_StatusCode retval = UA_mbedTLS_LoadLocalCertificate(&localCertificate, &policy->localCertificate);
111335
111336 if (retval != UA_STATUSCODE_GOOD)
111337 return retval;
111338
111339 /* AsymmetricModule */
111340 UA_SecurityPolicySignatureAlgorithm *asym_signatureAlgorithm =
111341 &asymmetricModule->cryptoModule.signatureAlgorithm;
111342 asym_signatureAlgorithm->uri =
111343 UA_STRING("http://www.w3.org/2000/09/xmldsig#rsa-sha1\0");
111344 asym_signatureAlgorithm->verify =
111345 (UA_StatusCode (*)(void *, const UA_ByteString *, const UA_ByteString *))asym_verify_sp_basic128rsa15;
111346 asym_signatureAlgorithm->sign =
111347 (UA_StatusCode (*)(void *, const UA_ByteString *, UA_ByteString *))asym_sign_sp_basic128rsa15;
111348 asym_signatureAlgorithm->getLocalSignatureSize =
111349 (size_t (*)(const void *))asym_getLocalSignatureSize_sp_basic128rsa15;
111350 asym_signatureAlgorithm->getRemoteSignatureSize =
111351 (size_t (*)(const void *))asym_getRemoteSignatureSize_sp_basic128rsa15;
111352 asym_signatureAlgorithm->getLocalKeyLength = NULL; // TODO: Write function
111353 asym_signatureAlgorithm->getRemoteKeyLength = NULL; // TODO: Write function
111354
111355 UA_SecurityPolicyEncryptionAlgorithm *asym_encryptionAlgorithm =
111356 &asymmetricModule->cryptoModule.encryptionAlgorithm;
111357 asym_encryptionAlgorithm->uri = UA_STRING("http://www.w3.org/2001/04/xmlenc#rsa-1_5");
111358 asym_encryptionAlgorithm->encrypt =
111359 (UA_StatusCode(*)(void *, UA_ByteString *))asym_encrypt_sp_basic128rsa15;
111360 asym_encryptionAlgorithm->decrypt =
111361 (UA_StatusCode(*)(void *, UA_ByteString *)) asym_decrypt_sp_basic128rsa15;
111362 asym_encryptionAlgorithm->getLocalKeyLength =
111363 (size_t (*)(const void *))asym_getLocalEncryptionKeyLength_sp_basic128rsa15;
111364 asym_encryptionAlgorithm->getRemoteKeyLength =
111365 (size_t (*)(const void *))asym_getRemoteEncryptionKeyLength_sp_basic128rsa15;
111366 asym_encryptionAlgorithm->getRemoteBlockSize =
111367 (size_t (*)(const void *))asym_getRemoteBlockSize_sp_basic128rsa15;
111368 asym_encryptionAlgorithm->getRemotePlainTextBlockSize =
111369 (size_t (*)(const void *))asym_getRemotePlainTextBlockSize_sp_basic128rsa15;
111370
111371 asymmetricModule->makeCertificateThumbprint = asym_makeThumbprint_sp_basic128rsa15;
111372 asymmetricModule->compareCertificateThumbprint =
111373 asymmetricModule_compareCertificateThumbprint_sp_basic128rsa15;
111374
111375 /* SymmetricModule */
111376 symmetricModule->generateKey = sym_generateKey_sp_basic128rsa15;
111377 symmetricModule->generateNonce = sym_generateNonce_sp_basic128rsa15;
111378
111379 UA_SecurityPolicySignatureAlgorithm *sym_signatureAlgorithm =
111380 &symmetricModule->cryptoModule.signatureAlgorithm;
111381 sym_signatureAlgorithm->uri =
111382 UA_STRING("http://www.w3.org/2000/09/xmldsig#hmac-sha1\0");
111383 sym_signatureAlgorithm->verify =
111384 (UA_StatusCode (*)(void *, const UA_ByteString *,
111385 const UA_ByteString *))sym_verify_sp_basic128rsa15;
111386 sym_signatureAlgorithm->sign =
111387 (UA_StatusCode (*)(void *, const UA_ByteString *, UA_ByteString *))sym_sign_sp_basic128rsa15;
111388 sym_signatureAlgorithm->getLocalSignatureSize = sym_getSignatureSize_sp_basic128rsa15;
111389 sym_signatureAlgorithm->getRemoteSignatureSize = sym_getSignatureSize_sp_basic128rsa15;
111390 sym_signatureAlgorithm->getLocalKeyLength =
111391 (size_t (*)(const void *))sym_getSigningKeyLength_sp_basic128rsa15;
111392 sym_signatureAlgorithm->getRemoteKeyLength =
111393 (size_t (*)(const void *))sym_getSigningKeyLength_sp_basic128rsa15;
111394
111395 UA_SecurityPolicyEncryptionAlgorithm *sym_encryptionAlgorithm =
111396 &symmetricModule->cryptoModule.encryptionAlgorithm;
111397 sym_encryptionAlgorithm->uri = UA_STRING("http://www.w3.org/2001/04/xmlenc#aes128-cbc");
111398 sym_encryptionAlgorithm->encrypt =
111399 (UA_StatusCode(*)(void *, UA_ByteString *))sym_encrypt_sp_basic128rsa15;
111400 sym_encryptionAlgorithm->decrypt =
111401 (UA_StatusCode(*)(void *, UA_ByteString *))sym_decrypt_sp_basic128rsa15;
111402 sym_encryptionAlgorithm->getLocalKeyLength = sym_getEncryptionKeyLength_sp_basic128rsa15;
111403 sym_encryptionAlgorithm->getRemoteKeyLength = sym_getEncryptionKeyLength_sp_basic128rsa15;
111404 sym_encryptionAlgorithm->getRemoteBlockSize =
111405 (size_t (*)(const void *))sym_getEncryptionBlockSize_sp_basic128rsa15;
111406 sym_encryptionAlgorithm->getRemotePlainTextBlockSize =
111407 (size_t (*)(const void *))sym_getPlainTextBlockSize_sp_basic128rsa15;
111408 symmetricModule->secureChannelNonceLength = 16;
111409
111410 // Use the same signature algorithm as the asymmetric component for certificate signing (see standard)
111411 policy->certificateSigningAlgorithm = policy->asymmetricModule.cryptoModule.signatureAlgorithm;
111412
111413 /* ChannelModule */
111414 channelModule->newContext = channelContext_newContext_sp_basic128rsa15;
111415 channelModule->deleteContext = (void (*)(void *))
111416 channelContext_deleteContext_sp_basic128rsa15;
111417
111418 channelModule->setLocalSymEncryptingKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
111419 channelContext_setLocalSymEncryptingKey_sp_basic128rsa15;
111420 channelModule->setLocalSymSigningKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
111421 channelContext_setLocalSymSigningKey_sp_basic128rsa15;
111422 channelModule->setLocalSymIv = (UA_StatusCode (*)(void *, const UA_ByteString *))
111423 channelContext_setLocalSymIv_sp_basic128rsa15;
111424
111425 channelModule->setRemoteSymEncryptingKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
111426 channelContext_setRemoteSymEncryptingKey_sp_basic128rsa15;
111427 channelModule->setRemoteSymSigningKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
111428 channelContext_setRemoteSymSigningKey_sp_basic128rsa15;
111429 channelModule->setRemoteSymIv = (UA_StatusCode (*)(void *, const UA_ByteString *))
111430 channelContext_setRemoteSymIv_sp_basic128rsa15;
111431
111432 channelModule->compareCertificate = (UA_StatusCode (*)(const void *, const UA_ByteString *))
111433 channelContext_compareCertificate_sp_basic128rsa15;
111434
111435 policy->updateCertificateAndPrivateKey = updateCertificateAndPrivateKey_sp_basic128rsa15;
111436 policy->clear = clear_sp_basic128rsa15;
111437
111438 UA_StatusCode res = policyContext_newContext_sp_basic128rsa15(policy, localPrivateKey);
111439 if(res != UA_STATUSCODE_GOOD)
111440 clear_sp_basic128rsa15(policy);
111441
111442 return res;
111443}
111444
111445#endif
111446
111447/**** amalgamated original file "/plugins/crypto/mbedtls/ua_securitypolicy_basic256.c" ****/
111448
111449/* This Source Code Form is subject to the terms of the Mozilla Public
111450 * License, v. 2.0. If a copy of the MPL was not distributed with this
111451 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
111452 *
111453 * Copyright 2018 (c) Mark Giraud, Fraunhofer IOSB
111454 * Copyright 2018 (c) Daniel Feist, Precitec GmbH & Co. KG
111455 * Copyright 2019 (c) Kalycito Infotech Private Limited
111456 * Copyright 2020 (c) Wind River Systems, Inc.
111457 * Copyright 2020 (c) basysKom GmbH
111458 *
111459 */
111460
111461
111462#ifdef UA_ENABLE_ENCRYPTION_MBEDTLS
111463
111464
111465#include <mbedtls/aes.h>
111466#include <mbedtls/entropy.h>
111467#include <mbedtls/error.h>
111468#include <mbedtls/sha1.h>
111469#include <mbedtls/version.h>
111470
111471/* Notes:
111472 * mbedTLS' AES allows in-place encryption and decryption. Sow we don't have to
111473 * allocate temp buffers.
111474 * https://tls.mbed.org/discussions/generic/in-place-decryption-with-aes256-same-input-output-buffer
111475 */
111476
111477#define UA_SECURITYPOLICY_BASIC256SHA1_RSAPADDING_LEN 42
111478#define UA_SHA1_LENGTH 20
111479#define UA_BASIC256_SYM_SIGNING_KEY_LENGTH 24
111480#define UA_SECURITYPOLICY_BASIC256_SYM_KEY_LENGTH 32
111481#define UA_SECURITYPOLICY_BASIC256_SYM_ENCRYPTION_BLOCK_SIZE 16
111482#define UA_SECURITYPOLICY_BASIC256_SYM_PLAIN_TEXT_BLOCK_SIZE 16
111483#define UA_SECURITYPOLICY_BASIC256_MINASYMKEYLENGTH 128
111484#define UA_SECURITYPOLICY_BASIC256_MAXASYMKEYLENGTH 512
111485
111486typedef struct {
111487 UA_ByteString localCertThumbprint;
111488
111489 mbedtls_ctr_drbg_context drbgContext;
111490 mbedtls_entropy_context entropyContext;
111491 mbedtls_md_context_t sha1MdContext;
111492 mbedtls_pk_context localPrivateKey;
111493} Basic256_PolicyContext;
111494
111495typedef struct {
111496 Basic256_PolicyContext *policyContext;
111497
111498 UA_ByteString localSymSigningKey;
111499 UA_ByteString localSymEncryptingKey;
111500 UA_ByteString localSymIv;
111501
111502 UA_ByteString remoteSymSigningKey;
111503 UA_ByteString remoteSymEncryptingKey;
111504 UA_ByteString remoteSymIv;
111505
111506 mbedtls_x509_crt remoteCertificate;
111507} Basic256_ChannelContext;
111508
111509/********************/
111510/* AsymmetricModule */
111511/********************/
111512
111513/* VERIFY AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256 */
111514static UA_StatusCode
111515asym_verify_sp_basic256(Basic256_ChannelContext *cc,
111516 const UA_ByteString *message,
111517 const UA_ByteString *signature) {
111518 if(message == NULL || signature == NULL || cc == NULL)
111519 return UA_STATUSCODE_BADINTERNALERROR;
111520
111521 return mbedtls_verifySig_sha1(&cc->remoteCertificate, message, signature);
111522}
111523
111524/* AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256 */
111525static UA_StatusCode
111526asym_sign_sp_basic256(Basic256_ChannelContext *cc,
111527 const UA_ByteString *message,
111528 UA_ByteString *signature) {
111529 if(message == NULL || signature == NULL || cc == NULL)
111530 return UA_STATUSCODE_BADINTERNALERROR;
111531
111532 Basic256_PolicyContext *pc = cc->policyContext;
111533 return mbedtls_sign_sha1(&pc->localPrivateKey, &pc->drbgContext,
111534 message, signature);
111535}
111536
111537static size_t
111538asym_getLocalSignatureSize_sp_basic256(const Basic256_ChannelContext *cc) {
111539 if(cc == NULL)
111540 return 0;
111541#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
111542 return mbedtls_pk_rsa(cc->policyContext->localPrivateKey)->len;
111543#else
111544 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->policyContext->localPrivateKey));
111545#endif
111546}
111547
111548static size_t
111549asym_getRemoteSignatureSize_sp_basic256(const Basic256_ChannelContext *cc) {
111550 if(cc == NULL)
111551 return 0;
111552#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
111553 return mbedtls_pk_rsa(cc->remoteCertificate.pk)->len;
111554#else
111555 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
111556#endif
111557}
111558
111559static size_t
111560asym_getRemotePlainTextBlockSize_sp_basic256(const Basic256_ChannelContext *cc) {
111561 if(cc == NULL)
111562 return 0;
111563#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
111564 mbedtls_rsa_context *const rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
111565 return rsaContext->len - UA_SECURITYPOLICY_BASIC256SHA1_RSAPADDING_LEN;
111566#else
111567 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk)) -
111568 UA_SECURITYPOLICY_BASIC256SHA1_RSAPADDING_LEN;
111569#endif
111570}
111571
111572/* AsymmetricEncryptionAlgorithm_RSA-OAEP-SHA1 */
111573static UA_StatusCode
111574asym_encrypt_sp_basic256(Basic256_ChannelContext *cc,
111575 UA_ByteString *data) {
111576 if(cc == NULL || data == NULL)
111577 return UA_STATUSCODE_BADINTERNALERROR;
111578
111579 const size_t plainTextBlockSize = asym_getRemotePlainTextBlockSize_sp_basic256(cc);
111580
111581 mbedtls_rsa_context *remoteRsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
111582 mbedtls_rsa_set_padding(remoteRsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1);
111583
111584 return mbedtls_encrypt_rsaOaep(remoteRsaContext, &cc->policyContext->drbgContext,
111585 data, plainTextBlockSize);
111586}
111587
111588/* AsymmetricEncryptionAlgorithm_RSA-OAEP-SHA1 */
111589static UA_StatusCode
111590asym_decrypt_sp_basic256(Basic256_ChannelContext *cc,
111591 UA_ByteString *data) {
111592 if(cc == NULL || data == NULL)
111593 return UA_STATUSCODE_BADINTERNALERROR;
111594 return mbedtls_decrypt_rsaOaep(&cc->policyContext->localPrivateKey,
111595 &cc->policyContext->drbgContext, data, MBEDTLS_MD_SHA1);
111596}
111597
111598static size_t
111599asym_getLocalEncryptionKeyLength_sp_basic256(const Basic256_ChannelContext *cc) {
111600 return mbedtls_pk_get_len(&cc->policyContext->localPrivateKey) * 8;
111601}
111602
111603static size_t
111604asym_getRemoteEncryptionKeyLength_sp_basic256(const Basic256_ChannelContext *cc) {
111605 return mbedtls_pk_get_len(&cc->remoteCertificate.pk) * 8;
111606}
111607
111608static size_t
111609asym_getRemoteBlockSize_sp_basic256(const Basic256_ChannelContext *cc) {
111610 if(cc == NULL)
111611 return 0;
111612#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
111613 mbedtls_rsa_context *const rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
111614 return rsaContext->len;
111615#else
111616 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
111617#endif
111618}
111619
111620static UA_StatusCode
111621asym_makeThumbprint_sp_basic256(const UA_SecurityPolicy *securityPolicy,
111622 const UA_ByteString *certificate,
111623 UA_ByteString *thumbprint) {
111624 if(securityPolicy == NULL || certificate == NULL || thumbprint == NULL)
111625 return UA_STATUSCODE_BADINTERNALERROR;
111626 return mbedtls_thumbprint_sha1(certificate, thumbprint);
111627}
111628
111629static UA_StatusCode
111630asymmetricModule_compareCertificateThumbprint_sp_basic256(const UA_SecurityPolicy *securityPolicy,
111631 const UA_ByteString *certificateThumbprint) {
111632 if(securityPolicy == NULL || certificateThumbprint == NULL)
111633 return UA_STATUSCODE_BADINTERNALERROR;
111634
111635 Basic256_PolicyContext *pc = (Basic256_PolicyContext *)securityPolicy->policyContext;
111636 if(!UA_ByteString_equal(certificateThumbprint, &pc->localCertThumbprint))
111637 return UA_STATUSCODE_BADCERTIFICATEINVALID;
111638
111639 return UA_STATUSCODE_GOOD;
111640}
111641
111642/*******************/
111643/* SymmetricModule */
111644/*******************/
111645
111646static UA_StatusCode
111647sym_verify_sp_basic256(Basic256_ChannelContext *cc,
111648 const UA_ByteString *message,
111649 const UA_ByteString *signature) {
111650 if(cc == NULL || message == NULL || signature == NULL)
111651 return UA_STATUSCODE_BADINTERNALERROR;
111652
111653 /* Compute MAC */
111654 if(signature->length != UA_SHA1_LENGTH)
111655 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
111656
111657 Basic256_PolicyContext *pc = cc->policyContext;
111658
111659 unsigned char mac[UA_SHA1_LENGTH];
111660 mbedtls_hmac(&pc->sha1MdContext, &cc->remoteSymSigningKey, message, mac);
111661
111662 /* Compare with Signature */
111663 if(!UA_constantTimeEqual(signature->data, mac, UA_SHA1_LENGTH))
111664 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
111665 return UA_STATUSCODE_GOOD;
111666}
111667
111668static UA_StatusCode
111669sym_sign_sp_basic256(const Basic256_ChannelContext *cc,
111670 const UA_ByteString *message, UA_ByteString *signature) {
111671 if(signature->length != UA_SHA1_LENGTH)
111672 return UA_STATUSCODE_BADINTERNALERROR;
111673
111674 mbedtls_hmac(&cc->policyContext->sha1MdContext, &cc->localSymSigningKey,
111675 message, signature->data);
111676 return UA_STATUSCODE_GOOD;
111677}
111678
111679static size_t
111680sym_getSignatureSize_sp_basic256(const void *channelContext) {
111681 return UA_SHA1_LENGTH;
111682}
111683
111684static size_t
111685sym_getSigningKeyLength_sp_basic256(const void *const channelContext) {
111686 return UA_BASIC256_SYM_SIGNING_KEY_LENGTH;
111687}
111688
111689static size_t
111690sym_getEncryptionKeyLength_sp_basic256(const void *channelContext) {
111691 return UA_SECURITYPOLICY_BASIC256_SYM_KEY_LENGTH;
111692}
111693
111694static size_t
111695sym_getEncryptionBlockSize_sp_basic256(const void *const channelContext) {
111696 return UA_SECURITYPOLICY_BASIC256_SYM_ENCRYPTION_BLOCK_SIZE;
111697}
111698
111699static size_t
111700sym_getPlainTextBlockSize_sp_basic256(const void *const channelContext) {
111701 return UA_SECURITYPOLICY_BASIC256_SYM_PLAIN_TEXT_BLOCK_SIZE;
111702}
111703
111704static UA_StatusCode
111705sym_encrypt_sp_basic256(const Basic256_ChannelContext *cc,
111706 UA_ByteString *data) {
111707 if(cc == NULL || data == NULL)
111708 return UA_STATUSCODE_BADINTERNALERROR;
111709
111710 if(cc->localSymIv.length != UA_SECURITYPOLICY_BASIC256_SYM_ENCRYPTION_BLOCK_SIZE)
111711 return UA_STATUSCODE_BADINTERNALERROR;
111712
111713 size_t plainTextBlockSize = UA_SECURITYPOLICY_BASIC256_SYM_PLAIN_TEXT_BLOCK_SIZE;
111714 if(data->length % plainTextBlockSize != 0)
111715 return UA_STATUSCODE_BADINTERNALERROR;
111716
111717 /* Keylength in bits */
111718 unsigned int keylength = (unsigned int)(cc->localSymEncryptingKey.length * 8);
111719 mbedtls_aes_context aesContext;
111720 int mbedErr = mbedtls_aes_setkey_enc(&aesContext, cc->localSymEncryptingKey.data, keylength);
111721 if(mbedErr)
111722 return UA_STATUSCODE_BADINTERNALERROR;
111723
111724 UA_ByteString ivCopy;
111725 UA_StatusCode retval = UA_ByteString_copy(&cc->localSymIv, &ivCopy);
111726 if(retval != UA_STATUSCODE_GOOD)
111727 return retval;
111728
111729 mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_ENCRYPT, data->length,
111730 ivCopy.data, data->data, data->data);
111731 if(mbedErr)
111732 retval = UA_STATUSCODE_BADINTERNALERROR;
111733 UA_ByteString_clear(&ivCopy);
111734 return retval;
111735}
111736
111737static UA_StatusCode
111738sym_decrypt_sp_basic256(const Basic256_ChannelContext *cc,
111739 UA_ByteString *data) {
111740 if(cc == NULL || data == NULL)
111741 return UA_STATUSCODE_BADINTERNALERROR;
111742
111743 size_t encryptionBlockSize = UA_SECURITYPOLICY_BASIC256_SYM_ENCRYPTION_BLOCK_SIZE;
111744 if(cc->remoteSymIv.length != encryptionBlockSize)
111745 return UA_STATUSCODE_BADINTERNALERROR;
111746
111747 if(data->length % encryptionBlockSize != 0)
111748 return UA_STATUSCODE_BADINTERNALERROR;
111749
111750 unsigned int keylength = (unsigned int)(cc->remoteSymEncryptingKey.length * 8);
111751 mbedtls_aes_context aesContext;
111752 int mbedErr = mbedtls_aes_setkey_dec(&aesContext, cc->remoteSymEncryptingKey.data, keylength);
111753 if(mbedErr)
111754 return UA_STATUSCODE_BADINTERNALERROR;
111755
111756 UA_ByteString ivCopy;
111757 UA_StatusCode retval = UA_ByteString_copy(&cc->remoteSymIv, &ivCopy);
111758 if(retval != UA_STATUSCODE_GOOD)
111759 return retval;
111760
111761 mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_DECRYPT, data->length,
111762 ivCopy.data, data->data, data->data);
111763 if(mbedErr)
111764 retval = UA_STATUSCODE_BADINTERNALERROR;
111765 UA_ByteString_clear(&ivCopy);
111766 return retval;
111767}
111768
111769static UA_StatusCode
111770sym_generateKey_sp_basic256(void *policyContext, const UA_ByteString *secret,
111771 const UA_ByteString *seed, UA_ByteString *out) {
111772 if(secret == NULL || seed == NULL || out == NULL)
111773 return UA_STATUSCODE_BADINTERNALERROR;
111774 Basic256_PolicyContext *pc = (Basic256_PolicyContext *)policyContext;
111775 return mbedtls_generateKey(&pc->sha1MdContext, secret, seed, out);
111776}
111777
111778static UA_StatusCode
111779sym_generateNonce_sp_basic256(void *policyContext, UA_ByteString *out) {
111780 if(out == NULL)
111781 return UA_STATUSCODE_BADINTERNALERROR;
111782 Basic256_PolicyContext *pc = (Basic256_PolicyContext *)policyContext;
111783 int mbedErr = mbedtls_ctr_drbg_random(&pc->drbgContext, out->data, out->length);
111784 if(mbedErr)
111785 return UA_STATUSCODE_BADUNEXPECTEDERROR;
111786 return UA_STATUSCODE_GOOD;
111787}
111788
111789/*****************/
111790/* ChannelModule */
111791/*****************/
111792
111793/* Assumes that the certificate has been verified externally */
111794static UA_StatusCode
111795parseRemoteCertificate_sp_basic256(Basic256_ChannelContext *cc,
111796 const UA_ByteString *remoteCertificate) {
111797 if(remoteCertificate == NULL || cc == NULL)
111798 return UA_STATUSCODE_BADINTERNALERROR;
111799
111800 /* Parse the certificate */
111801 int mbedErr = mbedtls_x509_crt_parse(&cc->remoteCertificate, remoteCertificate->data,
111802 remoteCertificate->length);
111803 if(mbedErr)
111804 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
111805
111806 /* Check the key length */
111807#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
111808 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
111809 size_t keylen = rsaContext->len;
111810#else
111811 size_t keylen = mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
111812#endif
111813 if(keylen < UA_SECURITYPOLICY_BASIC256_MINASYMKEYLENGTH ||
111814 keylen > UA_SECURITYPOLICY_BASIC256_MAXASYMKEYLENGTH)
111815 return UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED;
111816
111817 return UA_STATUSCODE_GOOD;
111818}
111819
111820static void
111821channelContext_deleteContext_sp_basic256(Basic256_ChannelContext *cc) {
111822 UA_ByteString_clear(&cc->localSymSigningKey);
111823 UA_ByteString_clear(&cc->localSymEncryptingKey);
111824 UA_ByteString_clear(&cc->localSymIv);
111825
111826 UA_ByteString_clear(&cc->remoteSymSigningKey);
111827 UA_ByteString_clear(&cc->remoteSymEncryptingKey);
111828 UA_ByteString_clear(&cc->remoteSymIv);
111829
111830 mbedtls_x509_crt_free(&cc->remoteCertificate);
111831
111832 UA_free(cc);
111833}
111834
111835static UA_StatusCode
111836channelContext_newContext_sp_basic256(const UA_SecurityPolicy *securityPolicy,
111837 const UA_ByteString *remoteCertificate,
111838 void **pp_contextData) {
111839 if(securityPolicy == NULL || remoteCertificate == NULL || pp_contextData == NULL)
111840 return UA_STATUSCODE_BADINTERNALERROR;
111841
111842 /* Allocate the channel context */
111843 *pp_contextData = UA_malloc(sizeof(Basic256_ChannelContext));
111844 if(*pp_contextData == NULL)
111845 return UA_STATUSCODE_BADOUTOFMEMORY;
111846
111847 Basic256_ChannelContext *cc = (Basic256_ChannelContext *)*pp_contextData;
111848
111849 /* Initialize the channel context */
111850 cc->policyContext = (Basic256_PolicyContext *)securityPolicy->policyContext;
111851
111852 UA_ByteString_init(&cc->localSymSigningKey);
111853 UA_ByteString_init(&cc->localSymEncryptingKey);
111854 UA_ByteString_init(&cc->localSymIv);
111855
111856 UA_ByteString_init(&cc->remoteSymSigningKey);
111857 UA_ByteString_init(&cc->remoteSymEncryptingKey);
111858 UA_ByteString_init(&cc->remoteSymIv);
111859
111860 mbedtls_x509_crt_init(&cc->remoteCertificate);
111861
111862 // TODO: this can be optimized so that we dont allocate memory before parsing the certificate
111863 UA_StatusCode retval = parseRemoteCertificate_sp_basic256(cc, remoteCertificate);
111864 if(retval != UA_STATUSCODE_GOOD) {
111865 channelContext_deleteContext_sp_basic256(cc);
111866 *pp_contextData = NULL;
111867 }
111868 return retval;
111869}
111870
111871static UA_StatusCode
111872channelContext_setLocalSymEncryptingKey_sp_basic256(Basic256_ChannelContext *cc,
111873 const UA_ByteString *key) {
111874 if(key == NULL || cc == NULL)
111875 return UA_STATUSCODE_BADINTERNALERROR;
111876
111877 UA_ByteString_clear(&cc->localSymEncryptingKey);
111878 return UA_ByteString_copy(key, &cc->localSymEncryptingKey);
111879}
111880
111881static UA_StatusCode
111882channelContext_setLocalSymSigningKey_sp_basic256(Basic256_ChannelContext *cc,
111883 const UA_ByteString *key) {
111884 if(key == NULL || cc == NULL)
111885 return UA_STATUSCODE_BADINTERNALERROR;
111886
111887 UA_ByteString_clear(&cc->localSymSigningKey);
111888 return UA_ByteString_copy(key, &cc->localSymSigningKey);
111889}
111890
111891
111892static UA_StatusCode
111893channelContext_setLocalSymIv_sp_basic256(Basic256_ChannelContext *cc,
111894 const UA_ByteString *iv) {
111895 if(iv == NULL || cc == NULL)
111896 return UA_STATUSCODE_BADINTERNALERROR;
111897
111898 UA_ByteString_clear(&cc->localSymIv);
111899 return UA_ByteString_copy(iv, &cc->localSymIv);
111900}
111901
111902static UA_StatusCode
111903channelContext_setRemoteSymEncryptingKey_sp_basic256(Basic256_ChannelContext *cc,
111904 const UA_ByteString *key) {
111905 if(key == NULL || cc == NULL)
111906 return UA_STATUSCODE_BADINTERNALERROR;
111907
111908 UA_ByteString_clear(&cc->remoteSymEncryptingKey);
111909 return UA_ByteString_copy(key, &cc->remoteSymEncryptingKey);
111910}
111911
111912static UA_StatusCode
111913channelContext_setRemoteSymSigningKey_sp_basic256(Basic256_ChannelContext *cc,
111914 const UA_ByteString *key) {
111915 if(key == NULL || cc == NULL)
111916 return UA_STATUSCODE_BADINTERNALERROR;
111917
111918 UA_ByteString_clear(&cc->remoteSymSigningKey);
111919 return UA_ByteString_copy(key, &cc->remoteSymSigningKey);
111920}
111921
111922static UA_StatusCode
111923channelContext_setRemoteSymIv_sp_basic256(Basic256_ChannelContext *cc,
111924 const UA_ByteString *iv) {
111925 if(iv == NULL || cc == NULL)
111926 return UA_STATUSCODE_BADINTERNALERROR;
111927
111928 UA_ByteString_clear(&cc->remoteSymIv);
111929 return UA_ByteString_copy(iv, &cc->remoteSymIv);
111930}
111931
111932static UA_StatusCode
111933channelContext_compareCertificate_sp_basic256(const Basic256_ChannelContext *cc,
111934 const UA_ByteString *certificate) {
111935 if(cc == NULL || certificate == NULL)
111936 return UA_STATUSCODE_BADINTERNALERROR;
111937
111938 mbedtls_x509_crt cert;
111939 mbedtls_x509_crt_init(&cert);
111940 int mbedErr = mbedtls_x509_crt_parse(&cert, certificate->data, certificate->length);
111941 if(mbedErr)
111942 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
111943
111944 UA_StatusCode retval = UA_STATUSCODE_GOOD;
111945 if(cert.raw.len != cc->remoteCertificate.raw.len ||
111946 memcmp(cert.raw.p, cc->remoteCertificate.raw.p, cert.raw.len) != 0)
111947 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
111948
111949 mbedtls_x509_crt_free(&cert);
111950 return retval;
111951}
111952
111953static void
111954clear_sp_basic256(UA_SecurityPolicy *securityPolicy) {
111955 if(securityPolicy == NULL)
111956 return;
111957
111958 UA_ByteString_clear(&securityPolicy->localCertificate);
111959
111960 if(securityPolicy->policyContext == NULL)
111961 return;
111962
111963 /* delete all allocated members in the context */
111964 Basic256_PolicyContext *pc = (Basic256_PolicyContext *)
111965 securityPolicy->policyContext;
111966
111967 mbedtls_ctr_drbg_free(&pc->drbgContext);
111968 mbedtls_entropy_free(&pc->entropyContext);
111969 mbedtls_pk_free(&pc->localPrivateKey);
111970 mbedtls_md_free(&pc->sha1MdContext);
111971 UA_ByteString_clear(&pc->localCertThumbprint);
111972
111973 UA_LOG_DEBUG(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
111974 "Deleted members of EndpointContext for sp_basic256");
111975
111976 UA_free(pc);
111977 securityPolicy->policyContext = NULL;
111978}
111979
111980static UA_StatusCode
111981updateCertificateAndPrivateKey_sp_basic256(UA_SecurityPolicy *securityPolicy,
111982 const UA_ByteString newCertificate,
111983 const UA_ByteString newPrivateKey) {
111984 if(securityPolicy == NULL)
111985 return UA_STATUSCODE_BADINTERNALERROR;
111986
111987 if(securityPolicy->policyContext == NULL)
111988 return UA_STATUSCODE_BADINTERNALERROR;
111989
111990 Basic256_PolicyContext *pc = (Basic256_PolicyContext *)
111991 securityPolicy->policyContext;
111992
111993 UA_ByteString_clear(&securityPolicy->localCertificate);
111994
111995 UA_StatusCode retval = UA_mbedTLS_LoadLocalCertificate(&newCertificate, &securityPolicy->localCertificate);
111996
111997 if (retval != UA_STATUSCODE_GOOD)
111998 return retval;
111999
112000 /* Set the new private key */
112001 mbedtls_pk_free(&pc->localPrivateKey);
112002 mbedtls_pk_init(&pc->localPrivateKey);
112003
112004 int mbedErr = UA_mbedTLS_LoadPrivateKey(&newPrivateKey, &pc->localPrivateKey, &pc->entropyContext);
112005
112006 if(mbedErr) {
112007 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112008 goto error;
112009 }
112010
112011 retval = asym_makeThumbprint_sp_basic256(securityPolicy,
112012 &securityPolicy->localCertificate,
112013 &pc->localCertThumbprint);
112014 if(retval != UA_STATUSCODE_GOOD)
112015 goto error;
112016
112017 return retval;
112018
112019 error:
112020 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
112021 "Could not update certificate and private key");
112022 if(securityPolicy->policyContext != NULL)
112023 clear_sp_basic256(securityPolicy);
112024 return retval;
112025}
112026
112027static UA_StatusCode
112028policyContext_newContext_sp_basic256(UA_SecurityPolicy *securityPolicy,
112029 const UA_ByteString localPrivateKey) {
112030 UA_StatusCode retval = UA_STATUSCODE_GOOD;
112031 if(securityPolicy == NULL)
112032 return UA_STATUSCODE_BADINTERNALERROR;
112033
112034 if (localPrivateKey.length == 0) {
112035 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
112036 "Can not initialize security policy. Private key is empty.");
112037 return UA_STATUSCODE_BADINVALIDARGUMENT;
112038 }
112039
112040 Basic256_PolicyContext *pc = (Basic256_PolicyContext *)
112041 UA_malloc(sizeof(Basic256_PolicyContext));
112042 securityPolicy->policyContext = (void *)pc;
112043 if(!pc) {
112044 retval = UA_STATUSCODE_BADOUTOFMEMORY;
112045 goto error;
112046 }
112047
112048 /* Initialize the PolicyContext */
112049 memset(pc, 0, sizeof(Basic256_PolicyContext));
112050 mbedtls_ctr_drbg_init(&pc->drbgContext);
112051 mbedtls_entropy_init(&pc->entropyContext);
112052 mbedtls_pk_init(&pc->localPrivateKey);
112053 mbedtls_md_init(&pc->sha1MdContext);
112054
112055 /* Initialized the message digest */
112056 const mbedtls_md_info_t *mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
112057 int mbedErr = mbedtls_md_setup(&pc->sha1MdContext, mdInfo, MBEDTLS_MD_SHA1);
112058 if(mbedErr) {
112059 retval = UA_STATUSCODE_BADOUTOFMEMORY;
112060 goto error;
112061 }
112062
112063 mbedErr = mbedtls_entropy_self_test(0);
112064
112065 if(mbedErr) {
112066 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112067 goto error;
112068 }
112069
112070 /* Seed the RNG */
112071 char *personalization = "open62541-drbg";
112072 mbedErr = mbedtls_ctr_drbg_seed(&pc->drbgContext, mbedtls_entropy_func,
112073 &pc->entropyContext,
112074 (const unsigned char *)personalization, 14);
112075 if(mbedErr) {
112076 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112077 goto error;
112078 }
112079
112080 /* Set the private key */
112081 mbedErr = UA_mbedTLS_LoadPrivateKey(&localPrivateKey, &pc->localPrivateKey, &pc->entropyContext);
112082 if(mbedErr) {
112083 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112084 goto error;
112085 }
112086
112087 /* Set the local certificate thumbprint */
112088 retval = UA_ByteString_allocBuffer(&pc->localCertThumbprint, UA_SHA1_LENGTH);
112089 if(retval != UA_STATUSCODE_GOOD)
112090 goto error;
112091 retval = asym_makeThumbprint_sp_basic256(securityPolicy,
112092 &securityPolicy->localCertificate,
112093 &pc->localCertThumbprint);
112094 if(retval != UA_STATUSCODE_GOOD)
112095 goto error;
112096
112097 return UA_STATUSCODE_GOOD;
112098
112099error:
112100 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
112101 "Could not create securityContext: %s", UA_StatusCode_name(retval));
112102 if(securityPolicy->policyContext != NULL)
112103 clear_sp_basic256(securityPolicy);
112104 return retval;
112105}
112106
112107UA_StatusCode
112108UA_SecurityPolicy_Basic256(UA_SecurityPolicy *policy, const UA_ByteString localCertificate,
112109 const UA_ByteString localPrivateKey, const UA_Logger *logger) {
112110
112111 UA_LOG_WARNING(logger, UA_LOGCATEGORY_SECURITYPOLICY,
112112 "!! WARNING !! The Basic256 SecurityPolicy is unsecure. "
112113 "There are known attacks that break the encryption.");
112114
112115 memset(policy, 0, sizeof(UA_SecurityPolicy));
112116 policy->logger = logger;
112117
112118 policy->policyUri = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#Basic256\0");
112119
112120 UA_SecurityPolicyAsymmetricModule *const asymmetricModule = &policy->asymmetricModule;
112121 UA_SecurityPolicySymmetricModule *const symmetricModule = &policy->symmetricModule;
112122 UA_SecurityPolicyChannelModule *const channelModule = &policy->channelModule;
112123
112124 UA_StatusCode retval = UA_mbedTLS_LoadLocalCertificate(&localCertificate, &policy->localCertificate);
112125
112126 if (retval != UA_STATUSCODE_GOOD)
112127 return retval;
112128
112129 /* AsymmetricModule */
112130 UA_SecurityPolicySignatureAlgorithm *asym_signatureAlgorithm =
112131 &asymmetricModule->cryptoModule.signatureAlgorithm;
112132 asym_signatureAlgorithm->uri =
112133 UA_STRING("http://www.w3.org/2000/09/xmldsig#rsa-sha1\0");
112134 asym_signatureAlgorithm->verify =
112135 (UA_StatusCode (*)(void *, const UA_ByteString *, const UA_ByteString *))asym_verify_sp_basic256;
112136 asym_signatureAlgorithm->sign =
112137 (UA_StatusCode (*)(void *, const UA_ByteString *, UA_ByteString *))asym_sign_sp_basic256;
112138 asym_signatureAlgorithm->getLocalSignatureSize =
112139 (size_t (*)(const void *))asym_getLocalSignatureSize_sp_basic256;
112140 asym_signatureAlgorithm->getRemoteSignatureSize =
112141 (size_t (*)(const void *))asym_getRemoteSignatureSize_sp_basic256;
112142 asym_signatureAlgorithm->getLocalKeyLength = NULL; // TODO: Write function
112143 asym_signatureAlgorithm->getRemoteKeyLength = NULL; // TODO: Write function
112144
112145 UA_SecurityPolicyEncryptionAlgorithm *asym_encryptionAlgorithm =
112146 &asymmetricModule->cryptoModule.encryptionAlgorithm;
112147 asym_encryptionAlgorithm->uri = UA_STRING("http://www.w3.org/2001/04/xmlenc#rsa-oaep\0");
112148 asym_encryptionAlgorithm->encrypt =
112149 (UA_StatusCode(*)(void *, UA_ByteString *))asym_encrypt_sp_basic256;
112150 asym_encryptionAlgorithm->decrypt =
112151 (UA_StatusCode(*)(void *, UA_ByteString *))asym_decrypt_sp_basic256;
112152 asym_encryptionAlgorithm->getLocalKeyLength =
112153 (size_t (*)(const void *))asym_getLocalEncryptionKeyLength_sp_basic256;
112154 asym_encryptionAlgorithm->getRemoteKeyLength =
112155 (size_t (*)(const void *))asym_getRemoteEncryptionKeyLength_sp_basic256;
112156 asym_encryptionAlgorithm->getRemoteBlockSize =
112157 (size_t (*)(const void *))asym_getRemoteBlockSize_sp_basic256;
112158 asym_encryptionAlgorithm->getRemotePlainTextBlockSize =
112159 (size_t (*)(const void *))asym_getRemotePlainTextBlockSize_sp_basic256;
112160
112161 asymmetricModule->makeCertificateThumbprint = asym_makeThumbprint_sp_basic256;
112162 asymmetricModule->compareCertificateThumbprint =
112163 asymmetricModule_compareCertificateThumbprint_sp_basic256;
112164
112165 /* SymmetricModule */
112166 symmetricModule->generateKey = sym_generateKey_sp_basic256;
112167 symmetricModule->generateNonce = sym_generateNonce_sp_basic256;
112168
112169 UA_SecurityPolicySignatureAlgorithm *sym_signatureAlgorithm =
112170 &symmetricModule->cryptoModule.signatureAlgorithm;
112171 sym_signatureAlgorithm->uri =
112172 UA_STRING("http://www.w3.org/2000/09/xmldsig#hmac-sha1\0");
112173 sym_signatureAlgorithm->verify =
112174 (UA_StatusCode (*)(void *, const UA_ByteString *,
112175 const UA_ByteString *))sym_verify_sp_basic256;
112176 sym_signatureAlgorithm->sign =
112177 (UA_StatusCode (*)(void *, const UA_ByteString *, UA_ByteString *))sym_sign_sp_basic256;
112178 sym_signatureAlgorithm->getLocalSignatureSize = sym_getSignatureSize_sp_basic256;
112179 sym_signatureAlgorithm->getRemoteSignatureSize = sym_getSignatureSize_sp_basic256;
112180 sym_signatureAlgorithm->getLocalKeyLength =
112181 (size_t (*)(const void *))sym_getSigningKeyLength_sp_basic256;
112182 sym_signatureAlgorithm->getRemoteKeyLength =
112183 (size_t (*)(const void *))sym_getSigningKeyLength_sp_basic256;
112184
112185 UA_SecurityPolicyEncryptionAlgorithm *sym_encryptionAlgorithm =
112186 &symmetricModule->cryptoModule.encryptionAlgorithm;
112187 sym_encryptionAlgorithm->uri = UA_STRING("http://www.w3.org/2001/04/xmlenc#aes256-cbc\0");
112188 sym_encryptionAlgorithm->encrypt =
112189 (UA_StatusCode(*)(void *, UA_ByteString *))sym_encrypt_sp_basic256;
112190 sym_encryptionAlgorithm->decrypt =
112191 (UA_StatusCode(*)(void *, UA_ByteString *))sym_decrypt_sp_basic256;
112192 sym_encryptionAlgorithm->getLocalKeyLength = sym_getEncryptionKeyLength_sp_basic256;
112193 sym_encryptionAlgorithm->getRemoteKeyLength = sym_getEncryptionKeyLength_sp_basic256;
112194 sym_encryptionAlgorithm->getRemoteBlockSize =
112195 (size_t (*)(const void *))sym_getEncryptionBlockSize_sp_basic256;
112196 sym_encryptionAlgorithm->getRemotePlainTextBlockSize =
112197 (size_t (*)(const void *))sym_getPlainTextBlockSize_sp_basic256;
112198 symmetricModule->secureChannelNonceLength = 32;
112199
112200 // Use the same signature algorithm as the asymmetric component for certificate signing (see standard)
112201 policy->certificateSigningAlgorithm = policy->asymmetricModule.cryptoModule.signatureAlgorithm;
112202
112203 /* ChannelModule */
112204 channelModule->newContext = channelContext_newContext_sp_basic256;
112205 channelModule->deleteContext = (void (*)(void *))
112206 channelContext_deleteContext_sp_basic256;
112207
112208 channelModule->setLocalSymEncryptingKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
112209 channelContext_setLocalSymEncryptingKey_sp_basic256;
112210 channelModule->setLocalSymSigningKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
112211 channelContext_setLocalSymSigningKey_sp_basic256;
112212 channelModule->setLocalSymIv = (UA_StatusCode (*)(void *, const UA_ByteString *))
112213 channelContext_setLocalSymIv_sp_basic256;
112214
112215 channelModule->setRemoteSymEncryptingKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
112216 channelContext_setRemoteSymEncryptingKey_sp_basic256;
112217 channelModule->setRemoteSymSigningKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
112218 channelContext_setRemoteSymSigningKey_sp_basic256;
112219 channelModule->setRemoteSymIv = (UA_StatusCode (*)(void *, const UA_ByteString *))
112220 channelContext_setRemoteSymIv_sp_basic256;
112221
112222 channelModule->compareCertificate = (UA_StatusCode (*)(const void *, const UA_ByteString *))
112223 channelContext_compareCertificate_sp_basic256;
112224
112225 policy->updateCertificateAndPrivateKey = updateCertificateAndPrivateKey_sp_basic256;
112226 policy->clear = clear_sp_basic256;
112227
112228 UA_StatusCode res = policyContext_newContext_sp_basic256(policy, localPrivateKey);
112229 if(res != UA_STATUSCODE_GOOD)
112230 clear_sp_basic256(policy);
112231
112232 return res;
112233}
112234
112235#endif
112236
112237/**** amalgamated original file "/plugins/crypto/mbedtls/ua_securitypolicy_basic256sha256.c" ****/
112238
112239/* This Source Code Form is subject to the terms of the Mozilla Public
112240 * License, v. 2.0. If a copy of the MPL was not distributed with this
112241 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
112242 *
112243 * Copyright 2018 (c) Mark Giraud, Fraunhofer IOSB
112244 * Copyright 2018 (c) Daniel Feist, Precitec GmbH & Co. KG
112245 * Copyright 2018 (c) HMS Industrial Networks AB (Author: Jonas Green)
112246 * Copyright 2020 (c) Wind River Systems, Inc.
112247 * Copyright 2020 (c) basysKom GmbH
112248 */
112249
112250
112251#ifdef UA_ENABLE_ENCRYPTION_MBEDTLS
112252
112253
112254#include <mbedtls/aes.h>
112255#include <mbedtls/ctr_drbg.h>
112256#include <mbedtls/entropy.h>
112257#include <mbedtls/error.h>
112258#include <mbedtls/md.h>
112259#include <mbedtls/sha1.h>
112260#include <mbedtls/sha256.h>
112261#include <mbedtls/version.h>
112262#include <mbedtls/x509_crt.h>
112263
112264/* Notes:
112265 * mbedTLS' AES allows in-place encryption and decryption. Sow we don't have to
112266 * allocate temp buffers.
112267 * https://tls.mbed.org/discussions/generic/in-place-decryption-with-aes256-same-input-output-buffer
112268 */
112269
112270#define UA_SECURITYPOLICY_BASIC256SHA256_RSAPADDING_LEN 42
112271#define UA_SHA1_LENGTH 20
112272#define UA_SHA256_LENGTH 32
112273#define UA_BASIC256SHA256_SYM_SIGNING_KEY_LENGTH 32
112274#define UA_SECURITYPOLICY_BASIC256SHA256_SYM_KEY_LENGTH 32
112275#define UA_SECURITYPOLICY_BASIC256SHA256_SYM_ENCRYPTION_BLOCK_SIZE 16
112276#define UA_SECURITYPOLICY_BASIC256SHA256_SYM_PLAIN_TEXT_BLOCK_SIZE 16
112277#define UA_SECURITYPOLICY_BASIC256SHA256_MINASYMKEYLENGTH 256
112278#define UA_SECURITYPOLICY_BASIC256SHA256_MAXASYMKEYLENGTH 512
112279
112280typedef struct {
112281 UA_ByteString localCertThumbprint;
112282
112283 mbedtls_ctr_drbg_context drbgContext;
112284 mbedtls_entropy_context entropyContext;
112285 mbedtls_md_context_t sha256MdContext;
112286 mbedtls_pk_context localPrivateKey;
112287} Basic256Sha256_PolicyContext;
112288
112289typedef struct {
112290 Basic256Sha256_PolicyContext *policyContext;
112291
112292 UA_ByteString localSymSigningKey;
112293 UA_ByteString localSymEncryptingKey;
112294 UA_ByteString localSymIv;
112295
112296 UA_ByteString remoteSymSigningKey;
112297 UA_ByteString remoteSymEncryptingKey;
112298 UA_ByteString remoteSymIv;
112299
112300 mbedtls_x509_crt remoteCertificate;
112301} Basic256Sha256_ChannelContext;
112302
112303/********************/
112304/* AsymmetricModule */
112305/********************/
112306
112307/* VERIFY AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256 */
112308static UA_StatusCode
112309asym_verify_sp_basic256sha256(Basic256Sha256_ChannelContext *cc,
112310 const UA_ByteString *message,
112311 const UA_ByteString *signature) {
112312 if(message == NULL || signature == NULL || cc == NULL)
112313 return UA_STATUSCODE_BADINTERNALERROR;
112314
112315 unsigned char hash[UA_SHA256_LENGTH];
112316#if MBEDTLS_VERSION_NUMBER >= 0x02070000 && MBEDTLS_VERSION_NUMBER < 0x03000000
112317 // TODO check return status
112318 mbedtls_sha256_ret(message->data, message->length, hash, 0);
112319#else
112320 mbedtls_sha256(message->data, message->length, hash, 0);
112321#endif
112322
112323 /* Set the RSA settings */
112324 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
112325 mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA256);
112326
112327 /* For RSA keys, the default padding type is PKCS#1 v1.5 in mbedtls_pk_verify() */
112328 /* Alternatively, use more specific function mbedtls_rsa_rsassa_pkcs1_v15_verify(), i.e. */
112329 /* int mbedErr = mbedtls_rsa_rsassa_pkcs1_v15_verify(rsaContext, NULL, NULL,
112330 MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256,
112331 UA_SHA256_LENGTH, hash,
112332 signature->data); */
112333 int mbedErr = mbedtls_pk_verify(&cc->remoteCertificate.pk,
112334 MBEDTLS_MD_SHA256, hash, UA_SHA256_LENGTH,
112335 signature->data, signature->length);
112336
112337 if(mbedErr)
112338 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112339 return UA_STATUSCODE_GOOD;
112340}
112341
112342/* AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256 */
112343static UA_StatusCode
112344asym_sign_sp_basic256sha256(Basic256Sha256_ChannelContext *cc,
112345 const UA_ByteString *message,
112346 UA_ByteString *signature) {
112347 if(message == NULL || signature == NULL || cc == NULL)
112348 return UA_STATUSCODE_BADINTERNALERROR;
112349
112350 unsigned char hash[UA_SHA256_LENGTH];
112351#if MBEDTLS_VERSION_NUMBER >= 0x02070000 && MBEDTLS_VERSION_NUMBER < 0x03000000
112352 // TODO check return status
112353 mbedtls_sha256_ret(message->data, message->length, hash, 0);
112354#else
112355 mbedtls_sha256(message->data, message->length, hash, 0);
112356#endif
112357
112358 Basic256Sha256_PolicyContext *pc = cc->policyContext;
112359 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(pc->localPrivateKey);
112360 mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA256);
112361
112362 size_t sigLen = 0;
112363
112364 /* For RSA keys, the default padding type is PKCS#1 v1.5 in mbedtls_pk_sign */
112365 /* Alternatively use more specific function mbedtls_rsa_rsassa_pkcs1_v15_sign() */
112366 int mbedErr = mbedtls_pk_sign(&pc->localPrivateKey,
112367 MBEDTLS_MD_SHA256, hash,
112368 UA_SHA256_LENGTH, signature->data,
112369#if MBEDTLS_VERSION_NUMBER >= 0x03000000
112370 signature->length,
112371#endif
112372 &sigLen, mbedtls_ctr_drbg_random,
112373 &pc->drbgContext);
112374 if(mbedErr)
112375 return UA_STATUSCODE_BADINTERNALERROR;
112376 return UA_STATUSCODE_GOOD;
112377}
112378
112379static size_t
112380asym_getLocalSignatureSize_sp_basic256sha256(const Basic256Sha256_ChannelContext *cc) {
112381 if(cc == NULL)
112382 return 0;
112383#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
112384 return mbedtls_pk_rsa(cc->policyContext->localPrivateKey)->len;
112385#else
112386 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->policyContext->localPrivateKey));
112387#endif
112388}
112389
112390static size_t
112391asym_getRemoteSignatureSize_sp_basic256sha256(const Basic256Sha256_ChannelContext *cc) {
112392 if(cc == NULL)
112393 return 0;
112394#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
112395 return mbedtls_pk_rsa(cc->remoteCertificate.pk)->len;
112396#else
112397 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
112398#endif
112399}
112400
112401static size_t
112402asym_getRemoteBlockSize_sp_basic256sha256(const Basic256Sha256_ChannelContext *cc) {
112403 if(cc == NULL)
112404 return 0;
112405#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
112406 mbedtls_rsa_context *const rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
112407 return rsaContext->len;
112408#else
112409 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
112410#endif
112411}
112412
112413static size_t
112414asym_getRemotePlainTextBlockSize_sp_basic256sha256(const Basic256Sha256_ChannelContext *cc) {
112415 if(cc == NULL)
112416 return 0;
112417#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
112418 mbedtls_rsa_context *const rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
112419 return rsaContext->len - UA_SECURITYPOLICY_BASIC256SHA256_RSAPADDING_LEN;
112420#else
112421 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk)) -
112422 UA_SECURITYPOLICY_BASIC256SHA256_RSAPADDING_LEN;
112423#endif
112424}
112425
112426
112427/* AsymmetricEncryptionAlgorithm_RSA-OAEP-SHA1 */
112428static UA_StatusCode
112429asym_encrypt_sp_basic256sha256(Basic256Sha256_ChannelContext *cc,
112430 UA_ByteString *data) {
112431 if(cc == NULL || data == NULL)
112432 return UA_STATUSCODE_BADINTERNALERROR;
112433
112434 const size_t plainTextBlockSize = asym_getRemotePlainTextBlockSize_sp_basic256sha256(cc);
112435
112436 mbedtls_rsa_context *remoteRsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
112437 mbedtls_rsa_set_padding(remoteRsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1);
112438
112439 return mbedtls_encrypt_rsaOaep(remoteRsaContext, &cc->policyContext->drbgContext,
112440 data, plainTextBlockSize);
112441}
112442
112443/* AsymmetricEncryptionAlgorithm_RSA-OAEP-SHA1 */
112444static UA_StatusCode
112445asym_decrypt_sp_basic256sha256(Basic256Sha256_ChannelContext *cc,
112446 UA_ByteString *data) {
112447 if(cc == NULL || data == NULL)
112448 return UA_STATUSCODE_BADINTERNALERROR;
112449 return mbedtls_decrypt_rsaOaep(&cc->policyContext->localPrivateKey,
112450 &cc->policyContext->drbgContext, data, MBEDTLS_MD_SHA1);
112451}
112452
112453static size_t
112454asym_getLocalEncryptionKeyLength_sp_basic256sha256(const Basic256Sha256_ChannelContext *cc) {
112455 return mbedtls_pk_get_len(&cc->policyContext->localPrivateKey) * 8;
112456}
112457
112458static size_t
112459asym_getRemoteEncryptionKeyLength_sp_basic256sha256(const Basic256Sha256_ChannelContext *cc) {
112460 return mbedtls_pk_get_len(&cc->remoteCertificate.pk) * 8;
112461}
112462
112463static UA_StatusCode
112464asym_makeThumbprint_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
112465 const UA_ByteString *certificate,
112466 UA_ByteString *thumbprint) {
112467 if(securityPolicy == NULL || certificate == NULL || thumbprint == NULL)
112468 return UA_STATUSCODE_BADINTERNALERROR;
112469 return mbedtls_thumbprint_sha1(certificate, thumbprint);
112470}
112471
112472static UA_StatusCode
112473asymmetricModule_compareCertificateThumbprint_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
112474 const UA_ByteString *certificateThumbprint) {
112475 if(securityPolicy == NULL || certificateThumbprint == NULL)
112476 return UA_STATUSCODE_BADINTERNALERROR;
112477
112478 Basic256Sha256_PolicyContext *pc = (Basic256Sha256_PolicyContext *)securityPolicy->policyContext;
112479 if(!UA_ByteString_equal(certificateThumbprint, &pc->localCertThumbprint))
112480 return UA_STATUSCODE_BADCERTIFICATEINVALID;
112481
112482 return UA_STATUSCODE_GOOD;
112483}
112484
112485/*******************/
112486/* SymmetricModule */
112487/*******************/
112488
112489static UA_StatusCode
112490sym_verify_sp_basic256sha256(Basic256Sha256_ChannelContext *cc,
112491 const UA_ByteString *message,
112492 const UA_ByteString *signature) {
112493 if(cc == NULL || message == NULL || signature == NULL)
112494 return UA_STATUSCODE_BADINTERNALERROR;
112495
112496 /* Compute MAC */
112497 if(signature->length != UA_SHA256_LENGTH)
112498 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112499
112500 Basic256Sha256_PolicyContext *pc = cc->policyContext;
112501 unsigned char mac[UA_SHA256_LENGTH];
112502 mbedtls_hmac(&pc->sha256MdContext, &cc->remoteSymSigningKey, message, mac);
112503
112504 /* Compare with Signature */
112505 if(!UA_constantTimeEqual(signature->data, mac, UA_SHA256_LENGTH))
112506 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112507 return UA_STATUSCODE_GOOD;
112508}
112509
112510static UA_StatusCode
112511sym_sign_sp_basic256sha256(const Basic256Sha256_ChannelContext *cc,
112512 const UA_ByteString *message,
112513 UA_ByteString *signature) {
112514 if(signature->length != UA_SHA256_LENGTH)
112515 return UA_STATUSCODE_BADINTERNALERROR;
112516
112517 mbedtls_hmac(&cc->policyContext->sha256MdContext, &cc->localSymSigningKey,
112518 message, signature->data);
112519 return UA_STATUSCODE_GOOD;
112520}
112521
112522static size_t
112523sym_getSignatureSize_sp_basic256sha256(const void *channelContext) {
112524 return UA_SHA256_LENGTH;
112525}
112526
112527static size_t
112528sym_getSigningKeyLength_sp_basic256sha256(const void *channelContext) {
112529 return UA_BASIC256SHA256_SYM_SIGNING_KEY_LENGTH;
112530}
112531
112532static size_t
112533sym_getEncryptionKeyLength_sp_basic256sha256(const void *channelContext) {
112534 return UA_SECURITYPOLICY_BASIC256SHA256_SYM_KEY_LENGTH;
112535}
112536
112537static size_t
112538sym_getEncryptionBlockSize_sp_basic256sha256(const void *channelContext) {
112539 return UA_SECURITYPOLICY_BASIC256SHA256_SYM_ENCRYPTION_BLOCK_SIZE;
112540}
112541
112542static size_t
112543sym_getPlainTextBlockSize_sp_basic256sha256(const void *channelContext) {
112544 return UA_SECURITYPOLICY_BASIC256SHA256_SYM_PLAIN_TEXT_BLOCK_SIZE;
112545}
112546
112547static UA_StatusCode
112548sym_encrypt_sp_basic256sha256(const Basic256Sha256_ChannelContext *cc,
112549 UA_ByteString *data) {
112550 if(cc == NULL || data == NULL)
112551 return UA_STATUSCODE_BADINTERNALERROR;
112552
112553 if(cc->localSymIv.length != UA_SECURITYPOLICY_BASIC256SHA256_SYM_ENCRYPTION_BLOCK_SIZE)
112554 return UA_STATUSCODE_BADINTERNALERROR;
112555
112556 size_t plainTextBlockSize = UA_SECURITYPOLICY_BASIC256SHA256_SYM_PLAIN_TEXT_BLOCK_SIZE;
112557
112558 if(data->length % plainTextBlockSize != 0)
112559 return UA_STATUSCODE_BADINTERNALERROR;
112560
112561 /* Keylength in bits */
112562 unsigned int keylength = (unsigned int)(cc->localSymEncryptingKey.length * 8);
112563 mbedtls_aes_context aesContext;
112564 int mbedErr = mbedtls_aes_setkey_enc(&aesContext, cc->localSymEncryptingKey.data, keylength);
112565 if(mbedErr)
112566 return UA_STATUSCODE_BADINTERNALERROR;
112567
112568 UA_ByteString ivCopy;
112569 UA_StatusCode retval = UA_ByteString_copy(&cc->localSymIv, &ivCopy);
112570 if(retval != UA_STATUSCODE_GOOD)
112571 return retval;
112572
112573 mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_ENCRYPT, data->length,
112574 ivCopy.data, data->data, data->data);
112575 if(mbedErr)
112576 retval = UA_STATUSCODE_BADINTERNALERROR;
112577 UA_ByteString_clear(&ivCopy);
112578 return retval;
112579}
112580
112581static UA_StatusCode
112582sym_decrypt_sp_basic256sha256(const Basic256Sha256_ChannelContext *cc,
112583 UA_ByteString *data) {
112584 if(cc == NULL || data == NULL)
112585 return UA_STATUSCODE_BADINTERNALERROR;
112586
112587 size_t encryptionBlockSize = UA_SECURITYPOLICY_BASIC256SHA256_SYM_ENCRYPTION_BLOCK_SIZE;
112588 if(cc->remoteSymIv.length != encryptionBlockSize)
112589 return UA_STATUSCODE_BADINTERNALERROR;
112590
112591 if(data->length % encryptionBlockSize != 0)
112592 return UA_STATUSCODE_BADINTERNALERROR;
112593
112594 unsigned int keylength = (unsigned int)(cc->remoteSymEncryptingKey.length * 8);
112595 mbedtls_aes_context aesContext;
112596 int mbedErr = mbedtls_aes_setkey_dec(&aesContext, cc->remoteSymEncryptingKey.data, keylength);
112597 if(mbedErr)
112598 return UA_STATUSCODE_BADINTERNALERROR;
112599
112600 UA_ByteString ivCopy;
112601 UA_StatusCode retval = UA_ByteString_copy(&cc->remoteSymIv, &ivCopy);
112602 if(retval != UA_STATUSCODE_GOOD)
112603 return retval;
112604
112605 mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_DECRYPT, data->length,
112606 ivCopy.data, data->data, data->data);
112607 if(mbedErr)
112608 retval = UA_STATUSCODE_BADINTERNALERROR;
112609 UA_ByteString_clear(&ivCopy);
112610 return retval;
112611}
112612
112613static UA_StatusCode
112614sym_generateKey_sp_basic256sha256(void *policyContext, const UA_ByteString *secret,
112615 const UA_ByteString *seed, UA_ByteString *out) {
112616 if(secret == NULL || seed == NULL || out == NULL)
112617 return UA_STATUSCODE_BADINTERNALERROR;
112618 Basic256Sha256_PolicyContext *pc = (Basic256Sha256_PolicyContext *)policyContext;
112619 return mbedtls_generateKey(&pc->sha256MdContext, secret, seed, out);
112620}
112621
112622static UA_StatusCode
112623sym_generateNonce_sp_basic256sha256(void *policyContext, UA_ByteString *out) {
112624 if(out == NULL)
112625 return UA_STATUSCODE_BADINTERNALERROR;
112626 Basic256Sha256_PolicyContext *pc = (Basic256Sha256_PolicyContext *)policyContext;
112627 int mbedErr = mbedtls_ctr_drbg_random(&pc->drbgContext, out->data, out->length);
112628 if(mbedErr)
112629 return UA_STATUSCODE_BADUNEXPECTEDERROR;
112630 return UA_STATUSCODE_GOOD;
112631}
112632
112633/*****************/
112634/* ChannelModule */
112635/*****************/
112636
112637/* Assumes that the certificate has been verified externally */
112638static UA_StatusCode
112639parseRemoteCertificate_sp_basic256sha256(Basic256Sha256_ChannelContext *cc,
112640 const UA_ByteString *remoteCertificate) {
112641 if(remoteCertificate == NULL || cc == NULL)
112642 return UA_STATUSCODE_BADINTERNALERROR;
112643
112644 /* Parse the certificate */
112645 int mbedErr = mbedtls_x509_crt_parse(&cc->remoteCertificate, remoteCertificate->data,
112646 remoteCertificate->length);
112647 if(mbedErr)
112648 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112649
112650 /* Check the key length */
112651#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
112652 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
112653 size_t keylen = rsaContext->len;
112654#else
112655 size_t keylen = mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
112656#endif
112657 if(keylen < UA_SECURITYPOLICY_BASIC256SHA256_MINASYMKEYLENGTH ||
112658 keylen > UA_SECURITYPOLICY_BASIC256SHA256_MAXASYMKEYLENGTH)
112659 return UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED;
112660
112661 return UA_STATUSCODE_GOOD;
112662}
112663
112664static void
112665channelContext_deleteContext_sp_basic256sha256(Basic256Sha256_ChannelContext *cc) {
112666 UA_ByteString_clear(&cc->localSymSigningKey);
112667 UA_ByteString_clear(&cc->localSymEncryptingKey);
112668 UA_ByteString_clear(&cc->localSymIv);
112669
112670 UA_ByteString_clear(&cc->remoteSymSigningKey);
112671 UA_ByteString_clear(&cc->remoteSymEncryptingKey);
112672 UA_ByteString_clear(&cc->remoteSymIv);
112673
112674 mbedtls_x509_crt_free(&cc->remoteCertificate);
112675
112676 UA_free(cc);
112677}
112678
112679static UA_StatusCode
112680channelContext_newContext_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy,
112681 const UA_ByteString *remoteCertificate,
112682 void **pp_contextData) {
112683 if(securityPolicy == NULL || remoteCertificate == NULL || pp_contextData == NULL)
112684 return UA_STATUSCODE_BADINTERNALERROR;
112685
112686 /* Allocate the channel context */
112687 *pp_contextData = UA_malloc(sizeof(Basic256Sha256_ChannelContext));
112688 if(*pp_contextData == NULL)
112689 return UA_STATUSCODE_BADOUTOFMEMORY;
112690
112691 Basic256Sha256_ChannelContext *cc = (Basic256Sha256_ChannelContext *)*pp_contextData;
112692
112693 /* Initialize the channel context */
112694 cc->policyContext = (Basic256Sha256_PolicyContext *)securityPolicy->policyContext;
112695
112696 UA_ByteString_init(&cc->localSymSigningKey);
112697 UA_ByteString_init(&cc->localSymEncryptingKey);
112698 UA_ByteString_init(&cc->localSymIv);
112699
112700 UA_ByteString_init(&cc->remoteSymSigningKey);
112701 UA_ByteString_init(&cc->remoteSymEncryptingKey);
112702 UA_ByteString_init(&cc->remoteSymIv);
112703
112704 mbedtls_x509_crt_init(&cc->remoteCertificate);
112705
112706 // TODO: this can be optimized so that we dont allocate memory before parsing the certificate
112707 UA_StatusCode retval = parseRemoteCertificate_sp_basic256sha256(cc, remoteCertificate);
112708 if(retval != UA_STATUSCODE_GOOD) {
112709 channelContext_deleteContext_sp_basic256sha256(cc);
112710 *pp_contextData = NULL;
112711 }
112712 return retval;
112713}
112714
112715static UA_StatusCode
112716channelContext_setLocalSymEncryptingKey_sp_basic256sha256(Basic256Sha256_ChannelContext *cc,
112717 const UA_ByteString *key) {
112718 if(key == NULL || cc == NULL)
112719 return UA_STATUSCODE_BADINTERNALERROR;
112720
112721 UA_ByteString_clear(&cc->localSymEncryptingKey);
112722 return UA_ByteString_copy(key, &cc->localSymEncryptingKey);
112723}
112724
112725static UA_StatusCode
112726channelContext_setLocalSymSigningKey_sp_basic256sha256(Basic256Sha256_ChannelContext *cc,
112727 const UA_ByteString *key) {
112728 if(key == NULL || cc == NULL)
112729 return UA_STATUSCODE_BADINTERNALERROR;
112730
112731 UA_ByteString_clear(&cc->localSymSigningKey);
112732 return UA_ByteString_copy(key, &cc->localSymSigningKey);
112733}
112734
112735
112736static UA_StatusCode
112737channelContext_setLocalSymIv_sp_basic256sha256(Basic256Sha256_ChannelContext *cc,
112738 const UA_ByteString *iv) {
112739 if(iv == NULL || cc == NULL)
112740 return UA_STATUSCODE_BADINTERNALERROR;
112741
112742 UA_ByteString_clear(&cc->localSymIv);
112743 return UA_ByteString_copy(iv, &cc->localSymIv);
112744}
112745
112746static UA_StatusCode
112747channelContext_setRemoteSymEncryptingKey_sp_basic256sha256(Basic256Sha256_ChannelContext *cc,
112748 const UA_ByteString *key) {
112749 if(key == NULL || cc == NULL)
112750 return UA_STATUSCODE_BADINTERNALERROR;
112751
112752 UA_ByteString_clear(&cc->remoteSymEncryptingKey);
112753 return UA_ByteString_copy(key, &cc->remoteSymEncryptingKey);
112754}
112755
112756static UA_StatusCode
112757channelContext_setRemoteSymSigningKey_sp_basic256sha256(Basic256Sha256_ChannelContext *cc,
112758 const UA_ByteString *key) {
112759 if(key == NULL || cc == NULL)
112760 return UA_STATUSCODE_BADINTERNALERROR;
112761
112762 UA_ByteString_clear(&cc->remoteSymSigningKey);
112763 return UA_ByteString_copy(key, &cc->remoteSymSigningKey);
112764}
112765
112766static UA_StatusCode
112767channelContext_setRemoteSymIv_sp_basic256sha256(Basic256Sha256_ChannelContext *cc,
112768 const UA_ByteString *iv) {
112769 if(iv == NULL || cc == NULL)
112770 return UA_STATUSCODE_BADINTERNALERROR;
112771
112772 UA_ByteString_clear(&cc->remoteSymIv);
112773 return UA_ByteString_copy(iv, &cc->remoteSymIv);
112774}
112775
112776static UA_StatusCode
112777channelContext_compareCertificate_sp_basic256sha256(const Basic256Sha256_ChannelContext *cc,
112778 const UA_ByteString *certificate) {
112779 if(cc == NULL || certificate == NULL)
112780 return UA_STATUSCODE_BADINTERNALERROR;
112781
112782 mbedtls_x509_crt cert;
112783 mbedtls_x509_crt_init(&cert);
112784 int mbedErr = mbedtls_x509_crt_parse(&cert, certificate->data, certificate->length);
112785 if(mbedErr)
112786 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112787
112788 UA_StatusCode retval = UA_STATUSCODE_GOOD;
112789 if(cert.raw.len != cc->remoteCertificate.raw.len ||
112790 memcmp(cert.raw.p, cc->remoteCertificate.raw.p, cert.raw.len) != 0)
112791 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112792
112793 mbedtls_x509_crt_free(&cert);
112794 return retval;
112795}
112796
112797static void
112798clear_sp_basic256sha256(UA_SecurityPolicy *securityPolicy) {
112799 if(securityPolicy == NULL)
112800 return;
112801
112802 UA_ByteString_clear(&securityPolicy->localCertificate);
112803
112804 if(securityPolicy->policyContext == NULL)
112805 return;
112806
112807 /* delete all allocated members in the context */
112808 Basic256Sha256_PolicyContext *pc = (Basic256Sha256_PolicyContext *)
112809 securityPolicy->policyContext;
112810
112811 mbedtls_ctr_drbg_free(&pc->drbgContext);
112812 mbedtls_entropy_free(&pc->entropyContext);
112813 mbedtls_pk_free(&pc->localPrivateKey);
112814 mbedtls_md_free(&pc->sha256MdContext);
112815 UA_ByteString_clear(&pc->localCertThumbprint);
112816
112817 UA_LOG_DEBUG(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
112818 "Deleted members of EndpointContext for sp_basic256sha256");
112819
112820 UA_free(pc);
112821 securityPolicy->policyContext = NULL;
112822}
112823
112824static UA_StatusCode
112825updateCertificateAndPrivateKey_sp_basic256sha256(UA_SecurityPolicy *securityPolicy,
112826 const UA_ByteString newCertificate,
112827 const UA_ByteString newPrivateKey) {
112828 if(securityPolicy == NULL)
112829 return UA_STATUSCODE_BADINTERNALERROR;
112830
112831 if(securityPolicy->policyContext == NULL)
112832 return UA_STATUSCODE_BADINTERNALERROR;
112833
112834 Basic256Sha256_PolicyContext *pc =
112835 (Basic256Sha256_PolicyContext *) securityPolicy->policyContext;
112836
112837 UA_ByteString_clear(&securityPolicy->localCertificate);
112838
112839 UA_StatusCode retval = UA_mbedTLS_LoadLocalCertificate(&newCertificate, &securityPolicy->localCertificate);
112840
112841 if (retval != UA_STATUSCODE_GOOD)
112842 return retval;
112843
112844 /* Set the new private key */
112845 mbedtls_pk_free(&pc->localPrivateKey);
112846 mbedtls_pk_init(&pc->localPrivateKey);
112847 int mbedErr = UA_mbedTLS_LoadPrivateKey(&newPrivateKey, &pc->localPrivateKey, &pc->entropyContext);
112848 if(mbedErr) {
112849 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112850 goto error;
112851 }
112852
112853 retval = asym_makeThumbprint_sp_basic256sha256(securityPolicy,
112854 &securityPolicy->localCertificate,
112855 &pc->localCertThumbprint);
112856 if(retval != UA_STATUSCODE_GOOD)
112857 goto error;
112858
112859 return retval;
112860
112861 error:
112862 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
112863 "Could not update certificate and private key");
112864 if(securityPolicy->policyContext != NULL)
112865 clear_sp_basic256sha256(securityPolicy);
112866 return retval;
112867}
112868
112869static UA_StatusCode
112870policyContext_newContext_sp_basic256sha256(UA_SecurityPolicy *securityPolicy,
112871 const UA_ByteString localPrivateKey) {
112872 UA_StatusCode retval = UA_STATUSCODE_GOOD;
112873 if(securityPolicy == NULL)
112874 return UA_STATUSCODE_BADINTERNALERROR;
112875
112876 if (localPrivateKey.length == 0) {
112877 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
112878 "Can not initialize security policy. Private key is empty.");
112879 return UA_STATUSCODE_BADINVALIDARGUMENT;
112880 }
112881
112882 Basic256Sha256_PolicyContext *pc = (Basic256Sha256_PolicyContext *)
112883 UA_malloc(sizeof(Basic256Sha256_PolicyContext));
112884 securityPolicy->policyContext = (void *)pc;
112885 if(!pc) {
112886 retval = UA_STATUSCODE_BADOUTOFMEMORY;
112887 goto error;
112888 }
112889
112890 /* Initialize the PolicyContext */
112891 memset(pc, 0, sizeof(Basic256Sha256_PolicyContext));
112892 mbedtls_ctr_drbg_init(&pc->drbgContext);
112893 mbedtls_entropy_init(&pc->entropyContext);
112894 mbedtls_pk_init(&pc->localPrivateKey);
112895 mbedtls_md_init(&pc->sha256MdContext);
112896
112897 /* Initialized the message digest */
112898 const mbedtls_md_info_t *const mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
112899 int mbedErr = mbedtls_md_setup(&pc->sha256MdContext, mdInfo, MBEDTLS_MD_SHA256);
112900 if(mbedErr) {
112901 retval = UA_STATUSCODE_BADOUTOFMEMORY;
112902 goto error;
112903 }
112904
112905 mbedErr = mbedtls_entropy_self_test(0);
112906
112907 if(mbedErr) {
112908 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112909 goto error;
112910 }
112911
112912 /* Seed the RNG */
112913 char *personalization = "open62541-drbg";
112914 mbedErr = mbedtls_ctr_drbg_seed(&pc->drbgContext, mbedtls_entropy_func,
112915 &pc->entropyContext,
112916 (const unsigned char *)personalization, 14);
112917 if(mbedErr) {
112918 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112919 goto error;
112920 }
112921
112922 /* Set the private key */
112923 mbedErr = UA_mbedTLS_LoadPrivateKey(&localPrivateKey, &pc->localPrivateKey, &pc->entropyContext);
112924 if(mbedErr) {
112925 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
112926 goto error;
112927 }
112928
112929 /* Set the local certificate thumbprint */
112930 retval = UA_ByteString_allocBuffer(&pc->localCertThumbprint, UA_SHA1_LENGTH);
112931 if(retval != UA_STATUSCODE_GOOD)
112932 goto error;
112933 retval = asym_makeThumbprint_sp_basic256sha256(securityPolicy,
112934 &securityPolicy->localCertificate,
112935 &pc->localCertThumbprint);
112936 if(retval != UA_STATUSCODE_GOOD)
112937 goto error;
112938
112939 return UA_STATUSCODE_GOOD;
112940
112941error:
112942 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
112943 "Could not create securityContext: %s", UA_StatusCode_name(retval));
112944 if(securityPolicy->policyContext != NULL)
112945 clear_sp_basic256sha256(securityPolicy);
112946 return retval;
112947}
112948
112949UA_StatusCode
112950UA_SecurityPolicy_Basic256Sha256(UA_SecurityPolicy *policy, const UA_ByteString localCertificate,
112951 const UA_ByteString localPrivateKey, const UA_Logger *logger) {
112952 memset(policy, 0, sizeof(UA_SecurityPolicy));
112953 policy->logger = logger;
112954
112955 policy->policyUri = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256");
112956
112957 UA_SecurityPolicyAsymmetricModule *const asymmetricModule = &policy->asymmetricModule;
112958 UA_SecurityPolicySymmetricModule *const symmetricModule = &policy->symmetricModule;
112959 UA_SecurityPolicyChannelModule *const channelModule = &policy->channelModule;
112960
112961 UA_StatusCode retval = UA_mbedTLS_LoadLocalCertificate(&localCertificate, &policy->localCertificate);
112962
112963 if (retval != UA_STATUSCODE_GOOD)
112964 return retval;
112965
112966 /* AsymmetricModule */
112967 UA_SecurityPolicySignatureAlgorithm *asym_signatureAlgorithm =
112968 &asymmetricModule->cryptoModule.signatureAlgorithm;
112969 asym_signatureAlgorithm->uri =
112970 UA_STRING("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\0");
112971 asym_signatureAlgorithm->verify =
112972 (UA_StatusCode (*)(void *, const UA_ByteString *, const UA_ByteString *))asym_verify_sp_basic256sha256;
112973 asym_signatureAlgorithm->sign =
112974 (UA_StatusCode (*)(void *, const UA_ByteString *, UA_ByteString *))asym_sign_sp_basic256sha256;
112975 asym_signatureAlgorithm->getLocalSignatureSize =
112976 (size_t (*)(const void *))asym_getLocalSignatureSize_sp_basic256sha256;
112977 asym_signatureAlgorithm->getRemoteSignatureSize =
112978 (size_t (*)(const void *))asym_getRemoteSignatureSize_sp_basic256sha256;
112979 asym_signatureAlgorithm->getLocalKeyLength = NULL; // TODO: Write function
112980 asym_signatureAlgorithm->getRemoteKeyLength = NULL; // TODO: Write function
112981
112982 UA_SecurityPolicyEncryptionAlgorithm *asym_encryptionAlgorithm =
112983 &asymmetricModule->cryptoModule.encryptionAlgorithm;
112984 asym_encryptionAlgorithm->uri = UA_STRING("http://www.w3.org/2001/04/xmlenc#rsa-oaep\0");
112985 asym_encryptionAlgorithm->encrypt =
112986 (UA_StatusCode(*)(void *, UA_ByteString *))asym_encrypt_sp_basic256sha256;
112987 asym_encryptionAlgorithm->decrypt =
112988 (UA_StatusCode(*)(void *, UA_ByteString *))
112989 asym_decrypt_sp_basic256sha256;
112990 asym_encryptionAlgorithm->getLocalKeyLength =
112991 (size_t (*)(const void *))asym_getLocalEncryptionKeyLength_sp_basic256sha256;
112992 asym_encryptionAlgorithm->getRemoteKeyLength =
112993 (size_t (*)(const void *))asym_getRemoteEncryptionKeyLength_sp_basic256sha256;
112994 asym_encryptionAlgorithm->getRemoteBlockSize =
112995 (size_t (*)(const void *))asym_getRemoteBlockSize_sp_basic256sha256;
112996 asym_encryptionAlgorithm->getRemotePlainTextBlockSize =
112997 (size_t (*)(const void *))asym_getRemotePlainTextBlockSize_sp_basic256sha256;
112998
112999 asymmetricModule->makeCertificateThumbprint = asym_makeThumbprint_sp_basic256sha256;
113000 asymmetricModule->compareCertificateThumbprint =
113001 asymmetricModule_compareCertificateThumbprint_sp_basic256sha256;
113002
113003 /* SymmetricModule */
113004 symmetricModule->generateKey = sym_generateKey_sp_basic256sha256;
113005 symmetricModule->generateNonce = sym_generateNonce_sp_basic256sha256;
113006
113007 UA_SecurityPolicySignatureAlgorithm *sym_signatureAlgorithm =
113008 &symmetricModule->cryptoModule.signatureAlgorithm;
113009 sym_signatureAlgorithm->uri =
113010 UA_STRING("http://www.w3.org/2000/09/xmldsig#hmac-sha2-256\0");
113011 sym_signatureAlgorithm->verify =
113012 (UA_StatusCode (*)(void *, const UA_ByteString *, const UA_ByteString *))sym_verify_sp_basic256sha256;
113013 sym_signatureAlgorithm->sign =
113014 (UA_StatusCode (*)(void *, const UA_ByteString *, UA_ByteString *))sym_sign_sp_basic256sha256;
113015 sym_signatureAlgorithm->getLocalSignatureSize = sym_getSignatureSize_sp_basic256sha256;
113016 sym_signatureAlgorithm->getRemoteSignatureSize = sym_getSignatureSize_sp_basic256sha256;
113017 sym_signatureAlgorithm->getLocalKeyLength =
113018 (size_t (*)(const void *))sym_getSigningKeyLength_sp_basic256sha256;
113019 sym_signatureAlgorithm->getRemoteKeyLength =
113020 (size_t (*)(const void *))sym_getSigningKeyLength_sp_basic256sha256;
113021
113022 UA_SecurityPolicyEncryptionAlgorithm *sym_encryptionAlgorithm =
113023 &symmetricModule->cryptoModule.encryptionAlgorithm;
113024 sym_encryptionAlgorithm->uri = UA_STRING("http://www.w3.org/2001/04/xmlenc#aes256-cbc");
113025 sym_encryptionAlgorithm->encrypt =
113026 (UA_StatusCode(*)(void *, UA_ByteString *))sym_encrypt_sp_basic256sha256;
113027 sym_encryptionAlgorithm->decrypt =
113028 (UA_StatusCode(*)(void *, UA_ByteString *))sym_decrypt_sp_basic256sha256;
113029 sym_encryptionAlgorithm->getLocalKeyLength = sym_getEncryptionKeyLength_sp_basic256sha256;
113030 sym_encryptionAlgorithm->getRemoteKeyLength = sym_getEncryptionKeyLength_sp_basic256sha256;
113031 sym_encryptionAlgorithm->getRemoteBlockSize =
113032 (size_t (*)(const void *))sym_getEncryptionBlockSize_sp_basic256sha256;
113033 sym_encryptionAlgorithm->getRemotePlainTextBlockSize =
113034 (size_t (*)(const void *))sym_getPlainTextBlockSize_sp_basic256sha256;
113035 symmetricModule->secureChannelNonceLength = 32;
113036
113037 // Use the same signature algorithm as the asymmetric component for certificate signing (see standard)
113038 policy->certificateSigningAlgorithm = policy->asymmetricModule.cryptoModule.signatureAlgorithm;
113039
113040 /* ChannelModule */
113041 channelModule->newContext = channelContext_newContext_sp_basic256sha256;
113042 channelModule->deleteContext = (void (*)(void *))
113043 channelContext_deleteContext_sp_basic256sha256;
113044
113045 channelModule->setLocalSymEncryptingKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
113046 channelContext_setLocalSymEncryptingKey_sp_basic256sha256;
113047 channelModule->setLocalSymSigningKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
113048 channelContext_setLocalSymSigningKey_sp_basic256sha256;
113049 channelModule->setLocalSymIv = (UA_StatusCode (*)(void *, const UA_ByteString *))
113050 channelContext_setLocalSymIv_sp_basic256sha256;
113051
113052 channelModule->setRemoteSymEncryptingKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
113053 channelContext_setRemoteSymEncryptingKey_sp_basic256sha256;
113054 channelModule->setRemoteSymSigningKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
113055 channelContext_setRemoteSymSigningKey_sp_basic256sha256;
113056 channelModule->setRemoteSymIv = (UA_StatusCode (*)(void *, const UA_ByteString *))
113057 channelContext_setRemoteSymIv_sp_basic256sha256;
113058
113059 channelModule->compareCertificate = (UA_StatusCode (*)(const void *, const UA_ByteString *))
113060 channelContext_compareCertificate_sp_basic256sha256;
113061
113062 policy->updateCertificateAndPrivateKey = updateCertificateAndPrivateKey_sp_basic256sha256;
113063 policy->clear = clear_sp_basic256sha256;
113064
113065 UA_StatusCode res = policyContext_newContext_sp_basic256sha256(policy, localPrivateKey);
113066 if(res != UA_STATUSCODE_GOOD)
113067 clear_sp_basic256sha256(policy);
113068
113069 return res;
113070}
113071
113072#endif
113073
113074/**** amalgamated original file "/plugins/crypto/mbedtls/ua_securitypolicy_aes128sha256rsaoaep.c" ****/
113075
113076/* This Source Code Form is subject to the terms of the Mozilla Public
113077 * License, v. 2.0. If a copy of the MPL was not distributed with this
113078 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
113079 *
113080 * Copyright 2018 (c) Mark Giraud, Fraunhofer IOSB
113081 * Copyright 2018 (c) Daniel Feist, Precitec GmbH & Co. KG
113082 * Copyright 2018 (c) HMS Industrial Networks AB (Author: Jonas Green)
113083 * Copyright 2020 (c) Wind River Systems, Inc.
113084 */
113085
113086
113087#ifdef UA_ENABLE_ENCRYPTION_MBEDTLS
113088
113089
113090#include <mbedtls/aes.h>
113091#include <mbedtls/ctr_drbg.h>
113092#include <mbedtls/entropy.h>
113093#include <mbedtls/error.h>
113094#include <mbedtls/md.h>
113095#include <mbedtls/sha1.h>
113096#include <mbedtls/sha256.h>
113097#include <mbedtls/version.h>
113098#include <mbedtls/x509_crt.h>
113099
113100/* Notes:
113101 * mbedTLS' AES allows in-place encryption and decryption. So we don't have to
113102 * allocate temp buffers.
113103 * https://tls.mbed.org/discussions/generic/in-place-decryption-with-aes256-same-input-output-buffer
113104 */
113105
113106#define UA_SECURITYPOLICY_AES128SHA256RSAOAEP_RSAPADDING_LEN 42
113107#define UA_SHA1_LENGTH 20
113108#define UA_SHA256_LENGTH 32
113109#define UA_AES128SHA256RSAOAEP_SYM_SIGNING_KEY_LENGTH 32
113110#define UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_KEY_LENGTH 16
113111#define UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_ENCRYPTION_BLOCK_SIZE 16
113112#define UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_PLAIN_TEXT_BLOCK_SIZE 16
113113#define UA_SECURITYPOLICY_AES128SHA256RSAOAEP_MINASYMKEYLENGTH 256
113114#define UA_SECURITYPOLICY_AES128SHA256RSAOAEP_MAXASYMKEYLENGTH 512
113115
113116typedef struct {
113117 UA_ByteString localCertThumbprint;
113118
113119 mbedtls_ctr_drbg_context drbgContext;
113120 mbedtls_entropy_context entropyContext;
113121 mbedtls_md_context_t sha256MdContext;
113122 mbedtls_pk_context localPrivateKey;
113123} Aes128Sha256PsaOaep_PolicyContext;
113124
113125typedef struct {
113126 Aes128Sha256PsaOaep_PolicyContext *policyContext;
113127
113128 UA_ByteString localSymSigningKey;
113129 UA_ByteString localSymEncryptingKey;
113130 UA_ByteString localSymIv;
113131
113132 UA_ByteString remoteSymSigningKey;
113133 UA_ByteString remoteSymEncryptingKey;
113134 UA_ByteString remoteSymIv;
113135
113136 mbedtls_x509_crt remoteCertificate;
113137} Aes128Sha256PsaOaep_ChannelContext;
113138
113139/********************/
113140/* AsymmetricModule */
113141/********************/
113142
113143/* VERIFY AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256 */
113144static UA_StatusCode
113145asym_verify_sp_aes128sha256rsaoaep(Aes128Sha256PsaOaep_ChannelContext *cc,
113146 const UA_ByteString *message,
113147 const UA_ByteString *signature) {
113148 if(message == NULL || signature == NULL || cc == NULL)
113149 return UA_STATUSCODE_BADINTERNALERROR;
113150
113151 unsigned char hash[UA_SHA256_LENGTH];
113152#if MBEDTLS_VERSION_NUMBER >= 0x02070000 && MBEDTLS_VERSION_NUMBER < 0x03000000
113153 // TODO check return status
113154 mbedtls_sha256_ret(message->data, message->length, hash, 0);
113155#else
113156 mbedtls_sha256(message->data, message->length, hash, 0);
113157#endif
113158
113159 /* Set the RSA settings */
113160 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
113161 mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA256);
113162
113163 /* For RSA keys, the default padding type is PKCS#1 v1.5 in mbedtls_pk_verify() */
113164 /* Alternatively, use more specific function mbedtls_rsa_rsassa_pkcs1_v15_verify(), i.e. */
113165 /* int mbedErr = mbedtls_rsa_rsassa_pkcs1_v15_verify(rsaContext, NULL, NULL,
113166 MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256,
113167 UA_SHA256_LENGTH, hash,
113168 signature->data); */
113169 int mbedErr = mbedtls_pk_verify(&cc->remoteCertificate.pk,
113170 MBEDTLS_MD_SHA256, hash, UA_SHA256_LENGTH,
113171 signature->data, signature->length);
113172
113173 if(mbedErr)
113174 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
113175 return UA_STATUSCODE_GOOD;
113176}
113177
113178/* AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256 */
113179static UA_StatusCode
113180asym_sign_sp_aes128sha256rsaoaep(Aes128Sha256PsaOaep_ChannelContext *cc,
113181 const UA_ByteString *message,
113182 UA_ByteString *signature) {
113183 if(message == NULL || signature == NULL || cc == NULL)
113184 return UA_STATUSCODE_BADINTERNALERROR;
113185
113186 unsigned char hash[UA_SHA256_LENGTH];
113187#if MBEDTLS_VERSION_NUMBER >= 0x02070000 && MBEDTLS_VERSION_NUMBER < 0x03000000
113188 // TODO check return status
113189 mbedtls_sha256_ret(message->data, message->length, hash, 0);
113190#else
113191 mbedtls_sha256(message->data, message->length, hash, 0);
113192#endif
113193
113194 Aes128Sha256PsaOaep_PolicyContext *pc = cc->policyContext;
113195 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(pc->localPrivateKey);
113196 mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA256);
113197
113198 size_t sigLen = 0;
113199
113200 /* For RSA keys, the default padding type is PKCS#1 v1.5 in mbedtls_pk_sign */
113201 /* Alternatively use more specific function mbedtls_rsa_rsassa_pkcs1_v15_sign() */
113202 int mbedErr = mbedtls_pk_sign(&pc->localPrivateKey,
113203 MBEDTLS_MD_SHA256, hash,
113204 UA_SHA256_LENGTH, signature->data,
113205#if MBEDTLS_VERSION_NUMBER >= 0x03000000
113206 signature->length,
113207#endif
113208 &sigLen, mbedtls_ctr_drbg_random,
113209 &pc->drbgContext);
113210 if(mbedErr)
113211 return UA_STATUSCODE_BADINTERNALERROR;
113212 return UA_STATUSCODE_GOOD;
113213}
113214
113215static size_t
113216asym_getLocalSignatureSize_sp_aes128sha256rsaoaep(const Aes128Sha256PsaOaep_ChannelContext *cc) {
113217 if(cc == NULL)
113218 return 0;
113219#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
113220 return mbedtls_pk_rsa(cc->policyContext->localPrivateKey)->len;
113221#else
113222 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->policyContext->localPrivateKey));
113223#endif
113224}
113225
113226static size_t
113227asym_getRemoteSignatureSize_sp_aes128sha256rsaoaep(const Aes128Sha256PsaOaep_ChannelContext *cc) {
113228 if(cc == NULL)
113229 return 0;
113230#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
113231 return mbedtls_pk_rsa(cc->remoteCertificate.pk)->len;
113232#else
113233 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
113234#endif
113235}
113236
113237static size_t
113238asym_getRemoteBlockSize_sp_aes128sha256rsaoaep(const Aes128Sha256PsaOaep_ChannelContext *cc) {
113239 if(cc == NULL)
113240 return 0;
113241#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
113242 return mbedtls_pk_rsa(cc->remoteCertificate.pk)->len;
113243#else
113244 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
113245#endif
113246}
113247
113248static size_t
113249asym_getRemotePlainTextBlockSize_sp_aes128sha256rsaoaep(const Aes128Sha256PsaOaep_ChannelContext *cc) {
113250 if(cc == NULL)
113251 return 0;
113252#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
113253 mbedtls_rsa_context *const rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
113254 return rsaContext->len - UA_SECURITYPOLICY_AES128SHA256RSAOAEP_RSAPADDING_LEN;
113255#else
113256 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk)) -
113257 UA_SECURITYPOLICY_AES128SHA256RSAOAEP_RSAPADDING_LEN;
113258#endif
113259}
113260
113261
113262/* AsymmetricEncryptionAlgorithm_RSA-OAEP-SHA1 */
113263static UA_StatusCode
113264asym_encrypt_sp_aes128sha256rsaoaep(Aes128Sha256PsaOaep_ChannelContext *cc,
113265 UA_ByteString *data) {
113266 if(cc == NULL || data == NULL)
113267 return UA_STATUSCODE_BADINTERNALERROR;
113268
113269 const size_t plainTextBlockSize = asym_getRemotePlainTextBlockSize_sp_aes128sha256rsaoaep(cc);
113270
113271 mbedtls_rsa_context *remoteRsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
113272 mbedtls_rsa_set_padding(remoteRsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1);
113273
113274 return mbedtls_encrypt_rsaOaep(remoteRsaContext, &cc->policyContext->drbgContext,
113275 data, plainTextBlockSize);
113276}
113277
113278/* AsymmetricEncryptionAlgorithm_RSA-OAEP-SHA1 */
113279static UA_StatusCode
113280asym_decrypt_sp_aes128sha256rsaoaep(Aes128Sha256PsaOaep_ChannelContext *cc,
113281 UA_ByteString *data) {
113282 if(cc == NULL || data == NULL)
113283 return UA_STATUSCODE_BADINTERNALERROR;
113284 return mbedtls_decrypt_rsaOaep(&cc->policyContext->localPrivateKey,
113285 &cc->policyContext->drbgContext, data, MBEDTLS_MD_SHA1);
113286}
113287
113288static size_t
113289asym_getLocalEncryptionKeyLength_sp_aes128sha256rsaoaep(const Aes128Sha256PsaOaep_ChannelContext *cc) {
113290 return mbedtls_pk_get_len(&cc->policyContext->localPrivateKey) * 8;
113291}
113292
113293static size_t
113294asym_getRemoteEncryptionKeyLength_sp_aes128sha256rsaoaep(const Aes128Sha256PsaOaep_ChannelContext *cc) {
113295 return mbedtls_pk_get_len(&cc->remoteCertificate.pk) * 8;
113296}
113297
113298static UA_StatusCode
113299asym_makeThumbprint_sp_aes128sha256rsaoaep(const UA_SecurityPolicy *securityPolicy,
113300 const UA_ByteString *certificate,
113301 UA_ByteString *thumbprint) {
113302 if(securityPolicy == NULL || certificate == NULL || thumbprint == NULL)
113303 return UA_STATUSCODE_BADINTERNALERROR;
113304 return mbedtls_thumbprint_sha1(certificate, thumbprint);
113305}
113306
113307static UA_StatusCode
113308asymmetricModule_compareCertificateThumbprint_sp_aes128sha256rsaoaep(const UA_SecurityPolicy *securityPolicy,
113309 const UA_ByteString *certificateThumbprint) {
113310 if(securityPolicy == NULL || certificateThumbprint == NULL)
113311 return UA_STATUSCODE_BADINTERNALERROR;
113312
113313 Aes128Sha256PsaOaep_PolicyContext *pc = (Aes128Sha256PsaOaep_PolicyContext *)securityPolicy->policyContext;
113314 if(!UA_ByteString_equal(certificateThumbprint, &pc->localCertThumbprint))
113315 return UA_STATUSCODE_BADCERTIFICATEINVALID;
113316
113317 return UA_STATUSCODE_GOOD;
113318}
113319
113320/*******************/
113321/* SymmetricModule */
113322/*******************/
113323
113324static UA_StatusCode
113325sym_verify_sp_aes128sha256rsaoaep(Aes128Sha256PsaOaep_ChannelContext *cc,
113326 const UA_ByteString *message,
113327 const UA_ByteString *signature) {
113328 if(cc == NULL || message == NULL || signature == NULL)
113329 return UA_STATUSCODE_BADINTERNALERROR;
113330
113331 /* Compute MAC */
113332 if(signature->length != UA_SHA256_LENGTH)
113333 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
113334 Aes128Sha256PsaOaep_PolicyContext *pc = cc->policyContext;
113335 unsigned char mac[UA_SHA256_LENGTH];
113336 mbedtls_hmac(&pc->sha256MdContext, &cc->remoteSymSigningKey, message, mac);
113337
113338 /* Compare with Signature */
113339 if(!UA_constantTimeEqual(signature->data, mac, UA_SHA256_LENGTH))
113340 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
113341 return UA_STATUSCODE_GOOD;
113342}
113343
113344static UA_StatusCode
113345sym_sign_sp_aes128sha256rsaoaep(const Aes128Sha256PsaOaep_ChannelContext *cc,
113346 const UA_ByteString *message,
113347 UA_ByteString *signature) {
113348 if(signature->length != UA_SHA256_LENGTH)
113349 return UA_STATUSCODE_BADINTERNALERROR;
113350
113351 mbedtls_hmac(&cc->policyContext->sha256MdContext, &cc->localSymSigningKey,
113352 message, signature->data);
113353 return UA_STATUSCODE_GOOD;
113354}
113355
113356static size_t
113357sym_getSignatureSize_sp_aes128sha256rsaoaep(const void *channelContext) {
113358 return UA_SHA256_LENGTH;
113359}
113360
113361static size_t
113362sym_getSigningKeyLength_sp_aes128sha256rsaoaep(const void *channelContext) {
113363 return UA_AES128SHA256RSAOAEP_SYM_SIGNING_KEY_LENGTH;
113364}
113365
113366static size_t
113367sym_getEncryptionKeyLength_sp_aes128sha256rsaoaep(const void *channelContext) {
113368 return UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_KEY_LENGTH;
113369}
113370
113371static size_t
113372sym_getEncryptionBlockSize_sp_aes128sha256rsaoaep(const void *channelContext) {
113373 return UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_ENCRYPTION_BLOCK_SIZE;
113374}
113375
113376static size_t
113377sym_getPlainTextBlockSize_sp_aes128sha256rsaoaep(const void *channelContext) {
113378 return UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_PLAIN_TEXT_BLOCK_SIZE;
113379}
113380
113381static UA_StatusCode
113382sym_encrypt_sp_aes128sha256rsaoaep(const Aes128Sha256PsaOaep_ChannelContext *cc,
113383 UA_ByteString *data) {
113384 if(cc == NULL || data == NULL)
113385 return UA_STATUSCODE_BADINTERNALERROR;
113386
113387 if(cc->localSymIv.length != UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_ENCRYPTION_BLOCK_SIZE)
113388 return UA_STATUSCODE_BADINTERNALERROR;
113389
113390 size_t plainTextBlockSize = UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_PLAIN_TEXT_BLOCK_SIZE;
113391
113392 if(data->length % plainTextBlockSize != 0)
113393 return UA_STATUSCODE_BADINTERNALERROR;
113394
113395 /* Keylength in bits */
113396 unsigned int keylength = (unsigned int)(cc->localSymEncryptingKey.length * 8);
113397 mbedtls_aes_context aesContext;
113398 int mbedErr = mbedtls_aes_setkey_enc(&aesContext, cc->localSymEncryptingKey.data, keylength);
113399 if(mbedErr)
113400 return UA_STATUSCODE_BADINTERNALERROR;
113401
113402 UA_ByteString ivCopy;
113403 UA_StatusCode retval = UA_ByteString_copy(&cc->localSymIv, &ivCopy);
113404 if(retval != UA_STATUSCODE_GOOD)
113405 return retval;
113406
113407 mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_ENCRYPT, data->length,
113408 ivCopy.data, data->data, data->data);
113409 if(mbedErr)
113410 retval = UA_STATUSCODE_BADINTERNALERROR;
113411 UA_ByteString_clear(&ivCopy);
113412 return retval;
113413}
113414
113415static UA_StatusCode
113416sym_decrypt_sp_aes128sha256rsaoaep(const Aes128Sha256PsaOaep_ChannelContext *cc,
113417 UA_ByteString *data) {
113418 if(cc == NULL || data == NULL)
113419 return UA_STATUSCODE_BADINTERNALERROR;
113420
113421 size_t encryptionBlockSize = UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_ENCRYPTION_BLOCK_SIZE;
113422
113423 if(cc->remoteSymIv.length != encryptionBlockSize)
113424 return UA_STATUSCODE_BADINTERNALERROR;
113425
113426 if(data->length % encryptionBlockSize != 0)
113427 return UA_STATUSCODE_BADINTERNALERROR;
113428
113429 unsigned int keylength = (unsigned int)(cc->remoteSymEncryptingKey.length * 8);
113430 mbedtls_aes_context aesContext;
113431 int mbedErr = mbedtls_aes_setkey_dec(&aesContext, cc->remoteSymEncryptingKey.data, keylength);
113432 if(mbedErr)
113433 return UA_STATUSCODE_BADINTERNALERROR;
113434
113435 UA_ByteString ivCopy;
113436 UA_StatusCode retval = UA_ByteString_copy(&cc->remoteSymIv, &ivCopy);
113437 if(retval != UA_STATUSCODE_GOOD)
113438 return retval;
113439
113440 mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_DECRYPT, data->length,
113441 ivCopy.data, data->data, data->data);
113442 if(mbedErr)
113443 retval = UA_STATUSCODE_BADINTERNALERROR;
113444 UA_ByteString_clear(&ivCopy);
113445 return retval;
113446}
113447
113448static UA_StatusCode
113449sym_generateKey_sp_aes128sha256rsaoaep(void *policyContext, const UA_ByteString *secret,
113450 const UA_ByteString *seed, UA_ByteString *out) {
113451 if(secret == NULL || seed == NULL || out == NULL)
113452 return UA_STATUSCODE_BADINTERNALERROR;
113453 Aes128Sha256PsaOaep_PolicyContext *pc = (Aes128Sha256PsaOaep_PolicyContext *)policyContext;
113454 return mbedtls_generateKey(&pc->sha256MdContext, secret, seed, out);
113455}
113456
113457static UA_StatusCode
113458sym_generateNonce_sp_aes128sha256rsaoaep(void *policyContext, UA_ByteString *out) {
113459 if(out == NULL)
113460 return UA_STATUSCODE_BADINTERNALERROR;
113461 Aes128Sha256PsaOaep_PolicyContext *pc =
113462 (Aes128Sha256PsaOaep_PolicyContext *)policyContext;
113463 int mbedErr = mbedtls_ctr_drbg_random(&pc->drbgContext, out->data, out->length);
113464 if(mbedErr)
113465 return UA_STATUSCODE_BADUNEXPECTEDERROR;
113466 return UA_STATUSCODE_GOOD;
113467}
113468
113469/*****************/
113470/* ChannelModule */
113471/*****************/
113472
113473/* Assumes that the certificate has been verified externally */
113474static UA_StatusCode
113475parseRemoteCertificate_sp_aes128sha256rsaoaep(Aes128Sha256PsaOaep_ChannelContext *cc,
113476 const UA_ByteString *remoteCertificate) {
113477 if(remoteCertificate == NULL || cc == NULL)
113478 return UA_STATUSCODE_BADINTERNALERROR;
113479
113480 /* Parse the certificate */
113481 int mbedErr = mbedtls_x509_crt_parse(&cc->remoteCertificate, remoteCertificate->data,
113482 remoteCertificate->length);
113483 if(mbedErr)
113484 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
113485
113486 /* Check the key length */
113487 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
113488#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
113489 size_t keylen = rsaContext->len;
113490#else
113491 size_t keylen = mbedtls_rsa_get_len(rsaContext);
113492#endif
113493 if(keylen < UA_SECURITYPOLICY_AES128SHA256RSAOAEP_MINASYMKEYLENGTH ||
113494 keylen > UA_SECURITYPOLICY_AES128SHA256RSAOAEP_MAXASYMKEYLENGTH)
113495 return UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED;
113496 return UA_STATUSCODE_GOOD;
113497}
113498
113499static void
113500channelContext_deleteContext_sp_aes128sha256rsaoaep(Aes128Sha256PsaOaep_ChannelContext *cc) {
113501 UA_ByteString_clear(&cc->localSymSigningKey);
113502 UA_ByteString_clear(&cc->localSymEncryptingKey);
113503 UA_ByteString_clear(&cc->localSymIv);
113504
113505 UA_ByteString_clear(&cc->remoteSymSigningKey);
113506 UA_ByteString_clear(&cc->remoteSymEncryptingKey);
113507 UA_ByteString_clear(&cc->remoteSymIv);
113508
113509 mbedtls_x509_crt_free(&cc->remoteCertificate);
113510
113511 UA_free(cc);
113512}
113513
113514static UA_StatusCode
113515channelContext_newContext_sp_aes128sha256rsaoaep(const UA_SecurityPolicy *securityPolicy,
113516 const UA_ByteString *remoteCertificate,
113517 void **pp_contextData) {
113518 if(securityPolicy == NULL || remoteCertificate == NULL || pp_contextData == NULL)
113519 return UA_STATUSCODE_BADINTERNALERROR;
113520
113521 /* Allocate the channel context */
113522 *pp_contextData = UA_malloc(sizeof(Aes128Sha256PsaOaep_ChannelContext));
113523 if(*pp_contextData == NULL)
113524 return UA_STATUSCODE_BADOUTOFMEMORY;
113525
113526 Aes128Sha256PsaOaep_ChannelContext *cc = (Aes128Sha256PsaOaep_ChannelContext *)*pp_contextData;
113527
113528 /* Initialize the channel context */
113529 cc->policyContext = (Aes128Sha256PsaOaep_PolicyContext *)securityPolicy->policyContext;
113530
113531 UA_ByteString_init(&cc->localSymSigningKey);
113532 UA_ByteString_init(&cc->localSymEncryptingKey);
113533 UA_ByteString_init(&cc->localSymIv);
113534
113535 UA_ByteString_init(&cc->remoteSymSigningKey);
113536 UA_ByteString_init(&cc->remoteSymEncryptingKey);
113537 UA_ByteString_init(&cc->remoteSymIv);
113538
113539 mbedtls_x509_crt_init(&cc->remoteCertificate);
113540
113541 // TODO: this can be optimized so that we dont allocate memory before parsing the certificate
113542 UA_StatusCode retval = parseRemoteCertificate_sp_aes128sha256rsaoaep(cc, remoteCertificate);
113543 if(retval != UA_STATUSCODE_GOOD) {
113544 channelContext_deleteContext_sp_aes128sha256rsaoaep(cc);
113545 *pp_contextData = NULL;
113546 }
113547 return retval;
113548}
113549
113550static UA_StatusCode
113551channelContext_setLocalSymEncryptingKey_sp_aes128sha256rsaoaep(Aes128Sha256PsaOaep_ChannelContext *cc,
113552 const UA_ByteString *key) {
113553 if(key == NULL || cc == NULL)
113554 return UA_STATUSCODE_BADINTERNALERROR;
113555
113556 UA_ByteString_clear(&cc->localSymEncryptingKey);
113557 return UA_ByteString_copy(key, &cc->localSymEncryptingKey);
113558}
113559
113560static UA_StatusCode
113561channelContext_setLocalSymSigningKey_sp_aes128sha256rsaoaep(Aes128Sha256PsaOaep_ChannelContext *cc,
113562 const UA_ByteString *key) {
113563 if(key == NULL || cc == NULL)
113564 return UA_STATUSCODE_BADINTERNALERROR;
113565
113566 UA_ByteString_clear(&cc->localSymSigningKey);
113567 return UA_ByteString_copy(key, &cc->localSymSigningKey);
113568}
113569
113570
113571static UA_StatusCode
113572channelContext_setLocalSymIv_sp_aes128sha256rsaoaep(Aes128Sha256PsaOaep_ChannelContext *cc,
113573 const UA_ByteString *iv) {
113574 if(iv == NULL || cc == NULL)
113575 return UA_STATUSCODE_BADINTERNALERROR;
113576
113577 UA_ByteString_clear(&cc->localSymIv);
113578 return UA_ByteString_copy(iv, &cc->localSymIv);
113579}
113580
113581static UA_StatusCode
113582channelContext_setRemoteSymEncryptingKey_sp_aes128sha256rsaoaep(Aes128Sha256PsaOaep_ChannelContext *cc,
113583 const UA_ByteString *key) {
113584 if(key == NULL || cc == NULL)
113585 return UA_STATUSCODE_BADINTERNALERROR;
113586
113587 UA_ByteString_clear(&cc->remoteSymEncryptingKey);
113588 return UA_ByteString_copy(key, &cc->remoteSymEncryptingKey);
113589}
113590
113591static UA_StatusCode
113592channelContext_setRemoteSymSigningKey_sp_aes128sha256rsaoaep(Aes128Sha256PsaOaep_ChannelContext *cc,
113593 const UA_ByteString *key) {
113594 if(key == NULL || cc == NULL)
113595 return UA_STATUSCODE_BADINTERNALERROR;
113596
113597 UA_ByteString_clear(&cc->remoteSymSigningKey);
113598 return UA_ByteString_copy(key, &cc->remoteSymSigningKey);
113599}
113600
113601static UA_StatusCode
113602channelContext_setRemoteSymIv_sp_aes128sha256rsaoaep(Aes128Sha256PsaOaep_ChannelContext *cc,
113603 const UA_ByteString *iv) {
113604 if(iv == NULL || cc == NULL)
113605 return UA_STATUSCODE_BADINTERNALERROR;
113606
113607 UA_ByteString_clear(&cc->remoteSymIv);
113608 return UA_ByteString_copy(iv, &cc->remoteSymIv);
113609}
113610
113611static UA_StatusCode
113612channelContext_compareCertificate_sp_aes128sha256rsaoaep(const Aes128Sha256PsaOaep_ChannelContext *cc,
113613 const UA_ByteString *certificate) {
113614 if(cc == NULL || certificate == NULL)
113615 return UA_STATUSCODE_BADINTERNALERROR;
113616
113617 mbedtls_x509_crt cert;
113618 mbedtls_x509_crt_init(&cert);
113619 int mbedErr = mbedtls_x509_crt_parse(&cert, certificate->data, certificate->length);
113620 if(mbedErr)
113621 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
113622
113623 UA_StatusCode retval = UA_STATUSCODE_GOOD;
113624 if(cert.raw.len != cc->remoteCertificate.raw.len ||
113625 memcmp(cert.raw.p, cc->remoteCertificate.raw.p, cert.raw.len) != 0)
113626 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
113627
113628 mbedtls_x509_crt_free(&cert);
113629 return retval;
113630}
113631
113632static void
113633clear_sp_aes128sha256rsaoaep(UA_SecurityPolicy *securityPolicy) {
113634 if(securityPolicy == NULL)
113635 return;
113636
113637 UA_ByteString_clear(&securityPolicy->localCertificate);
113638
113639 if(securityPolicy->policyContext == NULL)
113640 return;
113641
113642 /* delete all allocated members in the context */
113643 Aes128Sha256PsaOaep_PolicyContext *pc = (Aes128Sha256PsaOaep_PolicyContext *)
113644 securityPolicy->policyContext;
113645
113646 mbedtls_ctr_drbg_free(&pc->drbgContext);
113647 mbedtls_entropy_free(&pc->entropyContext);
113648 mbedtls_pk_free(&pc->localPrivateKey);
113649 mbedtls_md_free(&pc->sha256MdContext);
113650 UA_ByteString_clear(&pc->localCertThumbprint);
113651
113652 UA_LOG_DEBUG(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
113653 "Deleted members of EndpointContext for sp_aes128sha256rsaoaep");
113654
113655 UA_free(pc);
113656 securityPolicy->policyContext = NULL;
113657}
113658
113659static UA_StatusCode
113660updateCertificateAndPrivateKey_sp_aes128sha256rsaoaep(UA_SecurityPolicy *securityPolicy,
113661 const UA_ByteString newCertificate,
113662 const UA_ByteString newPrivateKey) {
113663 if(securityPolicy == NULL)
113664 return UA_STATUSCODE_BADINTERNALERROR;
113665
113666 if(securityPolicy->policyContext == NULL)
113667 return UA_STATUSCODE_BADINTERNALERROR;
113668
113669 Aes128Sha256PsaOaep_PolicyContext *pc =
113670 (Aes128Sha256PsaOaep_PolicyContext *) securityPolicy->policyContext;
113671
113672 UA_ByteString_clear(&securityPolicy->localCertificate);
113673
113674 UA_StatusCode retval = UA_mbedTLS_LoadLocalCertificate(&newCertificate, &securityPolicy->localCertificate);
113675
113676 if(retval != UA_STATUSCODE_GOOD)
113677 return retval;
113678
113679 /* Set the new private key */
113680 mbedtls_pk_free(&pc->localPrivateKey);
113681 mbedtls_pk_init(&pc->localPrivateKey);
113682 int mbedErr = UA_mbedTLS_LoadPrivateKey(&newPrivateKey, &pc->localPrivateKey, &pc->entropyContext);
113683 if(mbedErr) {
113684 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
113685 goto error;
113686 }
113687
113688 retval = asym_makeThumbprint_sp_aes128sha256rsaoaep(securityPolicy,
113689 &securityPolicy->localCertificate,
113690 &pc->localCertThumbprint);
113691 if(retval != UA_STATUSCODE_GOOD)
113692 goto error;
113693
113694 return retval;
113695
113696 error:
113697 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
113698 "Could not update certificate and private key");
113699 if(securityPolicy->policyContext != NULL)
113700 clear_sp_aes128sha256rsaoaep(securityPolicy);
113701 return retval;
113702}
113703
113704static UA_StatusCode
113705policyContext_newContext_sp_aes128sha256rsaoaep(UA_SecurityPolicy *securityPolicy,
113706 const UA_ByteString localPrivateKey) {
113707 UA_StatusCode retval = UA_STATUSCODE_GOOD;
113708 if(securityPolicy == NULL)
113709 return UA_STATUSCODE_BADINTERNALERROR;
113710
113711 if (localPrivateKey.length == 0) {
113712 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
113713 "Can not initialize security policy. Private key is empty.");
113714 return UA_STATUSCODE_BADINVALIDARGUMENT;
113715 }
113716
113717 Aes128Sha256PsaOaep_PolicyContext *pc = (Aes128Sha256PsaOaep_PolicyContext *)
113718 UA_malloc(sizeof(Aes128Sha256PsaOaep_PolicyContext));
113719 securityPolicy->policyContext = (void *)pc;
113720 if(!pc) {
113721 retval = UA_STATUSCODE_BADOUTOFMEMORY;
113722 goto error;
113723 }
113724
113725 /* Initialize the PolicyContext */
113726 memset(pc, 0, sizeof(Aes128Sha256PsaOaep_PolicyContext));
113727 mbedtls_ctr_drbg_init(&pc->drbgContext);
113728 mbedtls_entropy_init(&pc->entropyContext);
113729 mbedtls_pk_init(&pc->localPrivateKey);
113730 mbedtls_md_init(&pc->sha256MdContext);
113731
113732 /* Initialized the message digest */
113733 const mbedtls_md_info_t *const mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
113734 int mbedErr = mbedtls_md_setup(&pc->sha256MdContext, mdInfo, MBEDTLS_MD_SHA256);
113735 if(mbedErr) {
113736 retval = UA_STATUSCODE_BADOUTOFMEMORY;
113737 goto error;
113738 }
113739
113740 mbedErr = mbedtls_entropy_self_test(0);
113741
113742 if(mbedErr) {
113743 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
113744 goto error;
113745 }
113746
113747 /* Seed the RNG */
113748 char *personalization = "open62541-drbg";
113749 mbedErr = mbedtls_ctr_drbg_seed(&pc->drbgContext, mbedtls_entropy_func,
113750 &pc->entropyContext,
113751 (const unsigned char *)personalization, 14);
113752 if(mbedErr) {
113753 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
113754 goto error;
113755 }
113756
113757 /* Set the private key */
113758 mbedErr = UA_mbedTLS_LoadPrivateKey(&localPrivateKey, &pc->localPrivateKey, &pc->entropyContext);
113759 if(mbedErr) {
113760 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
113761 goto error;
113762 }
113763
113764 /* Set the local certificate thumbprint */
113765 retval = UA_ByteString_allocBuffer(&pc->localCertThumbprint, UA_SHA1_LENGTH);
113766 if(retval != UA_STATUSCODE_GOOD)
113767 goto error;
113768 retval = asym_makeThumbprint_sp_aes128sha256rsaoaep(securityPolicy,
113769 &securityPolicy->localCertificate,
113770 &pc->localCertThumbprint);
113771 if(retval != UA_STATUSCODE_GOOD)
113772 goto error;
113773
113774 return UA_STATUSCODE_GOOD;
113775
113776error:
113777 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
113778 "Could not create securityContext: %s", UA_StatusCode_name(retval));
113779 if(securityPolicy->policyContext != NULL)
113780 clear_sp_aes128sha256rsaoaep(securityPolicy);
113781 return retval;
113782}
113783
113784UA_StatusCode
113785UA_SecurityPolicy_Aes128Sha256RsaOaep(UA_SecurityPolicy *policy, const UA_ByteString localCertificate,
113786 const UA_ByteString localPrivateKey, const UA_Logger *logger) {
113787 memset(policy, 0, sizeof(UA_SecurityPolicy));
113788 policy->logger = logger;
113789
113790 policy->policyUri = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaep");
113791
113792 UA_SecurityPolicyAsymmetricModule *const asymmetricModule = &policy->asymmetricModule;
113793 UA_SecurityPolicySymmetricModule *const symmetricModule = &policy->symmetricModule;
113794 UA_SecurityPolicyChannelModule *const channelModule = &policy->channelModule;
113795
113796 UA_StatusCode retval = UA_mbedTLS_LoadLocalCertificate(&localCertificate, &policy->localCertificate);
113797
113798 if (retval != UA_STATUSCODE_GOOD)
113799 return retval;
113800
113801 /* AsymmetricModule */
113802 UA_SecurityPolicySignatureAlgorithm *asym_signatureAlgorithm =
113803 &asymmetricModule->cryptoModule.signatureAlgorithm;
113804 asym_signatureAlgorithm->uri =
113805 UA_STRING("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\0");
113806 asym_signatureAlgorithm->verify =
113807 (UA_StatusCode (*)(void *, const UA_ByteString *, const UA_ByteString *))asym_verify_sp_aes128sha256rsaoaep;
113808 asym_signatureAlgorithm->sign =
113809 (UA_StatusCode (*)(void *, const UA_ByteString *, UA_ByteString *))asym_sign_sp_aes128sha256rsaoaep;
113810 asym_signatureAlgorithm->getLocalSignatureSize =
113811 (size_t (*)(const void *))asym_getLocalSignatureSize_sp_aes128sha256rsaoaep;
113812 asym_signatureAlgorithm->getRemoteSignatureSize =
113813 (size_t (*)(const void *))asym_getRemoteSignatureSize_sp_aes128sha256rsaoaep;
113814 asym_signatureAlgorithm->getLocalKeyLength = NULL; // TODO: Write function
113815 asym_signatureAlgorithm->getRemoteKeyLength = NULL; // TODO: Write function
113816
113817 UA_SecurityPolicyEncryptionAlgorithm *asym_encryptionAlgorithm =
113818 &asymmetricModule->cryptoModule.encryptionAlgorithm;
113819 asym_encryptionAlgorithm->uri = UA_STRING("http://www.w3.org/2001/04/xmlenc#rsa-oaep\0");
113820 asym_encryptionAlgorithm->encrypt =
113821 (UA_StatusCode(*)(void *, UA_ByteString *))asym_encrypt_sp_aes128sha256rsaoaep;
113822 asym_encryptionAlgorithm->decrypt =
113823 (UA_StatusCode(*)(void *, UA_ByteString *)) asym_decrypt_sp_aes128sha256rsaoaep;
113824 asym_encryptionAlgorithm->getLocalKeyLength =
113825 (size_t (*)(const void *))asym_getLocalEncryptionKeyLength_sp_aes128sha256rsaoaep;
113826 asym_encryptionAlgorithm->getRemoteKeyLength =
113827 (size_t (*)(const void *))asym_getRemoteEncryptionKeyLength_sp_aes128sha256rsaoaep;
113828 asym_encryptionAlgorithm->getRemoteBlockSize = (size_t (*)(const void *))asym_getRemoteBlockSize_sp_aes128sha256rsaoaep;
113829 asym_encryptionAlgorithm->getRemotePlainTextBlockSize =
113830 (size_t (*)(const void *))asym_getRemotePlainTextBlockSize_sp_aes128sha256rsaoaep;
113831
113832 asymmetricModule->makeCertificateThumbprint = asym_makeThumbprint_sp_aes128sha256rsaoaep;
113833 asymmetricModule->compareCertificateThumbprint =
113834 asymmetricModule_compareCertificateThumbprint_sp_aes128sha256rsaoaep;
113835
113836 /* SymmetricModule */
113837 symmetricModule->generateKey = sym_generateKey_sp_aes128sha256rsaoaep;
113838 symmetricModule->generateNonce = sym_generateNonce_sp_aes128sha256rsaoaep;
113839
113840 UA_SecurityPolicySignatureAlgorithm *sym_signatureAlgorithm =
113841 &symmetricModule->cryptoModule.signatureAlgorithm;
113842 sym_signatureAlgorithm->uri =
113843 UA_STRING("http://www.w3.org/2000/09/xmldsig#hmac-sha1\0");
113844 sym_signatureAlgorithm->verify =
113845 (UA_StatusCode (*)(void *, const UA_ByteString *, const UA_ByteString *))sym_verify_sp_aes128sha256rsaoaep;
113846 sym_signatureAlgorithm->sign =
113847 (UA_StatusCode (*)(void *, const UA_ByteString *, UA_ByteString *))sym_sign_sp_aes128sha256rsaoaep;
113848 sym_signatureAlgorithm->getLocalSignatureSize = sym_getSignatureSize_sp_aes128sha256rsaoaep;
113849 sym_signatureAlgorithm->getRemoteSignatureSize = sym_getSignatureSize_sp_aes128sha256rsaoaep;
113850 sym_signatureAlgorithm->getLocalKeyLength =
113851 (size_t (*)(const void *))sym_getSigningKeyLength_sp_aes128sha256rsaoaep;
113852 sym_signatureAlgorithm->getRemoteKeyLength =
113853 (size_t (*)(const void *))sym_getSigningKeyLength_sp_aes128sha256rsaoaep;
113854
113855 UA_SecurityPolicyEncryptionAlgorithm *sym_encryptionAlgorithm =
113856 &symmetricModule->cryptoModule.encryptionAlgorithm;
113857 sym_encryptionAlgorithm->uri = UA_STRING("http://www.w3.org/2001/04/xmlenc#aes128-cbc");
113858 sym_encryptionAlgorithm->encrypt =
113859 (UA_StatusCode(*)(void *, UA_ByteString *))sym_encrypt_sp_aes128sha256rsaoaep;
113860 sym_encryptionAlgorithm->decrypt =
113861 (UA_StatusCode(*)(void *, UA_ByteString *))sym_decrypt_sp_aes128sha256rsaoaep;
113862 sym_encryptionAlgorithm->getLocalKeyLength = sym_getEncryptionKeyLength_sp_aes128sha256rsaoaep;
113863 sym_encryptionAlgorithm->getRemoteKeyLength = sym_getEncryptionKeyLength_sp_aes128sha256rsaoaep;
113864 sym_encryptionAlgorithm->getRemoteBlockSize =
113865 (size_t (*)(const void *))sym_getEncryptionBlockSize_sp_aes128sha256rsaoaep;
113866 sym_encryptionAlgorithm->getRemotePlainTextBlockSize =
113867 (size_t (*)(const void *))sym_getPlainTextBlockSize_sp_aes128sha256rsaoaep;
113868 symmetricModule->secureChannelNonceLength = 32;
113869
113870 // Use the same signature algorithm as the asymmetric component for certificate signing (see standard)
113871 policy->certificateSigningAlgorithm = policy->asymmetricModule.cryptoModule.signatureAlgorithm;
113872
113873 /* ChannelModule */
113874 channelModule->newContext = channelContext_newContext_sp_aes128sha256rsaoaep;
113875 channelModule->deleteContext = (void (*)(void *))
113876 channelContext_deleteContext_sp_aes128sha256rsaoaep;
113877
113878 channelModule->setLocalSymEncryptingKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
113879 channelContext_setLocalSymEncryptingKey_sp_aes128sha256rsaoaep;
113880 channelModule->setLocalSymSigningKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
113881 channelContext_setLocalSymSigningKey_sp_aes128sha256rsaoaep;
113882 channelModule->setLocalSymIv = (UA_StatusCode (*)(void *, const UA_ByteString *))
113883 channelContext_setLocalSymIv_sp_aes128sha256rsaoaep;
113884
113885 channelModule->setRemoteSymEncryptingKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
113886 channelContext_setRemoteSymEncryptingKey_sp_aes128sha256rsaoaep;
113887 channelModule->setRemoteSymSigningKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
113888 channelContext_setRemoteSymSigningKey_sp_aes128sha256rsaoaep;
113889 channelModule->setRemoteSymIv = (UA_StatusCode (*)(void *, const UA_ByteString *))
113890 channelContext_setRemoteSymIv_sp_aes128sha256rsaoaep;
113891
113892 channelModule->compareCertificate = (UA_StatusCode (*)(const void *, const UA_ByteString *))
113893 channelContext_compareCertificate_sp_aes128sha256rsaoaep;
113894
113895 policy->updateCertificateAndPrivateKey = updateCertificateAndPrivateKey_sp_aes128sha256rsaoaep;
113896 policy->clear = clear_sp_aes128sha256rsaoaep;
113897
113898 UA_StatusCode res = policyContext_newContext_sp_aes128sha256rsaoaep(policy, localPrivateKey);
113899 if(res != UA_STATUSCODE_GOOD)
113900 clear_sp_aes128sha256rsaoaep(policy);
113901
113902 return res;
113903}
113904
113905#endif
113906
113907/**** amalgamated original file "/plugins/crypto/mbedtls/ua_securitypolicy_aes256sha256rsapss.c" ****/
113908
113909/* This Source Code Form is subject to the terms of the Mozilla Public
113910 * License, v. 2.0. If a copy of the MPL was not distributed with this
113911 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
113912 *
113913 * Copyright 2022 (c) Fraunhofer IOSB (Author: Noel Graf)
113914 */
113915
113916
113917#ifdef UA_ENABLE_ENCRYPTION_MBEDTLS
113918
113919
113920#include <mbedtls/aes.h>
113921#include <mbedtls/ctr_drbg.h>
113922#include <mbedtls/entropy.h>
113923#include <mbedtls/error.h>
113924#include <mbedtls/md.h>
113925#include <mbedtls/sha1.h>
113926#include <mbedtls/sha256.h>
113927#include <mbedtls/version.h>
113928#include <mbedtls/x509_crt.h>
113929
113930/* Notes:
113931 * mbedTLS' AES allows in-place encryption and decryption. So we don't have to
113932 * allocate temp buffers.
113933 * https://tls.mbed.org/discussions/generic/in-place-decryption-with-aes256-same-input-output-buffer
113934 */
113935
113936#define UA_SHA1_LENGTH 20
113937#define UA_SHA256_LENGTH 32
113938#define UA_SECURITYPOLICY_AES256SHA256RSAPSS_RSAPADDING_LEN 66 /* UA_SHA256_LENGTH * 2 + 2 */
113939#define UA_AES256SHA256RSAPSS_SYM_SIGNING_KEY_LENGTH 32
113940#define UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_KEY_LENGTH 32 /*16*/
113941#define UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_ENCRYPTION_BLOCK_SIZE 16
113942#define UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_PLAIN_TEXT_BLOCK_SIZE 16
113943#define UA_SECURITYPOLICY_AES256SHA256RSAPSS_MINASYMKEYLENGTH 256
113944#define UA_SECURITYPOLICY_AES256SHA256RSAPSS_MAXASYMKEYLENGTH 512
113945
113946typedef struct {
113947 UA_ByteString localCertThumbprint;
113948
113949 mbedtls_ctr_drbg_context drbgContext;
113950 mbedtls_entropy_context entropyContext;
113951 mbedtls_md_context_t sha256MdContext;
113952 mbedtls_pk_context localPrivateKey;
113953} Aes256Sha256RsaPss_PolicyContext;
113954
113955typedef struct {
113956 Aes256Sha256RsaPss_PolicyContext *policyContext;
113957
113958 UA_ByteString localSymSigningKey;
113959 UA_ByteString localSymEncryptingKey;
113960 UA_ByteString localSymIv;
113961
113962 UA_ByteString remoteSymSigningKey;
113963 UA_ByteString remoteSymEncryptingKey;
113964 UA_ByteString remoteSymIv;
113965
113966 mbedtls_x509_crt remoteCertificate;
113967} Aes256Sha256RsaPss_ChannelContext;
113968
113969/********************/
113970/* AsymmetricModule */
113971/********************/
113972
113973/* VERIFY AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256 */
113974static UA_StatusCode
113975asym_verify_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
113976 const UA_ByteString *message,
113977 const UA_ByteString *signature) {
113978 if(message == NULL || signature == NULL || cc == NULL)
113979 return UA_STATUSCODE_BADINTERNALERROR;
113980
113981 unsigned char hash[UA_SHA256_LENGTH];
113982#if MBEDTLS_VERSION_NUMBER >= 0x02070000 && MBEDTLS_VERSION_NUMBER < 0x03000000
113983 // TODO check return status
113984 mbedtls_sha256_ret(message->data, message->length, hash, 0);
113985#else
113986 mbedtls_sha256(message->data, message->length, hash, 0);
113987#endif
113988
113989 /* Set the RSA settings */
113990 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
113991 mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
113992
113993#if MBEDTLS_VERSION_NUMBER < 0x03000000
113994 Aes256Sha256RsaPss_PolicyContext *pc = cc->policyContext;
113995 int mbedErr = mbedtls_rsa_pkcs1_verify(rsaContext, mbedtls_ctr_drbg_random, &pc->drbgContext,
113996 MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256, UA_SHA256_LENGTH,
113997 hash, signature->data);
113998#else
113999 int mbedErr = mbedtls_rsa_pkcs1_verify(rsaContext, MBEDTLS_MD_SHA256,
114000 UA_SHA256_LENGTH, hash, signature->data);
114001#endif
114002
114003 if(mbedErr)
114004 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
114005 return UA_STATUSCODE_GOOD;
114006}
114007
114008/* AsymmetricSignatureAlgorithm_RSA-PSS-SHA2-256 */
114009static UA_StatusCode
114010asym_sign_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
114011 const UA_ByteString *message,
114012 UA_ByteString *signature) {
114013 if(message == NULL || signature == NULL || cc == NULL)
114014 return UA_STATUSCODE_BADINTERNALERROR;
114015
114016 unsigned char hash[UA_SHA256_LENGTH];
114017#if MBEDTLS_VERSION_NUMBER >= 0x02070000 && MBEDTLS_VERSION_NUMBER < 0x03000000
114018 // TODO check return status
114019 mbedtls_sha256_ret(message->data, message->length, hash, 0);
114020#else
114021 mbedtls_sha256(message->data, message->length, hash, 0);
114022#endif
114023
114024 Aes256Sha256RsaPss_PolicyContext *pc = cc->policyContext;
114025 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(pc->localPrivateKey);
114026 mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
114027
114028#if MBEDTLS_VERSION_NUMBER < 0x03000000
114029 int mbedErr = mbedtls_rsa_pkcs1_sign(rsaContext, mbedtls_ctr_drbg_random, &pc->drbgContext,
114030 MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA256, UA_SHA256_LENGTH,
114031 hash, signature->data);
114032#else
114033 int mbedErr = mbedtls_rsa_pkcs1_sign(rsaContext, mbedtls_ctr_drbg_random, &pc->drbgContext,
114034 MBEDTLS_MD_SHA256, UA_SHA256_LENGTH,
114035 hash, signature->data);
114036#endif
114037
114038
114039 if(mbedErr)
114040 return UA_STATUSCODE_BADINTERNALERROR;
114041 return UA_STATUSCODE_GOOD;
114042}
114043
114044static size_t
114045asym_getLocalSignatureSize_sp_aes256sha256rsapss(const Aes256Sha256RsaPss_ChannelContext *cc) {
114046 if(cc == NULL)
114047 return 0;
114048#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
114049 return mbedtls_pk_rsa(cc->policyContext->localPrivateKey)->len;
114050#else
114051 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->policyContext->localPrivateKey));
114052#endif
114053}
114054
114055static size_t
114056asym_getRemoteSignatureSize_sp_aes256sha256rsapss(const Aes256Sha256RsaPss_ChannelContext *cc) {
114057 if(cc == NULL)
114058 return 0;
114059#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
114060 return mbedtls_pk_rsa(cc->remoteCertificate.pk)->len;
114061#else
114062 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
114063#endif
114064}
114065
114066static size_t
114067asym_getRemoteBlockSize_sp_aes256sha256rsapss(const Aes256Sha256RsaPss_ChannelContext *cc) {
114068 if(cc == NULL)
114069 return 0;
114070#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
114071 return mbedtls_pk_rsa(cc->remoteCertificate.pk)->len;
114072#else
114073 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
114074#endif
114075}
114076
114077static size_t
114078asym_getRemotePlainTextBlockSize_sp_aes256sha256rsapss(const Aes256Sha256RsaPss_ChannelContext *cc) {
114079 if(cc == NULL)
114080 return 0;
114081#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
114082 mbedtls_rsa_context *const rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
114083 return rsaContext->len - UA_SECURITYPOLICY_AES256SHA256RSAPSS_RSAPADDING_LEN;
114084#else
114085 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk)) -
114086 UA_SECURITYPOLICY_AES256SHA256RSAPSS_RSAPADDING_LEN;
114087#endif
114088}
114089
114090
114091/* AsymmetricEncryptionAlgorithm_RSA-OAEP-SHA2 */
114092static UA_StatusCode
114093asym_encrypt_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
114094 UA_ByteString *data) {
114095 if(cc == NULL || data == NULL)
114096 return UA_STATUSCODE_BADINTERNALERROR;
114097
114098 const size_t plainTextBlockSize = asym_getRemotePlainTextBlockSize_sp_aes256sha256rsapss(cc);
114099
114100 mbedtls_rsa_context *remoteRsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
114101 mbedtls_rsa_set_padding(remoteRsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
114102
114103 return mbedtls_encrypt_rsaOaep(remoteRsaContext, &cc->policyContext->drbgContext,
114104 data, plainTextBlockSize);
114105}
114106
114107/* AsymmetricEncryptionAlgorithm_RSA-OAEP-SHA2 */
114108static UA_StatusCode
114109asym_decrypt_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
114110 UA_ByteString *data) {
114111 if(cc == NULL || data == NULL)
114112 return UA_STATUSCODE_BADINTERNALERROR;
114113 return mbedtls_decrypt_rsaOaep(&cc->policyContext->localPrivateKey,
114114 &cc->policyContext->drbgContext, data, MBEDTLS_MD_SHA256);
114115}
114116
114117static size_t
114118asym_getLocalEncryptionKeyLength_sp_aes256sha256rsapss(const Aes256Sha256RsaPss_ChannelContext *cc) {
114119 return mbedtls_pk_get_len(&cc->policyContext->localPrivateKey) * 8;
114120}
114121
114122static size_t
114123asym_getRemoteEncryptionKeyLength_sp_aes256sha256rsapss(const Aes256Sha256RsaPss_ChannelContext *cc) {
114124 return mbedtls_pk_get_len(&cc->remoteCertificate.pk) * 8;
114125}
114126
114127static UA_StatusCode
114128asym_makeThumbprint_sp_aes256sha256rsapss(const UA_SecurityPolicy *securityPolicy,
114129 const UA_ByteString *certificate,
114130 UA_ByteString *thumbprint) {
114131 if(securityPolicy == NULL || certificate == NULL || thumbprint == NULL)
114132 return UA_STATUSCODE_BADINTERNALERROR;
114133 return mbedtls_thumbprint_sha1(certificate, thumbprint);
114134}
114135
114136static UA_StatusCode
114137asymmetricModule_compareCertificateThumbprint_sp_aes256sha256rsapss(const UA_SecurityPolicy *securityPolicy,
114138 const UA_ByteString *certificateThumbprint) {
114139 if(securityPolicy == NULL || certificateThumbprint == NULL)
114140 return UA_STATUSCODE_BADINTERNALERROR;
114141
114142 Aes256Sha256RsaPss_PolicyContext *pc = (Aes256Sha256RsaPss_PolicyContext *)securityPolicy->policyContext;
114143 if(!UA_ByteString_equal(certificateThumbprint, &pc->localCertThumbprint))
114144 return UA_STATUSCODE_BADCERTIFICATEINVALID;
114145
114146 return UA_STATUSCODE_GOOD;
114147}
114148
114149/*******************/
114150/* SymmetricModule */
114151/*******************/
114152
114153static UA_StatusCode
114154sym_verify_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
114155 const UA_ByteString *message,
114156 const UA_ByteString *signature) {
114157 if(cc == NULL || message == NULL || signature == NULL)
114158 return UA_STATUSCODE_BADINTERNALERROR;
114159
114160 /* Compute MAC */
114161 if(signature->length != UA_SHA256_LENGTH)
114162 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
114163 Aes256Sha256RsaPss_PolicyContext *pc = cc->policyContext;
114164 unsigned char mac[UA_SHA256_LENGTH];
114165 mbedtls_hmac(&pc->sha256MdContext, &cc->remoteSymSigningKey, message, mac);
114166
114167 /* Compare with Signature */
114168 if(!UA_constantTimeEqual(signature->data, mac, UA_SHA256_LENGTH))
114169 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
114170 return UA_STATUSCODE_GOOD;
114171}
114172
114173static UA_StatusCode
114174sym_sign_sp_aes256sha256rsapss(const Aes256Sha256RsaPss_ChannelContext *cc,
114175 const UA_ByteString *message,
114176 UA_ByteString *signature) {
114177 if(signature->length != UA_SHA256_LENGTH)
114178 return UA_STATUSCODE_BADINTERNALERROR;
114179
114180 mbedtls_hmac(&cc->policyContext->sha256MdContext, &cc->localSymSigningKey,
114181 message, signature->data);
114182 return UA_STATUSCODE_GOOD;
114183}
114184
114185static size_t
114186sym_getSignatureSize_sp_aes256sha256rsapss(const void *channelContext) {
114187 return UA_SHA256_LENGTH;
114188}
114189
114190static size_t
114191sym_getSigningKeyLength_sp_aes256sha256rsapss(const void *channelContext) {
114192 return UA_AES256SHA256RSAPSS_SYM_SIGNING_KEY_LENGTH;
114193}
114194
114195static size_t
114196sym_getEncryptionKeyLength_sp_aes256sha256rsapss(const void *channelContext) {
114197 return UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_KEY_LENGTH;
114198}
114199
114200static size_t
114201sym_getEncryptionBlockSize_sp_aes256sha256rsapss(const void *channelContext) {
114202 return UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_ENCRYPTION_BLOCK_SIZE;
114203}
114204
114205static size_t
114206sym_getPlainTextBlockSize_sp_aes256sha256rsapss(const void *channelContext) {
114207 return UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_PLAIN_TEXT_BLOCK_SIZE;
114208}
114209
114210static UA_StatusCode
114211sym_encrypt_sp_aes256sha256rsapss(const Aes256Sha256RsaPss_ChannelContext *cc,
114212 UA_ByteString *data) {
114213 if(cc == NULL || data == NULL)
114214 return UA_STATUSCODE_BADINTERNALERROR;
114215
114216 if(cc->localSymIv.length != UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_ENCRYPTION_BLOCK_SIZE)
114217 return UA_STATUSCODE_BADINTERNALERROR;
114218
114219 size_t plainTextBlockSize = UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_PLAIN_TEXT_BLOCK_SIZE;
114220
114221 if(data->length % plainTextBlockSize != 0)
114222 return UA_STATUSCODE_BADINTERNALERROR;
114223
114224 /* Keylength in bits */
114225 unsigned int keylength = (unsigned int)(cc->localSymEncryptingKey.length * 8);
114226 mbedtls_aes_context aesContext;
114227 int mbedErr = mbedtls_aes_setkey_enc(&aesContext, cc->localSymEncryptingKey.data, keylength);
114228 if(mbedErr)
114229 return UA_STATUSCODE_BADINTERNALERROR;
114230
114231 UA_ByteString ivCopy;
114232 UA_StatusCode retval = UA_ByteString_copy(&cc->localSymIv, &ivCopy);
114233 if(retval != UA_STATUSCODE_GOOD)
114234 return retval;
114235
114236 mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_ENCRYPT, data->length,
114237 ivCopy.data, data->data, data->data);
114238 if(mbedErr)
114239 retval = UA_STATUSCODE_BADINTERNALERROR;
114240 UA_ByteString_clear(&ivCopy);
114241 return retval;
114242}
114243
114244static UA_StatusCode
114245sym_decrypt_sp_aes256sha256rsapss(const Aes256Sha256RsaPss_ChannelContext *cc,
114246 UA_ByteString *data) {
114247 if(cc == NULL || data == NULL)
114248 return UA_STATUSCODE_BADINTERNALERROR;
114249
114250 size_t encryptionBlockSize = UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_ENCRYPTION_BLOCK_SIZE;
114251
114252 if(cc->remoteSymIv.length != encryptionBlockSize)
114253 return UA_STATUSCODE_BADINTERNALERROR;
114254
114255 if(data->length % encryptionBlockSize != 0)
114256 return UA_STATUSCODE_BADINTERNALERROR;
114257
114258 unsigned int keylength = (unsigned int)(cc->remoteSymEncryptingKey.length * 8);
114259 mbedtls_aes_context aesContext;
114260 int mbedErr = mbedtls_aes_setkey_dec(&aesContext, cc->remoteSymEncryptingKey.data, keylength);
114261 if(mbedErr)
114262 return UA_STATUSCODE_BADINTERNALERROR;
114263
114264 UA_ByteString ivCopy;
114265 UA_StatusCode retval = UA_ByteString_copy(&cc->remoteSymIv, &ivCopy);
114266 if(retval != UA_STATUSCODE_GOOD)
114267 return retval;
114268
114269 mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_DECRYPT, data->length,
114270 ivCopy.data, data->data, data->data);
114271 if(mbedErr)
114272 retval = UA_STATUSCODE_BADINTERNALERROR;
114273 UA_ByteString_clear(&ivCopy);
114274 return retval;
114275}
114276
114277static UA_StatusCode
114278sym_generateKey_sp_aes256sha256rsapss(void *policyContext, const UA_ByteString *secret,
114279 const UA_ByteString *seed, UA_ByteString *out) {
114280 if(secret == NULL || seed == NULL || out == NULL)
114281 return UA_STATUSCODE_BADINTERNALERROR;
114282 Aes256Sha256RsaPss_PolicyContext *pc = (Aes256Sha256RsaPss_PolicyContext *)policyContext;
114283 return mbedtls_generateKey(&pc->sha256MdContext, secret, seed, out);
114284}
114285
114286static UA_StatusCode
114287sym_generateNonce_sp_aes256sha256rsapss(void *policyContext, UA_ByteString *out) {
114288 if(out == NULL)
114289 return UA_STATUSCODE_BADINTERNALERROR;
114290 Aes256Sha256RsaPss_PolicyContext *pc =
114291 (Aes256Sha256RsaPss_PolicyContext *)policyContext;
114292 int mbedErr = mbedtls_ctr_drbg_random(&pc->drbgContext, out->data, out->length);
114293 if(mbedErr)
114294 return UA_STATUSCODE_BADUNEXPECTEDERROR;
114295 return UA_STATUSCODE_GOOD;
114296}
114297
114298/***********************************/
114299/* CertificateSigningAlgorithms */
114300/***********************************/
114301
114302static UA_StatusCode
114303asym_cert_verify_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
114304 const UA_ByteString *message,
114305 const UA_ByteString *signature) {
114306 if(message == NULL || signature == NULL || cc == NULL)
114307 return UA_STATUSCODE_BADINTERNALERROR;
114308
114309 unsigned char hash[UA_SHA256_LENGTH];
114310#if MBEDTLS_VERSION_NUMBER >= 0x02070000 && MBEDTLS_VERSION_NUMBER < 0x03000000
114311 // TODO check return status
114312 mbedtls_sha256_ret(message->data, message->length, hash, 0);
114313#else
114314 mbedtls_sha256(message->data, message->length, hash, 0);
114315#endif
114316
114317 /* Set the RSA settings */
114318 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
114319 mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA256);
114320
114321 /* For RSA keys, the default padding type is PKCS#1 v1.5 in mbedtls_pk_verify() */
114322 /* Alternatively, use more specific function mbedtls_rsa_rsassa_pkcs1_v15_verify(), i.e. */
114323 /* int mbedErr = mbedtls_rsa_rsassa_pkcs1_v15_verify(rsaContext, NULL, NULL,
114324 MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256,
114325 UA_SHA256_LENGTH, hash,
114326 signature->data); */
114327 int mbedErr = mbedtls_pk_verify(&cc->remoteCertificate.pk,
114328 MBEDTLS_MD_SHA256, hash, UA_SHA256_LENGTH,
114329 signature->data, signature->length);
114330
114331 if(mbedErr)
114332 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
114333 return UA_STATUSCODE_GOOD;
114334}
114335
114336/* AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256 */
114337static UA_StatusCode
114338asym_cert_sign_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
114339 const UA_ByteString *message,
114340 UA_ByteString *signature) {
114341 if(message == NULL || signature == NULL || cc == NULL)
114342 return UA_STATUSCODE_BADINTERNALERROR;
114343
114344 unsigned char hash[UA_SHA256_LENGTH];
114345#if MBEDTLS_VERSION_NUMBER >= 0x02070000 && MBEDTLS_VERSION_NUMBER < 0x03000000
114346 // TODO check return status
114347 mbedtls_sha256_ret(message->data, message->length, hash, 0);
114348#else
114349 mbedtls_sha256(message->data, message->length, hash, 0);
114350#endif
114351
114352 Aes256Sha256RsaPss_PolicyContext *pc = cc->policyContext;
114353 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(pc->localPrivateKey);
114354 mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA256);
114355
114356 size_t sigLen = 0;
114357
114358 /* For RSA keys, the default padding type is PKCS#1 v1.5 in mbedtls_pk_sign */
114359 /* Alternatively use more specific function mbedtls_rsa_rsassa_pkcs1_v15_sign() */
114360 int mbedErr = mbedtls_pk_sign(&pc->localPrivateKey,
114361 MBEDTLS_MD_SHA256, hash,
114362 UA_SHA256_LENGTH, signature->data,
114363#if MBEDTLS_VERSION_NUMBER >= 0x03000000
114364 signature->length,
114365#endif
114366 &sigLen, mbedtls_ctr_drbg_random,
114367 &pc->drbgContext);
114368 if(mbedErr)
114369 return UA_STATUSCODE_BADINTERNALERROR;
114370 return UA_STATUSCODE_GOOD;
114371}
114372
114373static size_t
114374asym_cert_getLocalSignatureSize_sp_aes256sha256rsapss(const Aes256Sha256RsaPss_ChannelContext *cc) {
114375 if(cc == NULL)
114376 return 0;
114377#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
114378 return mbedtls_pk_rsa(cc->policyContext->localPrivateKey)->len;
114379#else
114380 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->policyContext->localPrivateKey));
114381#endif
114382}
114383
114384static size_t
114385asym_cert_getRemoteSignatureSize_sp_aes256sha256rsapss(const Aes256Sha256RsaPss_ChannelContext *cc) {
114386 if(cc == NULL)
114387 return 0;
114388#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
114389 return mbedtls_pk_rsa(cc->remoteCertificate.pk)->len;
114390#else
114391 return mbedtls_rsa_get_len(mbedtls_pk_rsa(cc->remoteCertificate.pk));
114392#endif
114393}
114394
114395/*****************/
114396/* ChannelModule */
114397/*****************/
114398
114399/* Assumes that the certificate has been verified externally */
114400static UA_StatusCode
114401parseRemoteCertificate_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
114402 const UA_ByteString *remoteCertificate) {
114403 if(remoteCertificate == NULL || cc == NULL)
114404 return UA_STATUSCODE_BADINTERNALERROR;
114405
114406 /* Parse the certificate */
114407 int mbedErr = mbedtls_x509_crt_parse(&cc->remoteCertificate, remoteCertificate->data,
114408 remoteCertificate->length);
114409 if(mbedErr)
114410 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
114411
114412 /* Check the key length */
114413 mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk);
114414#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
114415 size_t keylen = rsaContext->len;
114416#else
114417 size_t keylen = mbedtls_rsa_get_len(rsaContext);
114418#endif
114419 if(keylen < UA_SECURITYPOLICY_AES256SHA256RSAPSS_MINASYMKEYLENGTH ||
114420 keylen > UA_SECURITYPOLICY_AES256SHA256RSAPSS_MAXASYMKEYLENGTH)
114421 return UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED;
114422 return UA_STATUSCODE_GOOD;
114423}
114424
114425static void
114426channelContext_deleteContext_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc) {
114427 UA_ByteString_clear(&cc->localSymSigningKey);
114428 UA_ByteString_clear(&cc->localSymEncryptingKey);
114429 UA_ByteString_clear(&cc->localSymIv);
114430
114431 UA_ByteString_clear(&cc->remoteSymSigningKey);
114432 UA_ByteString_clear(&cc->remoteSymEncryptingKey);
114433 UA_ByteString_clear(&cc->remoteSymIv);
114434
114435 mbedtls_x509_crt_free(&cc->remoteCertificate);
114436
114437 UA_free(cc);
114438}
114439
114440static UA_StatusCode
114441channelContext_newContext_sp_aes256sha256rsapss(const UA_SecurityPolicy *securityPolicy,
114442 const UA_ByteString *remoteCertificate,
114443 void **pp_contextData) {
114444 if(securityPolicy == NULL || remoteCertificate == NULL || pp_contextData == NULL)
114445 return UA_STATUSCODE_BADINTERNALERROR;
114446
114447 /* Allocate the channel context */
114448 *pp_contextData = UA_malloc(sizeof(Aes256Sha256RsaPss_ChannelContext));
114449 if(*pp_contextData == NULL)
114450 return UA_STATUSCODE_BADOUTOFMEMORY;
114451
114452 Aes256Sha256RsaPss_ChannelContext *cc = (Aes256Sha256RsaPss_ChannelContext *)*pp_contextData;
114453
114454 /* Initialize the channel context */
114455 cc->policyContext = (Aes256Sha256RsaPss_PolicyContext *)securityPolicy->policyContext;
114456
114457 UA_ByteString_init(&cc->localSymSigningKey);
114458 UA_ByteString_init(&cc->localSymEncryptingKey);
114459 UA_ByteString_init(&cc->localSymIv);
114460
114461 UA_ByteString_init(&cc->remoteSymSigningKey);
114462 UA_ByteString_init(&cc->remoteSymEncryptingKey);
114463 UA_ByteString_init(&cc->remoteSymIv);
114464
114465 mbedtls_x509_crt_init(&cc->remoteCertificate);
114466
114467 // TODO: this can be optimized so that we dont allocate memory before parsing the certificate
114468 UA_StatusCode retval = parseRemoteCertificate_sp_aes256sha256rsapss(cc, remoteCertificate);
114469 if(retval != UA_STATUSCODE_GOOD) {
114470 channelContext_deleteContext_sp_aes256sha256rsapss(cc);
114471 *pp_contextData = NULL;
114472 }
114473 return retval;
114474}
114475
114476static UA_StatusCode
114477channelContext_setLocalSymEncryptingKey_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
114478 const UA_ByteString *key) {
114479 if(key == NULL || cc == NULL)
114480 return UA_STATUSCODE_BADINTERNALERROR;
114481
114482 UA_ByteString_clear(&cc->localSymEncryptingKey);
114483 return UA_ByteString_copy(key, &cc->localSymEncryptingKey);
114484}
114485
114486static UA_StatusCode
114487channelContext_setLocalSymSigningKey_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
114488 const UA_ByteString *key) {
114489 if(key == NULL || cc == NULL)
114490 return UA_STATUSCODE_BADINTERNALERROR;
114491
114492 UA_ByteString_clear(&cc->localSymSigningKey);
114493 return UA_ByteString_copy(key, &cc->localSymSigningKey);
114494}
114495
114496
114497static UA_StatusCode
114498channelContext_setLocalSymIv_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
114499 const UA_ByteString *iv) {
114500 if(iv == NULL || cc == NULL)
114501 return UA_STATUSCODE_BADINTERNALERROR;
114502
114503 UA_ByteString_clear(&cc->localSymIv);
114504 return UA_ByteString_copy(iv, &cc->localSymIv);
114505}
114506
114507static UA_StatusCode
114508channelContext_setRemoteSymEncryptingKey_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
114509 const UA_ByteString *key) {
114510 if(key == NULL || cc == NULL)
114511 return UA_STATUSCODE_BADINTERNALERROR;
114512
114513 UA_ByteString_clear(&cc->remoteSymEncryptingKey);
114514 return UA_ByteString_copy(key, &cc->remoteSymEncryptingKey);
114515}
114516
114517static UA_StatusCode
114518channelContext_setRemoteSymSigningKey_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
114519 const UA_ByteString *key) {
114520 if(key == NULL || cc == NULL)
114521 return UA_STATUSCODE_BADINTERNALERROR;
114522
114523 UA_ByteString_clear(&cc->remoteSymSigningKey);
114524 return UA_ByteString_copy(key, &cc->remoteSymSigningKey);
114525}
114526
114527static UA_StatusCode
114528channelContext_setRemoteSymIv_sp_aes256sha256rsapss(Aes256Sha256RsaPss_ChannelContext *cc,
114529 const UA_ByteString *iv) {
114530 if(iv == NULL || cc == NULL)
114531 return UA_STATUSCODE_BADINTERNALERROR;
114532
114533 UA_ByteString_clear(&cc->remoteSymIv);
114534 return UA_ByteString_copy(iv, &cc->remoteSymIv);
114535}
114536
114537static UA_StatusCode
114538channelContext_compareCertificate_sp_aes256sha256rsapss(const Aes256Sha256RsaPss_ChannelContext *cc,
114539 const UA_ByteString *certificate) {
114540 if(cc == NULL || certificate == NULL)
114541 return UA_STATUSCODE_BADINTERNALERROR;
114542
114543 mbedtls_x509_crt cert;
114544 mbedtls_x509_crt_init(&cert);
114545 int mbedErr = mbedtls_x509_crt_parse(&cert, certificate->data, certificate->length);
114546 if(mbedErr)
114547 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
114548
114549 UA_StatusCode retval = UA_STATUSCODE_GOOD;
114550 if(cert.raw.len != cc->remoteCertificate.raw.len ||
114551 memcmp(cert.raw.p, cc->remoteCertificate.raw.p, cert.raw.len) != 0)
114552 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
114553
114554 mbedtls_x509_crt_free(&cert);
114555 return retval;
114556}
114557
114558static void
114559clear_sp_aes256sha256rsapss(UA_SecurityPolicy *securityPolicy) {
114560 if(securityPolicy == NULL)
114561 return;
114562
114563 UA_ByteString_clear(&securityPolicy->localCertificate);
114564
114565 if(securityPolicy->policyContext == NULL)
114566 return;
114567
114568 /* delete all allocated members in the context */
114569 Aes256Sha256RsaPss_PolicyContext *pc = (Aes256Sha256RsaPss_PolicyContext *)
114570 securityPolicy->policyContext;
114571
114572 mbedtls_ctr_drbg_free(&pc->drbgContext);
114573 mbedtls_entropy_free(&pc->entropyContext);
114574 mbedtls_pk_free(&pc->localPrivateKey);
114575 mbedtls_md_free(&pc->sha256MdContext);
114576 UA_ByteString_clear(&pc->localCertThumbprint);
114577
114578 UA_LOG_DEBUG(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
114579 "Deleted members of EndpointContext for sp_aes256sha256rsapss");
114580
114581 UA_free(pc);
114582 securityPolicy->policyContext = NULL;
114583}
114584
114585static UA_StatusCode
114586updateCertificateAndPrivateKey_sp_aes256sha256rsapss(UA_SecurityPolicy *securityPolicy,
114587 const UA_ByteString newCertificate,
114588 const UA_ByteString newPrivateKey) {
114589 if(securityPolicy == NULL)
114590 return UA_STATUSCODE_BADINTERNALERROR;
114591
114592 if(securityPolicy->policyContext == NULL)
114593 return UA_STATUSCODE_BADINTERNALERROR;
114594
114595 Aes256Sha256RsaPss_PolicyContext *pc =
114596 (Aes256Sha256RsaPss_PolicyContext *) securityPolicy->policyContext;
114597
114598 UA_ByteString_clear(&securityPolicy->localCertificate);
114599
114600 UA_StatusCode retval = UA_mbedTLS_LoadLocalCertificate(&newCertificate, &securityPolicy->localCertificate);
114601
114602 if(retval != UA_STATUSCODE_GOOD)
114603 return retval;
114604
114605 /* Set the new private key */
114606 mbedtls_pk_free(&pc->localPrivateKey);
114607 mbedtls_pk_init(&pc->localPrivateKey);
114608 int mbedErr = UA_mbedTLS_LoadPrivateKey(&newPrivateKey, &pc->localPrivateKey, &pc->entropyContext);
114609 if(mbedErr) {
114610 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
114611 goto error;
114612 }
114613
114614 retval = asym_makeThumbprint_sp_aes256sha256rsapss(securityPolicy,
114615 &securityPolicy->localCertificate,
114616 &pc->localCertThumbprint);
114617 if(retval != UA_STATUSCODE_GOOD)
114618 goto error;
114619
114620 return retval;
114621
114622error:
114623 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
114624 "Could not update certificate and private key");
114625 if(securityPolicy->policyContext != NULL)
114626 clear_sp_aes256sha256rsapss(securityPolicy);
114627 return retval;
114628}
114629
114630static UA_StatusCode
114631policyContext_newContext_sp_aes256sha256rsapss(UA_SecurityPolicy *securityPolicy,
114632 const UA_ByteString localPrivateKey) {
114633 UA_StatusCode retval = UA_STATUSCODE_GOOD;
114634 if(securityPolicy == NULL)
114635 return UA_STATUSCODE_BADINTERNALERROR;
114636
114637 if (localPrivateKey.length == 0) {
114638 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
114639 "Can not initialize security policy. Private key is empty.");
114640 return UA_STATUSCODE_BADINVALIDARGUMENT;
114641 }
114642
114643 Aes256Sha256RsaPss_PolicyContext *pc = (Aes256Sha256RsaPss_PolicyContext *)
114644 UA_malloc(sizeof(Aes256Sha256RsaPss_PolicyContext));
114645 securityPolicy->policyContext = (void *)pc;
114646 if(!pc) {
114647 retval = UA_STATUSCODE_BADOUTOFMEMORY;
114648 goto error;
114649 }
114650
114651 /* Initialize the PolicyContext */
114652 memset(pc, 0, sizeof(Aes256Sha256RsaPss_PolicyContext));
114653 mbedtls_ctr_drbg_init(&pc->drbgContext);
114654 mbedtls_entropy_init(&pc->entropyContext);
114655 mbedtls_pk_init(&pc->localPrivateKey);
114656 mbedtls_md_init(&pc->sha256MdContext);
114657
114658 /* Initialized the message digest */
114659 const mbedtls_md_info_t *const mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
114660 int mbedErr = mbedtls_md_setup(&pc->sha256MdContext, mdInfo, MBEDTLS_MD_SHA256);
114661 if(mbedErr) {
114662 retval = UA_STATUSCODE_BADOUTOFMEMORY;
114663 goto error;
114664 }
114665
114666 mbedErr = mbedtls_entropy_self_test(0);
114667
114668 if(mbedErr) {
114669 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
114670 goto error;
114671 }
114672
114673 /* Seed the RNG */
114674 char *personalization = "open62541-drbg";
114675 mbedErr = mbedtls_ctr_drbg_seed(&pc->drbgContext, mbedtls_entropy_func,
114676 &pc->entropyContext,
114677 (const unsigned char *)personalization, 14);
114678 if(mbedErr) {
114679 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
114680 goto error;
114681 }
114682
114683 /* Set the private key */
114684 mbedErr = UA_mbedTLS_LoadPrivateKey(&localPrivateKey, &pc->localPrivateKey, &pc->entropyContext);
114685 if(mbedErr) {
114686 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
114687 goto error;
114688 }
114689
114690 /* Set the local certificate thumbprint */
114691 retval = UA_ByteString_allocBuffer(&pc->localCertThumbprint, UA_SHA1_LENGTH);
114692 if(retval != UA_STATUSCODE_GOOD)
114693 goto error;
114694 retval = asym_makeThumbprint_sp_aes256sha256rsapss(securityPolicy,
114695 &securityPolicy->localCertificate,
114696 &pc->localCertThumbprint);
114697 if(retval != UA_STATUSCODE_GOOD)
114698 goto error;
114699
114700 return UA_STATUSCODE_GOOD;
114701
114702error:
114703 UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY,
114704 "Could not create securityContext: %s", UA_StatusCode_name(retval));
114705 if(securityPolicy->policyContext != NULL)
114706 clear_sp_aes256sha256rsapss(securityPolicy);
114707 return retval;
114708}
114709
114710UA_StatusCode
114711UA_SecurityPolicy_Aes256Sha256RsaPss(UA_SecurityPolicy *policy, const UA_ByteString localCertificate,
114712 const UA_ByteString localPrivateKey, const UA_Logger *logger) {
114713 memset(policy, 0, sizeof(UA_SecurityPolicy));
114714 policy->logger = logger;
114715
114716 policy->policyUri = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#Aes256_Sha256_RsaPss");
114717
114718 UA_SecurityPolicyAsymmetricModule *const asymmetricModule = &policy->asymmetricModule;
114719 UA_SecurityPolicySymmetricModule *const symmetricModule = &policy->symmetricModule;
114720 UA_SecurityPolicyChannelModule *const channelModule = &policy->channelModule;
114721
114722 UA_StatusCode retval = UA_mbedTLS_LoadLocalCertificate(&localCertificate, &policy->localCertificate);
114723
114724 if (retval != UA_STATUSCODE_GOOD)
114725 return retval;
114726
114727 /* AsymmetricModule */
114728 UA_SecurityPolicySignatureAlgorithm *asym_signatureAlgorithm =
114729 &asymmetricModule->cryptoModule.signatureAlgorithm;
114730 asym_signatureAlgorithm->uri =
114731 UA_STRING("http://opcfoundation.org/UA/security/rsa-pss-sha2-256\0");
114732 asym_signatureAlgorithm->verify =
114733 (UA_StatusCode (*)(void *, const UA_ByteString *, const UA_ByteString *))asym_verify_sp_aes256sha256rsapss;
114734 asym_signatureAlgorithm->sign =
114735 (UA_StatusCode (*)(void *, const UA_ByteString *, UA_ByteString *))asym_sign_sp_aes256sha256rsapss;
114736 asym_signatureAlgorithm->getLocalSignatureSize =
114737 (size_t (*)(const void *))asym_getLocalSignatureSize_sp_aes256sha256rsapss;
114738 asym_signatureAlgorithm->getRemoteSignatureSize =
114739 (size_t (*)(const void *))asym_getRemoteSignatureSize_sp_aes256sha256rsapss;
114740 asym_signatureAlgorithm->getLocalKeyLength = NULL; // TODO: Write function
114741 asym_signatureAlgorithm->getRemoteKeyLength = NULL; // TODO: Write function
114742
114743 UA_SecurityPolicyEncryptionAlgorithm *asym_encryptionAlgorithm =
114744 &asymmetricModule->cryptoModule.encryptionAlgorithm;
114745 asym_encryptionAlgorithm->uri = UA_STRING("http://opcfoundation.org/UA/security/rsa-oaep-sha2-256\0");
114746 asym_encryptionAlgorithm->encrypt =
114747 (UA_StatusCode(*)(void *, UA_ByteString *))asym_encrypt_sp_aes256sha256rsapss;
114748 asym_encryptionAlgorithm->decrypt =
114749 (UA_StatusCode(*)(void *, UA_ByteString *)) asym_decrypt_sp_aes256sha256rsapss;
114750 asym_encryptionAlgorithm->getLocalKeyLength =
114751 (size_t (*)(const void *))asym_getLocalEncryptionKeyLength_sp_aes256sha256rsapss;
114752 asym_encryptionAlgorithm->getRemoteKeyLength =
114753 (size_t (*)(const void *))asym_getRemoteEncryptionKeyLength_sp_aes256sha256rsapss;
114754 asym_encryptionAlgorithm->getRemoteBlockSize = (size_t (*)(const void *))asym_getRemoteBlockSize_sp_aes256sha256rsapss;
114755 asym_encryptionAlgorithm->getRemotePlainTextBlockSize =
114756 (size_t (*)(const void *))asym_getRemotePlainTextBlockSize_sp_aes256sha256rsapss;
114757
114758 asymmetricModule->makeCertificateThumbprint = asym_makeThumbprint_sp_aes256sha256rsapss;
114759 asymmetricModule->compareCertificateThumbprint =
114760 asymmetricModule_compareCertificateThumbprint_sp_aes256sha256rsapss;
114761
114762 /* SymmetricModule */
114763 symmetricModule->generateKey = sym_generateKey_sp_aes256sha256rsapss;
114764 symmetricModule->generateNonce = sym_generateNonce_sp_aes256sha256rsapss;
114765
114766 UA_SecurityPolicySignatureAlgorithm *sym_signatureAlgorithm =
114767 &symmetricModule->cryptoModule.signatureAlgorithm;
114768 sym_signatureAlgorithm->uri =
114769 UA_STRING("http://www.w3.org/2000/09/xmldsig#hmac-sha2-256\0");
114770 sym_signatureAlgorithm->verify =
114771 (UA_StatusCode (*)(void *, const UA_ByteString *, const UA_ByteString *))sym_verify_sp_aes256sha256rsapss;
114772 sym_signatureAlgorithm->sign =
114773 (UA_StatusCode (*)(void *, const UA_ByteString *, UA_ByteString *))sym_sign_sp_aes256sha256rsapss;
114774 sym_signatureAlgorithm->getLocalSignatureSize = sym_getSignatureSize_sp_aes256sha256rsapss;
114775 sym_signatureAlgorithm->getRemoteSignatureSize = sym_getSignatureSize_sp_aes256sha256rsapss;
114776 sym_signatureAlgorithm->getLocalKeyLength =
114777 (size_t (*)(const void *))sym_getSigningKeyLength_sp_aes256sha256rsapss;
114778 sym_signatureAlgorithm->getRemoteKeyLength =
114779 (size_t (*)(const void *))sym_getSigningKeyLength_sp_aes256sha256rsapss;
114780
114781 UA_SecurityPolicyEncryptionAlgorithm *sym_encryptionAlgorithm =
114782 &symmetricModule->cryptoModule.encryptionAlgorithm;
114783 sym_encryptionAlgorithm->uri = UA_STRING("http://www.w3.org/2001/04/xmlenc#aes256-cbc\0");
114784 sym_encryptionAlgorithm->encrypt =
114785 (UA_StatusCode(*)(void *, UA_ByteString *))sym_encrypt_sp_aes256sha256rsapss;
114786 sym_encryptionAlgorithm->decrypt =
114787 (UA_StatusCode(*)(void *, UA_ByteString *))sym_decrypt_sp_aes256sha256rsapss;
114788 sym_encryptionAlgorithm->getLocalKeyLength = sym_getEncryptionKeyLength_sp_aes256sha256rsapss;
114789 sym_encryptionAlgorithm->getRemoteKeyLength = sym_getEncryptionKeyLength_sp_aes256sha256rsapss;
114790 sym_encryptionAlgorithm->getRemoteBlockSize =
114791 (size_t (*)(const void *))sym_getEncryptionBlockSize_sp_aes256sha256rsapss;
114792 sym_encryptionAlgorithm->getRemotePlainTextBlockSize =
114793 (size_t (*)(const void *))sym_getPlainTextBlockSize_sp_aes256sha256rsapss;
114794 symmetricModule->secureChannelNonceLength = 32;
114795
114796 /* Certificate Signing Algorithm */
114797 policy->certificateSigningAlgorithm.uri =
114798 UA_STRING("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\0");
114799 policy->certificateSigningAlgorithm.verify =
114800 (UA_StatusCode (*)(void *, const UA_ByteString *, const UA_ByteString *))asym_cert_verify_sp_aes256sha256rsapss;
114801 policy->certificateSigningAlgorithm.sign =
114802 (UA_StatusCode (*)(void *, const UA_ByteString *, UA_ByteString *))asym_cert_sign_sp_aes256sha256rsapss;
114803 policy->certificateSigningAlgorithm.getLocalSignatureSize =
114804 (size_t (*)(const void *))asym_cert_getLocalSignatureSize_sp_aes256sha256rsapss;
114805 policy->certificateSigningAlgorithm.getRemoteSignatureSize =
114806 (size_t (*)(const void *))asym_cert_getRemoteSignatureSize_sp_aes256sha256rsapss;
114807 policy->certificateSigningAlgorithm.getLocalKeyLength = NULL; // TODO: Write function
114808 policy->certificateSigningAlgorithm.getRemoteKeyLength = NULL; // TODO: Write function
114809
114810 /* ChannelModule */
114811 channelModule->newContext = channelContext_newContext_sp_aes256sha256rsapss;
114812 channelModule->deleteContext = (void (*)(void *))
114813 channelContext_deleteContext_sp_aes256sha256rsapss;
114814
114815 channelModule->setLocalSymEncryptingKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
114816 channelContext_setLocalSymEncryptingKey_sp_aes256sha256rsapss;
114817 channelModule->setLocalSymSigningKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
114818 channelContext_setLocalSymSigningKey_sp_aes256sha256rsapss;
114819 channelModule->setLocalSymIv = (UA_StatusCode (*)(void *, const UA_ByteString *))
114820 channelContext_setLocalSymIv_sp_aes256sha256rsapss;
114821
114822 channelModule->setRemoteSymEncryptingKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
114823 channelContext_setRemoteSymEncryptingKey_sp_aes256sha256rsapss;
114824 channelModule->setRemoteSymSigningKey = (UA_StatusCode (*)(void *, const UA_ByteString *))
114825 channelContext_setRemoteSymSigningKey_sp_aes256sha256rsapss;
114826 channelModule->setRemoteSymIv = (UA_StatusCode (*)(void *, const UA_ByteString *))
114827 channelContext_setRemoteSymIv_sp_aes256sha256rsapss;
114828
114829 channelModule->compareCertificate = (UA_StatusCode (*)(const void *, const UA_ByteString *))
114830 channelContext_compareCertificate_sp_aes256sha256rsapss;
114831
114832 policy->updateCertificateAndPrivateKey = updateCertificateAndPrivateKey_sp_aes256sha256rsapss;
114833 policy->clear = clear_sp_aes256sha256rsapss;
114834
114835 UA_StatusCode res = policyContext_newContext_sp_aes256sha256rsapss(policy, localPrivateKey);
114836 if(res != UA_STATUSCODE_GOOD)
114837 clear_sp_aes256sha256rsapss(policy);
114838
114839 return res;
114840}
114841
114842#endif
114843
114844/**** amalgamated original file "/plugins/crypto/mbedtls/ua_mbedtls_create_certificate.c" ****/
114845
114846/* This Source Code Form is subject to the terms of the Mozilla Public
114847 * License, v. 2.0. If a copy of the MPL was not distributed with this
114848 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
114849 *
114850 * Copyright (c) 2023 Fraunhofer IOSB (Author: Noel Graf)
114851 *
114852 */
114853
114854#include <time.h>
114855
114856
114857#if defined(UA_ENABLE_ENCRYPTION_MBEDTLS)
114858
114859#include <mbedtls/x509_crt.h>
114860#include <mbedtls/oid.h>
114861#include <mbedtls/asn1write.h>
114862#include <mbedtls/entropy.h>
114863#include <mbedtls/ctr_drbg.h>
114864#include <mbedtls/platform.h>
114865#include <mbedtls/version.h>
114866
114867#define SET_OID(x, oid) \
114868 do { x.len = MBEDTLS_OID_SIZE(oid); x.p = (unsigned char *) oid; } while (0)
114869
114870#define MBEDTLS_ASN1_CHK_CLEANUP_ADD(g, f) \
114871 do \
114872 { \
114873 if ((ret = (f)) < 0) \
114874 goto cleanup; \
114875 else \
114876 (g) += ret; \
114877 } while (0)
114878
114879#if MBEDTLS_VERSION_NUMBER < 0x02170000
114880#define MBEDTLS_X509_SAN_OTHER_NAME 0
114881#define MBEDTLS_X509_SAN_RFC822_NAME 1
114882#define MBEDTLS_X509_SAN_DNS_NAME 2
114883#define MBEDTLS_X509_SAN_X400_ADDRESS_NAME 3
114884#define MBEDTLS_X509_SAN_DIRECTORY_NAME 4
114885#define MBEDTLS_X509_SAN_EDI_PARTY_NAME 5
114886#define MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER 6
114887#define MBEDTLS_X509_SAN_IP_ADDRESS 7
114888#define MBEDTLS_X509_SAN_REGISTERED_ID 8
114889#endif
114890
114891#define MBEDTLS_SAN_MAX_LEN 64
114892typedef struct mbedtls_write_san_node{
114893 int type;
114894 char* host;
114895 size_t hostlen;
114896} mbedtls_write_san_node;
114897
114898typedef struct mbedtls_write_san_list{
114899 mbedtls_write_san_node node;
114900 struct mbedtls_write_san_list* next;
114901} mbedtls_write_san_list;
114902
114903static size_t mbedtls_get_san_list_deep(const mbedtls_write_san_list* sanlist);
114904
114905int mbedtls_x509write_crt_set_subject_alt_name(mbedtls_x509write_cert *ctx, const mbedtls_write_san_list* sanlist);
114906
114907#if MBEDTLS_VERSION_NUMBER < 0x03030000
114908int mbedtls_x509write_crt_set_ext_key_usage(mbedtls_x509write_cert *ctx,
114909 const mbedtls_asn1_sequence *exts);
114910#endif
114911
114912static int write_certificate(mbedtls_x509write_cert *crt, UA_CertificateFormat certFormat,
114913 UA_ByteString *outCertificate, int (*f_rng)(void *, unsigned char *, size_t),
114914 void *p_rng);
114915
114916static int write_private_key(mbedtls_pk_context *key, UA_CertificateFormat keyFormat, UA_ByteString *outPrivateKey);
114917
114918UA_StatusCode
114919UA_CreateCertificate(const UA_Logger *logger, const UA_String *subject,
114920 size_t subjectSize, const UA_String *subjectAltName,
114921 size_t subjectAltNameSize, UA_CertificateFormat certFormat,
114922 UA_KeyValueMap *params, UA_ByteString *outPrivateKey,
114923 UA_ByteString *outCertificate) {
114924 if(!outPrivateKey || !outCertificate || !logger || !subjectAltName || !subject ||
114925 subjectAltNameSize == 0 || subjectSize == 0 ||
114926 (certFormat != UA_CERTIFICATEFORMAT_DER && certFormat != UA_CERTIFICATEFORMAT_PEM))
114927 return UA_STATUSCODE_BADINVALIDARGUMENT;
114928
114929 /* Use the maximum size */
114930 UA_UInt16 keySizeBits = 4096;
114931 /* Default to 1 year */
114932 UA_UInt16 expiresInDays = 365;
114933
114934 if(params) {
114935 const UA_UInt16 *keySizeBitsValue = (const UA_UInt16 *)UA_KeyValueMap_getScalar(
114936 params, UA_QUALIFIEDNAME(0, "key-size-bits"), &UA_TYPES[UA_TYPES_UINT16]);
114937 if(keySizeBitsValue)
114938 keySizeBits = *keySizeBitsValue;
114939
114940 const UA_UInt16 *expiresInDaysValue = (const UA_UInt16 *)UA_KeyValueMap_getScalar(
114941 params, UA_QUALIFIEDNAME(0, "expires-in-days"), &UA_TYPES[UA_TYPES_UINT16]);
114942 if(expiresInDaysValue)
114943 expiresInDays = *expiresInDaysValue;
114944 }
114945
114946 UA_ByteString_init(outPrivateKey);
114947 UA_ByteString_init(outCertificate);
114948
114949 mbedtls_pk_context key;
114950 mbedtls_ctr_drbg_context ctr_drbg;
114951 mbedtls_entropy_context entropy;
114952 const char *pers = "gen_key";
114953 mbedtls_x509write_cert crt;
114954
114955 UA_StatusCode errRet = UA_STATUSCODE_GOOD;
114956
114957 /* Set to sane values */
114958 mbedtls_pk_init(&key);
114959 mbedtls_ctr_drbg_init(&ctr_drbg);
114960 mbedtls_entropy_init(&entropy);
114961 mbedtls_x509write_crt_init(&crt);
114962
114963 /* Seed the random number generator */
114964 if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *)pers, strlen(pers)) != 0) {
114965 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
114966 "Failed to initialize the random number generator.");
114967 errRet = UA_STATUSCODE_BADINTERNALERROR;
114968 goto cleanup;
114969 }
114970
114971 /* Generate an RSA key pair */
114972 if (mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) != 0 ||
114973 mbedtls_rsa_gen_key(mbedtls_pk_rsa(key), mbedtls_ctr_drbg_random, &ctr_drbg, keySizeBits, 65537) != 0) {
114974 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
114975 "Failed to generate RSA key pair.");
114976 errRet = UA_STATUSCODE_BADINTERNALERROR;
114977 goto cleanup;
114978 }
114979
114980 /* Setting certificate values */
114981 mbedtls_x509write_crt_set_version(&crt, MBEDTLS_X509_CRT_VERSION_3);
114982 mbedtls_x509write_crt_set_md_alg(&crt, MBEDTLS_MD_SHA256);
114983
114984 size_t subject_char_len = 0;
114985 for(size_t i = 0; i < subjectSize; i++) {
114986 subject_char_len += subject[i].length;
114987 }
114988 char *subject_char = (char*)UA_malloc(subject_char_len + subjectSize);
114989 if(!subject_char) {
114990 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
114991 "Cannot allocate memory for subject. Out of memory.");
114992 errRet = UA_STATUSCODE_BADOUTOFMEMORY;
114993 goto cleanup;
114994 }
114995
114996 size_t pos = 0;
114997 for(size_t i = 0; i < subjectSize; i++) {
114998 subject_char_len += subject[i].length;
114999 memcpy(subject_char + pos, subject[i].data, subject[i].length);
115000 pos += subject[i].length;
115001 if(i < subjectSize - 1)
115002 subject_char[pos++] = ',';
115003 else
115004 subject_char[pos++] = '\0';
115005 }
115006
115007 if((mbedtls_x509write_crt_set_subject_name(&crt, subject_char)) != 0) {
115008 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
115009 "Setting subject failed.");
115010 errRet = UA_STATUSCODE_BADINTERNALERROR;
115011 UA_free(subject_char);
115012 goto cleanup;
115013 }
115014
115015 if((mbedtls_x509write_crt_set_issuer_name(&crt, subject_char)) != 0) {
115016 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
115017 "Setting issuer failed.");
115018 errRet = UA_STATUSCODE_BADINTERNALERROR;
115019 UA_free(subject_char);
115020 goto cleanup;
115021 }
115022
115023 UA_free(subject_char);
115024
115025 mbedtls_write_san_list *cur = NULL;
115026 mbedtls_write_san_list *cur_tmp = NULL;
115027 mbedtls_write_san_list *head = NULL;
115028 for(size_t i = 0; i < subjectAltNameSize; i++) {
115029 char *sanType;
115030 char *sanValue;
115031 size_t sanValueLength;
115032 char *subAlt = (char *)UA_malloc(subjectAltName[i].length + 1);
115033 memcpy(subAlt, subjectAltName[i].data, subjectAltName[i].length);
115034
115035 /* null-terminate the copied string */
115036 subAlt[subjectAltName[i].length] = 0;
115037 /* split into SAN type and value */
115038 sanType = strtok(subAlt, ":");
115039 sanValue = (char *)subjectAltName[i].data + strlen(sanType) + 1;
115040 sanValueLength = subjectAltName[i].length - strlen(sanType) - 1;
115041
115042 if(sanType) {
115043 cur_tmp = (mbedtls_write_san_list*)mbedtls_calloc(1, sizeof(mbedtls_write_san_list));
115044 cur_tmp->next = NULL;
115045 cur_tmp->node.host = sanValue;
115046 cur_tmp->node.hostlen = sanValueLength;
115047
115048 if(strcmp(sanType, "DNS") == 0) {
115049 cur_tmp->node.type = MBEDTLS_X509_SAN_DNS_NAME;
115050 } else if(strcmp(sanType, "URI") == 0) {
115051 cur_tmp->node.type = MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER;
115052 } else if(strcmp(sanType, "IP") == 0) {
115053 uint8_t ip[4] = {0};
115054 if(UA_inet_pton(AF_INET, sanValue, ip) <= 0) {
115055 UA_LOG_WARNING(logger, UA_LOGCATEGORY_SECURECHANNEL, "IP SAN preparation failed");
115056 mbedtls_free(cur_tmp);
115057 UA_free(subAlt);
115058 continue;
115059 }
115060 cur_tmp->node.type = MBEDTLS_X509_SAN_IP_ADDRESS;
115061 cur_tmp->node.host = (char *)ip;
115062 cur_tmp->node.hostlen = sizeof(ip);
115063 } else if(strcmp(sanType, "RFC822") == 0) {
115064 cur_tmp->node.type = MBEDTLS_X509_SAN_RFC822_NAME;
115065 } else {
115066 UA_LOG_WARNING(logger, UA_LOGCATEGORY_SECURECHANNEL, "Given an unsupported SAN");
115067 mbedtls_free(cur_tmp);
115068 UA_free(subAlt);
115069 continue;
115070 }
115071 } else {
115072 UA_LOG_WARNING(logger, UA_LOGCATEGORY_SECURECHANNEL, "Invalid Input format");
115073 UA_free(subAlt);
115074 continue;
115075 }
115076
115077 if(!cur) {
115078 cur = cur_tmp;
115079 head = cur_tmp;
115080 } else {
115081 cur->next = cur_tmp;
115082 cur = cur->next;
115083 }
115084
115085 UA_free(subAlt);
115086 }
115087
115088 if((mbedtls_x509write_crt_set_subject_alt_name(&crt, head)) != 0) {
115089 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
115090 "Setting subject alternative name failed.");
115091 errRet = UA_STATUSCODE_BADINTERNALERROR;
115092 while(head != NULL) {
115093 cur_tmp = head->next;
115094 mbedtls_free(head);
115095 head = cur_tmp;
115096 }
115097 goto cleanup;
115098 }
115099
115100 while(head != NULL) {
115101 cur_tmp = head->next;
115102 mbedtls_free(head);
115103 head = cur_tmp;
115104 }
115105
115106#if MBEDTLS_VERSION_NUMBER >= 0x03040000
115107 unsigned char *serial = (unsigned char *)"1";
115108 size_t serial_len = 1;
115109 mbedtls_x509write_crt_set_serial_raw(&crt, serial, serial_len);
115110#else
115111 mbedtls_mpi serial_mpi;
115112 mbedtls_mpi_init(&serial_mpi);
115113 mbedtls_mpi_lset(&serial_mpi, 1);
115114 mbedtls_x509write_crt_set_serial(&crt, &serial_mpi);
115115 mbedtls_mpi_free(&serial_mpi);
115116#endif
115117
115118 /* Get the current time */
115119 time_t rawTime;
115120 struct tm *timeInfo;
115121 time(&rawTime);
115122 timeInfo = gmtime(&rawTime);
115123
115124 /* Format the current timestamp */
115125 char current_timestamp[15]; // YYYYMMDDhhmmss + '\0'
115126 strftime(current_timestamp, sizeof(current_timestamp), "%Y%m%d%H%M%S", timeInfo);
115127
115128 /* Calculate the future timestamp */
115129 timeInfo->tm_mday += expiresInDays;
115130 time_t future_time = mktime(timeInfo);
115131
115132 /* Format the future timestamp */
115133 char future_timestamp[15]; // YYYYMMDDhhmmss + '\0'
115134 strftime(future_timestamp, sizeof(future_timestamp), "%Y%m%d%H%M%S", gmtime(&future_time));
115135
115136 if(mbedtls_x509write_crt_set_validity(&crt, current_timestamp, future_timestamp) != 0) {
115137 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
115138 "Setting 'not before' and 'not after' failed.");
115139 errRet = UA_STATUSCODE_BADINTERNALERROR;
115140 goto cleanup;
115141 }
115142
115143 if(mbedtls_x509write_crt_set_basic_constraints(&crt, 0, -1) != 0) {
115144 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
115145 "Setting basic constraints failed.");
115146 errRet = UA_STATUSCODE_BADINTERNALERROR;
115147 goto cleanup;
115148 }
115149
115150 if(mbedtls_x509write_crt_set_key_usage(&crt, MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_NON_REPUDIATION
115151 | MBEDTLS_X509_KU_KEY_ENCIPHERMENT | MBEDTLS_X509_KU_DATA_ENCIPHERMENT
115152 | MBEDTLS_X509_KU_KEY_CERT_SIGN | MBEDTLS_X509_KU_CRL_SIGN) != 0) {
115153 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
115154 "Setting key usage failed.");
115155 errRet = UA_STATUSCODE_BADINTERNALERROR;
115156 goto cleanup;
115157 }
115158
115159 mbedtls_asn1_sequence *ext_key_usage;
115160 ext_key_usage = (mbedtls_asn1_sequence *)mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
115161 ext_key_usage->buf.tag = MBEDTLS_ASN1_OID;
115162 SET_OID(ext_key_usage->buf, MBEDTLS_OID_SERVER_AUTH);
115163 ext_key_usage->next = (mbedtls_asn1_sequence *)mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
115164 ext_key_usage->next->buf.tag = MBEDTLS_ASN1_OID;
115165 SET_OID(ext_key_usage->next->buf, MBEDTLS_OID_CLIENT_AUTH);
115166
115167 if(mbedtls_x509write_crt_set_ext_key_usage(&crt, ext_key_usage) != 0) {
115168 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
115169 "Setting extended key usage failed.");
115170 errRet = UA_STATUSCODE_BADINTERNALERROR;
115171 mbedtls_free(ext_key_usage->next);
115172 mbedtls_free(ext_key_usage);
115173 goto cleanup;
115174 }
115175
115176 mbedtls_free(ext_key_usage->next);
115177 mbedtls_free(ext_key_usage);
115178
115179 mbedtls_x509write_crt_set_subject_key(&crt, &key);
115180 mbedtls_x509write_crt_set_issuer_key(&crt, &key);
115181
115182
115183 /* Write private key */
115184 if ((write_private_key(&key, certFormat, outPrivateKey)) != 0) {
115185 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
115186 "Create Certificate: Writing private key failed.");
115187 errRet = UA_STATUSCODE_BADINTERNALERROR;
115188 goto cleanup;
115189 }
115190
115191 /* Write Certificate */
115192 if ((write_certificate(&crt, certFormat, outCertificate,
115193 mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) {
115194 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
115195 "Create Certificate: Writing certificate failed.");
115196 errRet = UA_STATUSCODE_BADINTERNALERROR;
115197 goto cleanup;
115198 }
115199
115200 mbedtls_ctr_drbg_free(&ctr_drbg);
115201 mbedtls_entropy_free(&entropy);
115202 mbedtls_x509write_crt_free(&crt);
115203 mbedtls_pk_free(&key);
115204
115205cleanup:
115206 mbedtls_ctr_drbg_free(&ctr_drbg);
115207 mbedtls_entropy_free(&entropy);
115208 mbedtls_x509write_crt_free(&crt);
115209 mbedtls_pk_free(&key);
115210 return errRet;
115211}
115212
115213static int write_private_key(mbedtls_pk_context *key, UA_CertificateFormat keyFormat, UA_ByteString *outPrivateKey) {
115214 int ret;
115215 unsigned char output_buf[16000];
115216 unsigned char *c = output_buf;
115217 size_t len = 0;
115218
115219 memset(output_buf, 0, sizeof(output_buf));
115220 switch(keyFormat) {
115221 case UA_CERTIFICATEFORMAT_DER: {
115222 if((ret = mbedtls_pk_write_key_der(key, output_buf, sizeof(output_buf))) < 0) {
115223 return ret;
115224 }
115225
115226 len = ret;
115227 c = output_buf + sizeof(output_buf) - len;
115228 break;
115229 }
115230 case UA_CERTIFICATEFORMAT_PEM: {
115231 if((ret = mbedtls_pk_write_key_pem(key, output_buf, sizeof(output_buf))) != 0) {
115232 return ret;
115233 }
115234
115235 len = strlen((char *)output_buf);
115236 break;
115237 }
115238 }
115239
115240 outPrivateKey->length = len;
115241 UA_ByteString_allocBuffer(outPrivateKey, outPrivateKey->length);
115242 memcpy(outPrivateKey->data, c, outPrivateKey->length);
115243
115244 return 0;
115245}
115246
115247static int write_certificate(mbedtls_x509write_cert *crt, UA_CertificateFormat certFormat,
115248 UA_ByteString *outCertificate, int (*f_rng)(void *, unsigned char *, size_t),
115249 void *p_rng) {
115250 int ret;
115251 unsigned char output_buf[4096];
115252 unsigned char *c = output_buf;
115253 size_t len = 0;
115254
115255 memset(output_buf, 0, sizeof(output_buf));
115256 switch(certFormat) {
115257 case UA_CERTIFICATEFORMAT_DER: {
115258 if((ret = mbedtls_x509write_crt_der(crt, output_buf, sizeof(output_buf), f_rng, p_rng)) < 0) {
115259 return ret;
115260 }
115261
115262 len = ret;
115263 c = output_buf + sizeof(output_buf) - len;
115264 break;
115265 }
115266 case UA_CERTIFICATEFORMAT_PEM: {
115267 if((ret = mbedtls_x509write_crt_pem(crt, output_buf, sizeof(output_buf), f_rng, p_rng)) < 0) {
115268 return ret;
115269 }
115270
115271 len = strlen((char *)output_buf);
115272 break;
115273 }
115274 }
115275
115276 outCertificate->length = len;
115277 UA_ByteString_allocBuffer(outCertificate, outCertificate->length);
115278 memcpy(outCertificate->data, c, outCertificate->length);
115279
115280 return 0;
115281}
115282
115283#if MBEDTLS_VERSION_NUMBER < 0x03030000
115284int mbedtls_x509write_crt_set_ext_key_usage(mbedtls_x509write_cert *ctx,
115285 const mbedtls_asn1_sequence *exts) {
115286 unsigned char buf[256];
115287 unsigned char *c = buf + sizeof(buf);
115288 int ret;
115289 size_t len = 0;
115290 const mbedtls_asn1_sequence *last_ext = NULL;
115291 const mbedtls_asn1_sequence *ext;
115292
115293 memset(buf, 0, sizeof(buf));
115294
115295 /* We need at least one extension: SEQUENCE SIZE (1..MAX) OF KeyPurposeId */
115296 if(!exts) {
115297 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
115298 }
115299
115300 /* Iterate over exts backwards, so we write them out in the requested order */
115301 while(last_ext != exts) {
115302 for(ext = exts; ext->next != last_ext; ext = ext->next) {
115303 }
115304 if(ext->buf.tag != MBEDTLS_ASN1_OID) {
115305 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
115306 }
115307 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, buf, ext->buf.p, ext->buf.len));
115308 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, ext->buf.len));
115309 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_OID));
115310 last_ext = ext;
115311 }
115312
115313 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len));
115314 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
115315
115316 return mbedtls_x509write_crt_set_extension(ctx, MBEDTLS_OID_EXTENDED_KEY_USAGE,
115317 MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE), 1, c, len);
115318}
115319
115320#endif
115321
115322static size_t mbedtls_get_san_list_deep(const mbedtls_write_san_list* sanlist) {
115323 size_t ret = 0;
115324 const mbedtls_write_san_list* cur = sanlist;
115325 while (cur) {
115326 ++ret;
115327 cur = cur->next;
115328 }
115329
115330 return ret;
115331}
115332
115333int mbedtls_x509write_crt_set_subject_alt_name(mbedtls_x509write_cert *ctx, const mbedtls_write_san_list* sanlist) {
115334 int ret = 0;
115335 size_t sandeep = 0;
115336 const mbedtls_write_san_list* cur = sanlist;
115337 unsigned char* buf;
115338 unsigned char* pc;
115339 size_t len;
115340 size_t buflen = 0;
115341
115342 /* How many alt names to be written */
115343 sandeep = mbedtls_get_san_list_deep(sanlist);
115344 if (sandeep == 0)
115345 return ret;
115346
115347 buflen = MBEDTLS_SAN_MAX_LEN * sandeep + sandeep;
115348 buf = (unsigned char *)mbedtls_calloc(1, buflen);
115349 if(!buf)
115350 return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
115351
115352 memset(buf, 0, buflen);
115353 pc = buf + buflen;
115354
115355 len = 0;
115356 while(cur) {
115357 switch (cur->node.type) {
115358 case MBEDTLS_X509_SAN_DNS_NAME:
115359 case MBEDTLS_X509_SAN_RFC822_NAME:
115360 case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
115361 case MBEDTLS_X509_SAN_IP_ADDRESS:
115362 MBEDTLS_ASN1_CHK_CLEANUP_ADD(len,
115363 mbedtls_asn1_write_raw_buffer(&pc, buf, (const unsigned char *)cur->node.host,
115364 cur->node.hostlen));
115365 MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_len(&pc, buf, cur->node.hostlen));
115366 MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_tag(&pc, buf,
115367 MBEDTLS_ASN1_CONTEXT_SPECIFIC | cur->node.type));
115368 break;
115369 default:
115370 /* Error out on an unsupported SAN */
115371 ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
115372 goto cleanup;
115373 }
115374
115375 cur = cur->next;
115376 }
115377
115378 MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_len(&pc, buf, len));
115379 MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_tag(&pc, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
115380
115381 ret = mbedtls_x509write_crt_set_extension(ctx, MBEDTLS_OID_SUBJECT_ALT_NAME,
115382 MBEDTLS_OID_SIZE(MBEDTLS_OID_SUBJECT_ALT_NAME), 0, buf + buflen - len, len);
115383
115384 mbedtls_free(buf);
115385 return ret;
115386
115387cleanup:
115388 mbedtls_free(buf);
115389 return ret;
115390}
115391
115392#endif
115393
115394/**** amalgamated original file "/plugins/crypto/mbedtls/ua_pki_mbedtls.c" ****/
115395
115396/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
115397 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
115398 *
115399 * Copyright 2018 (c) Mark Giraud, Fraunhofer IOSB
115400 * Copyright 2019 (c) Kalycito Infotech Private Limited
115401 * Copyright 2019, 2024 (c) Julius Pfrommer, Fraunhofer IOSB
115402 */
115403
115404
115405#ifdef UA_ENABLE_ENCRYPTION_MBEDTLS
115406
115407
115408#include <mbedtls/x509.h>
115409#include <mbedtls/oid.h>
115410#include <mbedtls/x509_crt.h>
115411#include <mbedtls/entropy.h>
115412#include <mbedtls/error.h>
115413#include <mbedtls/version.h>
115414#include <string.h>
115415
115416#define UA_MBEDTLS_MAX_CHAIN_LENGTH 10
115417#define UA_MBEDTLS_MAX_DN_LENGTH 256
115418
115419/* Find binary substring. Taken and adjusted from
115420 * http://tungchingkai.blogspot.com/2011/07/binary-strstr.html */
115421
115422static const unsigned char *
115423bstrchr(const unsigned char *s, const unsigned char ch, size_t l) {
115424 /* find first occurrence of c in char s[] for length l*/
115425 for(; l > 0; ++s, --l) {
115426 if(*s == ch)
115427 return s;
115428 }
115429 return NULL;
115430}
115431
115432static const unsigned char *
115433UA_Bstrstr(const unsigned char *s1, size_t l1, const unsigned char *s2, size_t l2) {
115434 /* find first occurrence of s2[] in s1[] for length l1*/
115435 const unsigned char *ss1 = s1;
115436 const unsigned char *ss2 = s2;
115437 /* handle special case */
115438 if(l1 == 0)
115439 return (NULL);
115440 if(l2 == 0)
115441 return s1;
115442
115443 /* match prefix */
115444 for (; (s1 = bstrchr(s1, *s2, (uintptr_t)ss1-(uintptr_t)s1+(uintptr_t)l1)) != NULL &&
115445 (uintptr_t)ss1-(uintptr_t)s1+(uintptr_t)l1 != 0; ++s1) {
115446
115447 /* match rest of prefix */
115448 const unsigned char *sc1, *sc2;
115449 for (sc1 = s1, sc2 = s2; ;)
115450 if (++sc2 >= ss2+l2)
115451 return s1;
115452 else if (*++sc1 != *sc2)
115453 break;
115454 }
115455 return NULL;
115456}
115457
115458// mbedTLS expects PEM data to be null terminated
115459// The data length parameter must include the null terminator
115460static UA_ByteString copyDataFormatAware(const UA_ByteString *data)
115461{
115462 UA_ByteString result;
115463 UA_ByteString_init(&result);
115464
115465 if (!data->length)
115466 return result;
115467
115468 if (data->length && data->data[0] == '-') {
115469 UA_ByteString_allocBuffer(&result, data->length + 1);
115470 memcpy(result.data, data->data, data->length);
115471 result.data[data->length] = '\0';
115472 } else {
115473 UA_ByteString_copy(data, &result);
115474 }
115475
115476 return result;
115477}
115478
115479typedef struct {
115480 UA_CertificateVerification *cv;
115481
115482 /* If the folders are defined, we use them to reload the certificates during
115483 * runtime */
115484 UA_String trustListFolder;
115485 UA_String issuerListFolder;
115486 UA_String revocationListFolder;
115487 UA_String rejectedListFolder;
115488
115489 mbedtls_x509_crt certificateTrustList;
115490 mbedtls_x509_crt certificateIssuerList;
115491 mbedtls_x509_crl certificateRevocationList;
115492} CertInfo;
115493
115494#ifdef __linux__ /* Linux only so far */
115495
115496#include <dirent.h>
115497#include <limits.h>
115498
115499static UA_StatusCode
115500fileNamesFromFolder(const UA_String *folder, size_t *pathsSize, UA_String **paths) {
115501 char buf[PATH_MAX + 1];
115502 if(folder->length > PATH_MAX)
115503 return UA_STATUSCODE_BADINTERNALERROR;
115504
115505 memcpy(buf, folder->data, folder->length);
115506 buf[folder->length] = 0;
115507
115508 DIR *dir = opendir(buf);
115509 if(!dir)
115510 return UA_STATUSCODE_BADINTERNALERROR;
115511
115512 *paths = (UA_String*)UA_Array_new(256, &UA_TYPES[UA_TYPES_STRING]);
115513 if(*paths == NULL) {
115514 closedir(dir);
115515 return UA_STATUSCODE_BADOUTOFMEMORY;
115516 }
115517
115518 struct dirent *ent;
115519 char buf2[PATH_MAX + 1];
115520 char *res = realpath(buf, buf2);
115521 if(!res) {
115522 closedir(dir);
115523 return UA_STATUSCODE_BADINTERNALERROR;
115524 }
115525 size_t pathlen = strlen(buf2);
115526 *pathsSize = 0;
115527 while((ent = readdir (dir)) != NULL && *pathsSize < 256) {
115528 if(ent->d_type != DT_REG)
115529 continue;
115530 buf2[pathlen] = '/';
115531 buf2[pathlen+1] = 0;
115532 strcat(buf2, ent->d_name);
115533 (*paths)[*pathsSize] = UA_STRING_ALLOC(buf2);
115534 *pathsSize += 1;
115535 }
115536 closedir(dir);
115537
115538 if(*pathsSize == 0) {
115539 UA_free(*paths);
115540 *paths = NULL;
115541 }
115542 return UA_STATUSCODE_GOOD;
115543}
115544
115545static UA_StatusCode
115546reloadCertificates(const UA_CertificateVerification *cv, CertInfo *ci) {
115547 UA_StatusCode retval = UA_STATUSCODE_GOOD;
115548 int err = 0;
115549 int internalErrorFlag = 0;
115550
115551 /* Load the trustlists */
115552 if(ci->trustListFolder.length > 0) {
115553 UA_LOG_INFO(cv->logging, UA_LOGCATEGORY_SERVER, "Reloading the trust-list");
115554 mbedtls_x509_crt_free(&ci->certificateTrustList);
115555 mbedtls_x509_crt_init(&ci->certificateTrustList);
115556
115557 char f[PATH_MAX];
115558 memcpy(f, ci->trustListFolder.data, ci->trustListFolder.length);
115559 f[ci->trustListFolder.length] = 0;
115560 err = mbedtls_x509_crt_parse_path(&ci->certificateTrustList, f);
115561 if(err == 0) {
115562 UA_LOG_INFO(cv->logging, UA_LOGCATEGORY_SERVER,
115563 "Loaded certificate from %s", f);
115564 } else {
115565 char errBuff[300];
115566 mbedtls_strerror(err, errBuff, 300);
115567 UA_LOG_INFO(cv->logging, UA_LOGCATEGORY_SERVER,
115568 "Failed to load certificate from %s, mbedTLS error: %s (error code: %d)", f, errBuff, err);
115569 internalErrorFlag = 1;
115570 }
115571 }
115572
115573 /* Load the revocationlists */
115574 if(ci->revocationListFolder.length > 0) {
115575 UA_LOG_INFO(cv->logging, UA_LOGCATEGORY_SERVER, "Reloading the revocation-list");
115576 size_t pathsSize = 0;
115577 UA_String *paths = NULL;
115578 retval = fileNamesFromFolder(&ci->revocationListFolder, &pathsSize, &paths);
115579 if(retval != UA_STATUSCODE_GOOD)
115580 return retval;
115581 mbedtls_x509_crl_free(&ci->certificateRevocationList);
115582 mbedtls_x509_crl_init(&ci->certificateRevocationList);
115583 for(size_t i = 0; i < pathsSize; i++) {
115584 char f[PATH_MAX];
115585 memcpy(f, paths[i].data, paths[i].length);
115586 f[paths[i].length] = 0;
115587 err = mbedtls_x509_crl_parse_file(&ci->certificateRevocationList, f);
115588 if(err == 0) {
115589 UA_LOG_INFO(cv->logging, UA_LOGCATEGORY_SERVER,
115590 "Loaded certificate from %.*s",
115591 (int)paths[i].length, paths[i].data);
115592 } else {
115593 char errBuff[300];
115594 mbedtls_strerror(err, errBuff, 300);
115595 UA_LOG_INFO(cv->logging, UA_LOGCATEGORY_SERVER,
115596 "Failed to load certificate from %.*s, mbedTLS error: %s (error code: %d)",
115597 (int)paths[i].length, paths[i].data, errBuff, err);
115598 internalErrorFlag = 1;
115599 }
115600 }
115601 UA_Array_delete(paths, pathsSize, &UA_TYPES[UA_TYPES_STRING]);
115602 paths = NULL;
115603 pathsSize = 0;
115604 }
115605
115606 /* Load the issuerlists */
115607 if(ci->issuerListFolder.length > 0) {
115608 UA_LOG_INFO(cv->logging, UA_LOGCATEGORY_SERVER, "Reloading the issuer-list");
115609 mbedtls_x509_crt_free(&ci->certificateIssuerList);
115610 mbedtls_x509_crt_init(&ci->certificateIssuerList);
115611 char f[PATH_MAX];
115612 memcpy(f, ci->issuerListFolder.data, ci->issuerListFolder.length);
115613 f[ci->issuerListFolder.length] = 0;
115614 err = mbedtls_x509_crt_parse_path(&ci->certificateIssuerList, f);
115615 if(err == 0) {
115616 UA_LOG_INFO(cv->logging, UA_LOGCATEGORY_SERVER,
115617 "Loaded certificate from %s", f);
115618 } else {
115619 char errBuff[300];
115620 mbedtls_strerror(err, errBuff, 300);
115621 UA_LOG_INFO(cv->logging, UA_LOGCATEGORY_SERVER,
115622 "Failed to load certificate from %s, mbedTLS error: %s (error code: %d)",
115623 f, errBuff, err);
115624 internalErrorFlag = 1;
115625 }
115626 }
115627
115628 return (internalErrorFlag) ? UA_STATUSCODE_BADINTERNALERROR : retval;
115629}
115630
115631#endif
115632
115633/* We need to access some private fields below */
115634#ifndef MBEDTLS_PRIVATE
115635#define MBEDTLS_PRIVATE(x) x
115636#endif
115637
115638/* Is the certificate a CA? */
115639static UA_Boolean
115640mbedtlsCheckCA(mbedtls_x509_crt *cert) {
115641 /* The Basic Constraints extension must be set and the cert acts as CA */
115642 if(!(cert->MBEDTLS_PRIVATE(ext_types) & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS) ||
115643 !cert->MBEDTLS_PRIVATE(ca_istrue))
115644 return false;
115645
115646 /* The Key Usage extension must be set to cert signing and CRL issuing */
115647 if(!(cert->MBEDTLS_PRIVATE(ext_types) & MBEDTLS_X509_EXT_KEY_USAGE) ||
115648 mbedtls_x509_crt_check_key_usage(cert, MBEDTLS_X509_KU_KEY_CERT_SIGN) != 0 ||
115649 mbedtls_x509_crt_check_key_usage(cert, MBEDTLS_X509_KU_CRL_SIGN) != 0)
115650 return false;
115651
115652 return true;
115653}
115654
115655static UA_Boolean
115656mbedtlsSameName(UA_String name, const mbedtls_x509_name *name2) {
115657 char buf[UA_MBEDTLS_MAX_DN_LENGTH];
115658 int len = mbedtls_x509_dn_gets(buf, UA_MBEDTLS_MAX_DN_LENGTH, name2);
115659 if(len < 0)
115660 return false;
115661 UA_String nameString = {(size_t)len, (UA_Byte*)buf};
115662 return UA_String_equal(&name, &nameString);
115663}
115664
115665static UA_Boolean
115666mbedtlsSameBuf(mbedtls_x509_buf *a, mbedtls_x509_buf *b) {
115667 if(a->len != b->len)
115668 return false;
115669 return (memcmp(a->p, b->p, a->len) == 0);
115670}
115671
115672/* Return the first matching issuer candidate AFTER prev.
115673 * This can return the cert itself if self-signed. */
115674static mbedtls_x509_crt *
115675mbedtlsFindNextIssuer(CertInfo *ci, mbedtls_x509_crt *stack,
115676 mbedtls_x509_crt *cert, mbedtls_x509_crt *prev) {
115677 char inbuf[UA_MBEDTLS_MAX_DN_LENGTH];
115678 int nameLen = mbedtls_x509_dn_gets(inbuf, UA_MBEDTLS_MAX_DN_LENGTH, &cert->issuer);
115679 if(nameLen < 0)
115680 return NULL;
115681 UA_String issuerName = {(size_t)nameLen, (UA_Byte*)inbuf};
115682 do {
115683 for(mbedtls_x509_crt *i = stack; i; i = i->next) {
115684 if(prev) {
115685 if(prev == i)
115686 prev = NULL; /* This was the last issuer we tried to verify */
115687 continue;
115688 }
115689 /* Compare issuer name and subject name.
115690 * Skip when the key does not match the signature. */
115691 if(mbedtlsSameName(issuerName, &i->subject) &&
115692 mbedtls_pk_can_do(&i->pk, cert->MBEDTLS_PRIVATE(sig_pk)))
115693 return i;
115694 }
115695
115696 /* Switch from the stack that came with the cert to the issuer list and
115697 * then to the trust list. */
115698 if(stack == &ci->certificateTrustList)
115699 stack = NULL;
115700 else if(stack == &ci->certificateIssuerList)
115701 stack = &ci->certificateTrustList;
115702 else
115703 stack = &ci->certificateIssuerList;
115704 } while(stack);
115705 return NULL;
115706}
115707
115708static UA_StatusCode
115709mbedtlsCheckRevoked(CertInfo *ci, mbedtls_x509_crt *cert) {
115710 /* Parse the Issuer Name */
115711 char inbuf[UA_MBEDTLS_MAX_DN_LENGTH];
115712 int nameLen = mbedtls_x509_dn_gets(inbuf, UA_MBEDTLS_MAX_DN_LENGTH, &cert->issuer);
115713 if(nameLen < 0)
115714 return UA_STATUSCODE_BADINTERNALERROR;
115715 UA_String issuerName = {(size_t)nameLen, (UA_Byte*)inbuf};
115716
115717 if(ci->certificateRevocationList.raw.len == 0) {
115718 UA_LOG_WARNING(ci->cv->logging, UA_LOGCATEGORY_SECURITYPOLICY,
115719 "Zero revocation lists have been loaded. "
115720 "This seems intentional - omitting the check.");
115721 return UA_STATUSCODE_GOOD;
115722 }
115723
115724 /* Loop over the crl and match the Issuer Name */
115725 UA_StatusCode res = UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN;
115726 for(mbedtls_x509_crl *crl = &ci->certificateRevocationList; crl; crl = crl->next) {
115727 /* Is the CRL for certificates from the cert issuer?
115728 * Is the serial number of the certificate contained in the CRL? */
115729 if(mbedtlsSameName(issuerName, &crl->issuer)) {
115730 if(mbedtls_x509_crt_is_revoked(cert, crl) != 0)
115731 return UA_STATUSCODE_BADCERTIFICATEREVOKED;
115732 res = UA_STATUSCODE_GOOD; /* There was at least one crl that did not revoke (so far) */
115733 }
115734 }
115735 return res;
115736}
115737
115738/* Verify that the public key of the issuer was used to sign the certificate */
115739static UA_Boolean
115740mbedtlsCheckSignature(const mbedtls_x509_crt *cert, mbedtls_x509_crt *issuer) {
115741 size_t hash_len;
115742 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
115743 mbedtls_md_type_t md = cert->MBEDTLS_PRIVATE(sig_md);
115744#if !defined(MBEDTLS_USE_PSA_CRYPTO)
115745 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md);
115746 hash_len = mbedtls_md_get_size(md_info);
115747 if(mbedtls_md(md_info, cert->tbs.p, cert->tbs.len, hash) != 0)
115748 return false;
115749#else
115750 if(psa_hash_compute(mbedtls_md_psa_alg_from_type(md), cert->tbs.p,
115751 cert->tbs.len, hash, sizeof(hash), &hash_len) != PSA_SUCCESS)
115752 return false;
115753#endif
115754 const mbedtls_x509_buf *sig = &cert->MBEDTLS_PRIVATE(sig);
115755 void *sig_opts = cert->MBEDTLS_PRIVATE(sig_opts);
115756 mbedtls_pk_type_t pktype = cert->MBEDTLS_PRIVATE(sig_pk);
115757 return (mbedtls_pk_verify_ext(pktype, sig_opts, &issuer->pk, md,
115758 hash, hash_len, sig->p, sig->len) == 0);
115759}
115760
115761static UA_StatusCode
115762mbedtlsVerifyChain(CertInfo *ci, mbedtls_x509_crt *stack, mbedtls_x509_crt **old_issuers,
115763 mbedtls_x509_crt *cert, int depth) {
115764 /* Maxiumum chain length */
115765 if(depth == UA_MBEDTLS_MAX_CHAIN_LENGTH)
115766 return UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE;
115767
115768 /* Verification Step: Validity Period */
115769 if(mbedtls_x509_time_is_future(&cert->valid_from) ||
115770 mbedtls_x509_time_is_past(&cert->valid_to))
115771 return (depth == 0) ? UA_STATUSCODE_BADCERTIFICATETIMEINVALID :
115772 UA_STATUSCODE_BADCERTIFICATEISSUERTIMEINVALID;
115773
115774 /* Return the most specific error code. BADCERTIFICATECHAININCOMPLETE is
115775 * returned only if all possible chains are incomplete. */
115776 mbedtls_x509_crt *issuer = NULL;
115777 UA_StatusCode ret = UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE;
115778 while(ret != UA_STATUSCODE_GOOD) {
115779 /* Find the issuer. This can return the same certificate if it is
115780 * self-signed (subject == issuer). We come back here to try a different
115781 * "path" if a subsequent verification fails. */
115782 issuer = mbedtlsFindNextIssuer(ci, stack, cert, issuer);
115783 if(!issuer)
115784 break;
115785
115786 /* Verification Step: Certificate Usage
115787 * Can the issuer act as CA? Omit for self-signed leaf certificates. */
115788 if((depth > 0 || issuer != cert) && !mbedtlsCheckCA(issuer)) {
115789 ret = UA_STATUSCODE_BADCERTIFICATEISSUERUSENOTALLOWED;
115790 continue;
115791 }
115792
115793 /* Verification Step: Signature */
115794 if(!mbedtlsCheckSignature(cert, issuer)) {
115795 ret = UA_STATUSCODE_BADCERTIFICATEINVALID; /* Wrong issuer, try again */
115796 continue;
115797 }
115798
115799 /* The certificate is self-signed. We have arrived at the top of the
115800 * chain. We check whether the certificate is trusted below. This is the
115801 * only place where we return UA_STATUSCODE_BADCERTIFICATEUNTRUSTED.
115802 * This signals that the chain is complete (but can be still
115803 * untrusted).
115804 *
115805 * Break here as we have reached the end of the chain. Omit the
115806 * Revocation Check for self-signed certificates. */
115807 if(issuer == cert || mbedtlsSameBuf(&cert->tbs, &issuer->tbs)) {
115808 ret = UA_STATUSCODE_BADCERTIFICATEUNTRUSTED;
115809 break;
115810 }
115811
115812 /* Verification Step: Revocation Check */
115813 ret = mbedtlsCheckRevoked(ci, cert);
115814 if(depth > 0) {
115815 if(ret == UA_STATUSCODE_BADCERTIFICATEREVOKED)
115816 ret = UA_STATUSCODE_BADCERTIFICATEISSUERREVOKED;
115817 if(ret == UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN)
115818 ret = UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN;
115819 }
115820 if(ret != UA_STATUSCODE_GOOD)
115821 continue;
115822
115823 /* Detect (endless) loops of issuers */
115824 for(int i = 0; i < depth; i++) {
115825 if(old_issuers[i] == issuer)
115826 return UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE;
115827 }
115828 old_issuers[depth] = issuer;
115829
115830 /* We have found the issuer certificate used for the signature. Recurse
115831 * to the next certificate in the chain (verify the current issuer). */
115832 ret = mbedtlsVerifyChain(ci, stack, old_issuers, issuer, depth + 1);
115833 }
115834
115835 /* The chain is complete, but we haven't yet identified a trusted
115836 * certificate "on the way down". Can we trust this certificate? */
115837 if(ret == UA_STATUSCODE_BADCERTIFICATEUNTRUSTED) {
115838 for(mbedtls_x509_crt *t = &ci->certificateTrustList; t; t = t->next) {
115839 if(mbedtlsSameBuf(&cert->tbs, &t->tbs))
115840 return UA_STATUSCODE_GOOD;
115841 }
115842 }
115843
115844 return ret;
115845}
115846
115847/* This follows Part 6, 6.1.3 Determining if a Certificate is trusted.
115848 * It defines a sequence of steps for certificate verification. */
115849static UA_StatusCode
115850certificateVerification_verify(const UA_CertificateVerification *cv,
115851 const UA_ByteString *certificate) {
115852 if(!cv || !certificate)
115853 return UA_STATUSCODE_BADINTERNALERROR;
115854
115855 CertInfo *ci = (CertInfo*)cv->context;
115856 UA_StatusCode ret = UA_STATUSCODE_GOOD;
115857 mbedtls_x509_crt *old_issuers[UA_MBEDTLS_MAX_CHAIN_LENGTH];
115858
115859#ifdef __linux__ /* Reload certificates if folder paths are specified */
115860 ret = reloadCertificates(cv, ci);
115861 if(ret != UA_STATUSCODE_GOOD)
115862 return ret;
115863#endif
115864
115865 /* Verification Step: Certificate Structure
115866 * This parses the entire certificate chain contained in the bytestring. */
115867 mbedtls_x509_crt cert;
115868 mbedtls_x509_crt_init(&cert);
115869 int mbedErr = mbedtls_x509_crt_parse(&cert, certificate->data,
115870 certificate->length);
115871 if(mbedErr) {
115872 ret = UA_STATUSCODE_BADCERTIFICATEINVALID;
115873 goto errout;
115874 }
115875
115876 /* Verification Step: Certificate Usage
115877 * Check whether the certificate is a User certificate or a CA certificate.
115878 * Refer the test case CTT/Security/Security Certificate Validation/029.js
115879 * for more details. */
115880 if(mbedtlsCheckCA(&cert)) {
115881 ret = UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED;
115882 goto errout;
115883 }
115884
115885 /* These steps are performed outside of this method.
115886 * Because we need the server or client context.
115887 * - Security Policy
115888 * - Host Name
115889 * - URI */
115890
115891 /* Verification Step: Build Certificate Chain
115892 * We perform the checks for each certificate inside. */
115893 ret = mbedtlsVerifyChain(ci, &cert, old_issuers, &cert, 0);
115894
115895 errout:
115896 mbedtls_x509_crt_free(&cert);
115897
115898#ifdef UA_ENABLE_CERT_REJECTED_DIR
115899 if(ret != UA_STATUSCODE_GOOD &&
115900 ci->rejectedListFolder.length > 0) {
115901 char rejectedFileName[256] = {0};
115902 UA_ByteString thumbprint;
115903 UA_ByteString_allocBuffer(&thumbprint, UA_SHA1_LENGTH);
115904 if(mbedtls_thumbprint_sha1(certificate, &thumbprint) == UA_STATUSCODE_GOOD) {
115905 static const char hex2char[] = "0123456789ABCDEF";
115906 for(size_t pos = 0, namePos = 0; pos < thumbprint.length; pos++) {
115907 rejectedFileName[namePos++] = hex2char[(thumbprint.data[pos] & 0xf0) >> 4];
115908 rejectedFileName[namePos++] = hex2char[thumbprint.data[pos] & 0x0f];
115909 }
115910 strcat(rejectedFileName, ".der");
115911 } else {
115912 UA_UInt64 dt = (UA_UInt64) UA_DateTime_now();
115913 sprintf(rejectedFileName, "cert_%" PRIu64 ".der", dt);
115914 }
115915 UA_ByteString_clear(&thumbprint);
115916 char *rejectedFullFileName = (char *)
115917 calloc(ci->rejectedListFolder.length + 1 /* '/' */ + strlen(rejectedFileName) + 1, sizeof(char));
115918 if(!rejectedFullFileName)
115919 return ret;
115920 memcpy(rejectedFullFileName, ci->rejectedListFolder.data, ci->rejectedListFolder.length);
115921 rejectedFullFileName[ci->rejectedListFolder.length] = '/';
115922 memcpy(&rejectedFullFileName[ci->rejectedListFolder.length + 1], rejectedFileName, strlen(rejectedFileName));
115923 FILE * fp_rejectedFile = fopen(rejectedFullFileName, "wb");
115924 if(fp_rejectedFile) {
115925 fwrite(certificate->data, sizeof(certificate->data[0]), certificate->length, fp_rejectedFile);
115926 fclose(fp_rejectedFile);
115927 }
115928 free(rejectedFullFileName);
115929 }
115930#endif
115931
115932 return ret;
115933}
115934
115935static UA_StatusCode
115936certificateVerification_verifyApplicationURI(const UA_CertificateVerification *cv,
115937 const UA_ByteString *certificate,
115938 const UA_String *applicationURI) {
115939 CertInfo *ci;
115940 if(!cv)
115941 return UA_STATUSCODE_BADINTERNALERROR;
115942 ci = (CertInfo*)cv->context;
115943 if(!ci)
115944 return UA_STATUSCODE_BADINTERNALERROR;
115945
115946 /* Parse the certificate */
115947 mbedtls_x509_crt remoteCertificate;
115948 mbedtls_x509_crt_init(&remoteCertificate);
115949 int mbedErr = mbedtls_x509_crt_parse(&remoteCertificate, certificate->data,
115950 certificate->length);
115951 if(mbedErr)
115952 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
115953
115954 /* Poor man's ApplicationUri verification. mbedTLS does not parse all fields
115955 * of the Alternative Subject Name. Instead test whether the URI-string is
115956 * present in the v3_ext field in general.
115957 *
115958 * TODO: Improve parsing of the Alternative Subject Name */
115959 UA_StatusCode retval = UA_STATUSCODE_GOOD;
115960 if(UA_Bstrstr(remoteCertificate.v3_ext.p, remoteCertificate.v3_ext.len,
115961 applicationURI->data, applicationURI->length) == NULL)
115962 retval = UA_STATUSCODE_BADCERTIFICATEURIINVALID;
115963
115964 mbedtls_x509_crt_free(&remoteCertificate);
115965 return retval;
115966}
115967
115968static void
115969certificateVerification_clear(UA_CertificateVerification *cv) {
115970 CertInfo *ci = (CertInfo*)cv->context;
115971 if(!ci)
115972 return;
115973 mbedtls_x509_crt_free(&ci->certificateTrustList);
115974 mbedtls_x509_crl_free(&ci->certificateRevocationList);
115975 mbedtls_x509_crt_free(&ci->certificateIssuerList);
115976 UA_String_clear(&ci->trustListFolder);
115977 UA_String_clear(&ci->issuerListFolder);
115978 UA_String_clear(&ci->revocationListFolder);
115979 UA_String_clear(&ci->rejectedListFolder);
115980 UA_free(ci);
115981 cv->context = NULL;
115982}
115983
115984static UA_StatusCode
115985getCertificate_ExpirationDate(UA_DateTime *expiryDateTime,
115986 UA_ByteString *certificate) {
115987 mbedtls_x509_crt publicKey;
115988 mbedtls_x509_crt_init(&publicKey);
115989 int mbedErr = mbedtls_x509_crt_parse(&publicKey, certificate->data, certificate->length);
115990 if(mbedErr)
115991 return UA_STATUSCODE_BADINTERNALERROR;
115992 UA_DateTimeStruct ts;
115993 ts.year = (UA_Int16)publicKey.valid_to.year;
115994 ts.month = (UA_UInt16)publicKey.valid_to.mon;
115995 ts.day = (UA_UInt16)publicKey.valid_to.day;
115996 ts.hour = (UA_UInt16)publicKey.valid_to.hour;
115997 ts.min = (UA_UInt16)publicKey.valid_to.min;
115998 ts.sec = (UA_UInt16)publicKey.valid_to.sec;
115999 ts.milliSec = 0;
116000 ts.microSec = 0;
116001 ts.nanoSec = 0;
116002 *expiryDateTime = UA_DateTime_fromStruct(ts);
116003 mbedtls_x509_crt_free(&publicKey);
116004 return UA_STATUSCODE_GOOD;
116005}
116006
116007static UA_StatusCode
116008getCertificate_SubjectName(UA_String *subjectName,
116009 UA_ByteString *certificate) {
116010 mbedtls_x509_crt publicKey;
116011 mbedtls_x509_crt_init(&publicKey);
116012 int mbedErr = mbedtls_x509_crt_parse(&publicKey, certificate->data, certificate->length);
116013 if(mbedErr)
116014 return UA_STATUSCODE_BADINTERNALERROR;
116015 char buf[1024];
116016 int res = mbedtls_x509_dn_gets(buf, 1024, &publicKey.subject);
116017 mbedtls_x509_crt_free(&publicKey);
116018 if(res < 0)
116019 return UA_STATUSCODE_BADINTERNALERROR;
116020 UA_String tmp = {(size_t)res, (UA_Byte*)buf};
116021 return UA_String_copy(&tmp, subjectName);
116022}
116023
116024UA_StatusCode
116025UA_CertificateVerification_Trustlist(UA_CertificateVerification *cv,
116026 const UA_ByteString *certificateTrustList,
116027 size_t certificateTrustListSize,
116028 const UA_ByteString *certificateIssuerList,
116029 size_t certificateIssuerListSize,
116030 const UA_ByteString *certificateRevocationList,
116031 size_t certificateRevocationListSize) {
116032
116033 if(cv == NULL) {
116034 return UA_STATUSCODE_BADINTERNALERROR;
116035 }
116036
116037 /* Clear if the plugin is already initialized */
116038 if(cv->clear)
116039 cv->clear(cv);
116040
116041 CertInfo *ci = (CertInfo*)UA_malloc(sizeof(CertInfo));
116042 if(!ci)
116043 return UA_STATUSCODE_BADOUTOFMEMORY;
116044 memset(ci, 0, sizeof(CertInfo));
116045 ci->cv = cv;
116046 mbedtls_x509_crt_init(&ci->certificateTrustList);
116047 mbedtls_x509_crl_init(&ci->certificateRevocationList);
116048 mbedtls_x509_crt_init(&ci->certificateIssuerList);
116049
116050 cv->context = (void*)ci;
116051 cv->verifyCertificate = certificateVerification_verify;
116052 cv->clear = certificateVerification_clear;
116053 cv->verifyApplicationURI = certificateVerification_verifyApplicationURI;
116054 cv->getExpirationDate = getCertificate_ExpirationDate;
116055 cv->getSubjectName = getCertificate_SubjectName;
116056
116057 int err;
116058 UA_ByteString data;
116059 UA_ByteString_init(&data);
116060
116061 for(size_t i = 0; i < certificateTrustListSize; i++) {
116062 data = copyDataFormatAware(&certificateTrustList[i]);
116063 err = mbedtls_x509_crt_parse(&ci->certificateTrustList,
116064 data.data,
116065 data.length);
116066 UA_ByteString_clear(&data);
116067 if(err)
116068 goto error;
116069 }
116070 for(size_t i = 0; i < certificateIssuerListSize; i++) {
116071 data = copyDataFormatAware(&certificateIssuerList[i]);
116072 err = mbedtls_x509_crt_parse(&ci->certificateIssuerList,
116073 data.data,
116074 data.length);
116075 UA_ByteString_clear(&data);
116076 if(err)
116077 goto error;
116078 }
116079 for(size_t i = 0; i < certificateRevocationListSize; i++) {
116080 data = copyDataFormatAware(&certificateRevocationList[i]);
116081 err = mbedtls_x509_crl_parse(&ci->certificateRevocationList,
116082 data.data,
116083 data.length);
116084 UA_ByteString_clear(&data);
116085 if(err)
116086 goto error;
116087 }
116088
116089 return UA_STATUSCODE_GOOD;
116090error:
116091 certificateVerification_clear(cv);
116092 return UA_STATUSCODE_BADINTERNALERROR;
116093}
116094
116095#ifdef __linux__ /* Linux only so far */
116096
116097#ifdef UA_ENABLE_CERT_REJECTED_DIR
116098UA_StatusCode
116099UA_CertificateVerification_CertFolders(UA_CertificateVerification *cv,
116100 const char *trustListFolder,
116101 const char *issuerListFolder,
116102 const char *revocationListFolder,
116103 const char *rejectedListFolder) {
116104#else
116105UA_StatusCode
116106UA_CertificateVerification_CertFolders(UA_CertificateVerification *cv,
116107 const char *trustListFolder,
116108 const char *issuerListFolder,
116109 const char *revocationListFolder) {
116110#endif
116111 UA_StatusCode ret;
116112 if(cv == NULL) {
116113 return UA_STATUSCODE_BADINTERNALERROR;
116114 }
116115 if(cv->logging == NULL) {
116116 return UA_STATUSCODE_BADINTERNALERROR;
116117 }
116118
116119 /* Clear if the plugin is already initialized */
116120 if(cv->clear)
116121 cv->clear(cv);
116122
116123 CertInfo *ci = (CertInfo*)UA_malloc(sizeof(CertInfo));
116124 if(!ci)
116125 return UA_STATUSCODE_BADOUTOFMEMORY;
116126 memset(ci, 0, sizeof(CertInfo));
116127 ci->cv = cv;
116128 mbedtls_x509_crt_init(&ci->certificateTrustList);
116129 mbedtls_x509_crl_init(&ci->certificateRevocationList);
116130 mbedtls_x509_crt_init(&ci->certificateIssuerList);
116131
116132 /* Only set the folder paths. They will be reloaded during runtime.
116133 * TODO: Add a more efficient reloading of only the changes */
116134 ci->trustListFolder = UA_STRING_ALLOC(trustListFolder);
116135 ci->issuerListFolder = UA_STRING_ALLOC(issuerListFolder);
116136 ci->revocationListFolder = UA_STRING_ALLOC(revocationListFolder);
116137#ifdef UA_ENABLE_CERT_REJECTED_DIR
116138 ci->rejectedListFolder = UA_STRING_ALLOC(rejectedListFolder);
116139#endif
116140
116141 cv->context = (void*)ci;
116142 cv->verifyCertificate = certificateVerification_verify;
116143 cv->clear = certificateVerification_clear;
116144 cv->verifyApplicationURI = certificateVerification_verifyApplicationURI;
116145
116146 ret = reloadCertificates(cv, ci);
116147
116148 return ret;
116149}
116150
116151#endif
116152
116153UA_StatusCode
116154UA_PKI_decryptPrivateKey(const UA_ByteString privateKey,
116155 const UA_ByteString password,
116156 UA_ByteString *outDerKey) {
116157 if(!outDerKey)
116158 return UA_STATUSCODE_BADINTERNALERROR;
116159
116160 if (privateKey.length == 0) {
116161 *outDerKey = UA_BYTESTRING_NULL;
116162 return UA_STATUSCODE_BADINVALIDARGUMENT;
116163 }
116164
116165 /* Already in DER format -> return verbatim */
116166 if(privateKey.length > 1 && privateKey.data[0] == 0x30 && privateKey.data[1] == 0x82)
116167 return UA_ByteString_copy(&privateKey, outDerKey);
116168
116169 /* Create a null-terminated string */
116170 UA_ByteString nullTerminatedKey = UA_mbedTLS_CopyDataFormatAware(&privateKey);
116171 if(nullTerminatedKey.length != privateKey.length + 1)
116172 return UA_STATUSCODE_BADOUTOFMEMORY;
116173
116174 /* Create the private-key context */
116175 mbedtls_pk_context ctx;
116176 mbedtls_pk_init(&ctx);
116177#if MBEDTLS_VERSION_NUMBER >= 0x02060000 && MBEDTLS_VERSION_NUMBER < 0x03000000
116178 int err = mbedtls_pk_parse_key(&ctx, nullTerminatedKey.data,
116179 nullTerminatedKey.length,
116180 password.data, password.length);
116181#else
116182 mbedtls_entropy_context entropy;
116183 mbedtls_entropy_init(&entropy);
116184 int err = mbedtls_pk_parse_key(&ctx, nullTerminatedKey.data,
116185 nullTerminatedKey.length,
116186 password.data, password.length,
116187 mbedtls_entropy_func, &entropy);
116188 mbedtls_entropy_free(&entropy);
116189#endif
116190 UA_ByteString_clear(&nullTerminatedKey);
116191 if(err != 0) {
116192 mbedtls_pk_free(&ctx);
116193 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
116194 }
116195
116196 /* Write the DER-encoded key into a local buffer */
116197 unsigned char buf[1 << 14];
116198 size_t pos = (size_t)mbedtls_pk_write_key_der(&ctx, buf, sizeof(buf));
116199
116200 /* Allocate memory */
116201 UA_StatusCode res = UA_ByteString_allocBuffer(outDerKey, pos);
116202 if(res != UA_STATUSCODE_GOOD) {
116203 mbedtls_pk_free(&ctx);
116204 return res;
116205 }
116206
116207 /* Copy to the output */
116208 memcpy(outDerKey->data, &buf[sizeof(buf) - pos], pos);
116209 mbedtls_pk_free(&ctx);
116210 return UA_STATUSCODE_GOOD;
116211}
116212
116213#endif /* UA_ENABLE_ENCRYPTION_MBEDTLS */
116214
116215/**** amalgamated original file "/plugins/crypto/openssl/securitypolicy_openssl_common.h" ****/
116216
116217/* This Source Code Form is subject to the terms of the Mozilla Public
116218 * License, v. 2.0. If a copy of the MPL was not distributed with this
116219 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
116220 *
116221 * Copyright 2020 (c) Wind River Systems, Inc.
116222 * Copyright 2020 (c) basysKom GmbH
116223 *
116224 */
116225
116226
116227
116228#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL)
116229
116230#include <openssl/x509.h>
116231#include <openssl/evp.h>
116232
116233#define UA_SHA1_LENGTH 20
116234
116235_UA_BEGIN_DECLS
116236
116237void saveDataToFile(const char *fileName, const UA_ByteString *str);
116238void UA_Openssl_Init(void);
116239
116240UA_StatusCode
116241UA_copyCertificate(UA_ByteString *dst, const UA_ByteString *src);
116242
116243UA_StatusCode
116244UA_OpenSSL_RSA_PKCS1_V15_SHA256_Verify(const UA_ByteString *msg,
116245 X509 *publicKeyX509,
116246 const UA_ByteString *signature);
116247
116248UA_StatusCode
116249UA_OpenSSL_RSA_PSS_SHA256_Verify (const UA_ByteString * msg,
116250 X509 *publicKeyX509,
116251 const UA_ByteString * signature);
116252
116253UA_StatusCode
116254UA_Openssl_X509_GetCertificateThumbprint(const UA_ByteString *certficate,
116255 UA_ByteString *pThumbprint,
116256 bool bThumbPrint);
116257UA_StatusCode
116258UA_Openssl_RSA_Oaep_Decrypt(UA_ByteString *data,
116259 EVP_PKEY *privateKey);
116260
116261UA_StatusCode
116262UA_Openssl_RSA_Oaep_Sha2_Decrypt (UA_ByteString *data,
116263 EVP_PKEY *privateKey);
116264
116265UA_StatusCode
116266UA_Openssl_RSA_OAEP_Encrypt(UA_ByteString *data, /* The data that is encrypted.
116267 The encrypted data will overwrite
116268 the data that was supplied. */
116269 size_t paddingSize, X509 *publicX509);
116270
116271UA_StatusCode
116272UA_Openssl_RSA_OAEP_SHA2_Encrypt (UA_ByteString * data,
116273 size_t paddingSize,
116274 X509 * publicX509);
116275
116276UA_StatusCode
116277UA_Openssl_Random_Key_PSHA256_Derive(const UA_ByteString *secret,
116278 const UA_ByteString *seed,
116279 UA_ByteString *out);
116280
116281UA_StatusCode
116282UA_Openssl_RSA_Public_GetKeyLength(X509 *publicKeyX509, UA_Int32 *keyLen);
116283
116284UA_StatusCode
116285UA_Openssl_RSA_PKCS1_V15_SHA256_Sign(const UA_ByteString *data,
116286 EVP_PKEY *privateKey,
116287 UA_ByteString *outSignature);
116288
116289UA_StatusCode
116290UA_Openssl_RSA_PSS_SHA256_Sign (const UA_ByteString * message,
116291 EVP_PKEY * privateKey,
116292 UA_ByteString * outSignature);
116293
116294UA_StatusCode
116295UA_OpenSSL_HMAC_SHA256_Verify(const UA_ByteString *message,
116296 const UA_ByteString *key,
116297 const UA_ByteString *signature);
116298
116299UA_StatusCode
116300UA_OpenSSL_HMAC_SHA256_Sign(const UA_ByteString *message,
116301 const UA_ByteString *key,
116302 UA_ByteString *signature);
116303
116304UA_StatusCode
116305UA_OpenSSL_AES_256_CBC_Decrypt(const UA_ByteString *iv,
116306 const UA_ByteString *key,
116307 UA_ByteString *data /* [in/out]*/);
116308
116309UA_StatusCode
116310UA_OpenSSL_AES_256_CBC_Encrypt(const UA_ByteString *iv,
116311 const UA_ByteString *key,
116312 UA_ByteString *data /* [in/out]*/);
116313
116314UA_StatusCode
116315UA_OpenSSL_X509_compare(const UA_ByteString *cert, const X509 *b);
116316
116317UA_StatusCode
116318UA_Openssl_RSA_Private_GetKeyLength(EVP_PKEY *privateKey,
116319 UA_Int32 *keyLen) ;
116320
116321UA_StatusCode
116322UA_OpenSSL_RSA_PKCS1_V15_SHA1_Verify(const UA_ByteString *msg,
116323 X509 *publicKeyX509,
116324 const UA_ByteString *signature);
116325
116326UA_StatusCode
116327UA_Openssl_RSA_PKCS1_V15_SHA1_Sign(const UA_ByteString *message,
116328 EVP_PKEY *privateKey,
116329 UA_ByteString *outSignature);
116330UA_StatusCode
116331UA_Openssl_Random_Key_PSHA1_Derive(const UA_ByteString *secret,
116332 const UA_ByteString *seed,
116333 UA_ByteString *out);
116334UA_StatusCode
116335UA_OpenSSL_HMAC_SHA1_Verify(const UA_ByteString *message,
116336 const UA_ByteString *key,
116337 const UA_ByteString *signature);
116338
116339UA_StatusCode
116340UA_OpenSSL_HMAC_SHA1_Sign(const UA_ByteString *message,
116341 const UA_ByteString *key,
116342 UA_ByteString *signature);
116343
116344UA_StatusCode
116345UA_Openssl_RSA_PKCS1_V15_Decrypt(UA_ByteString *data,
116346 EVP_PKEY *privateKey);
116347
116348UA_StatusCode
116349UA_Openssl_RSA_PKCS1_V15_Encrypt(UA_ByteString *data,
116350 size_t paddingSize,
116351 X509 *publicX509);
116352
116353UA_StatusCode
116354UA_OpenSSL_AES_128_CBC_Decrypt(const UA_ByteString *iv,
116355 const UA_ByteString *key,
116356 UA_ByteString *data /* [in/out]*/);
116357
116358UA_StatusCode
116359UA_OpenSSL_AES_128_CBC_Encrypt(const UA_ByteString *iv,
116360 const UA_ByteString *key,
116361 UA_ByteString *data /* [in/out]*/);
116362
116363EVP_PKEY *
116364UA_OpenSSL_LoadPrivateKey(const UA_ByteString *privateKey);
116365
116366X509 *
116367UA_OpenSSL_LoadCertificate(const UA_ByteString *certificate);
116368
116369X509 *
116370UA_OpenSSL_LoadDerCertificate(const UA_ByteString *certificate);
116371
116372X509 *
116373UA_OpenSSL_LoadPemCertificate(const UA_ByteString *certificate);
116374
116375UA_StatusCode
116376UA_OpenSSL_LoadLocalCertificate(const UA_ByteString *certificate, UA_ByteString *target);
116377
116378_UA_END_DECLS
116379
116380#endif /* defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL) */
116381
116382
116383/**** amalgamated original file "/plugins/crypto/openssl/ua_openssl_version_abstraction.h" ****/
116384
116385/* This Source Code Form is subject to the terms of the Mozilla Public
116386 * License, v. 2.0. If a copy of the MPL was not distributed with this
116387 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
116388 *
116389 * Copyright 2021 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati)
116390 *
116391 */
116392
116393
116394#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL)
116395
116396#include <openssl/x509.h>
116397
116398#if !defined(OPENSSL_VERSION_NUMBER)
116399#error "OPENSSL_VERSION_NUMBER is not defined."
116400#endif
116401
116402#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
116403#define X509_STORE_CTX_set0_trusted_stack(STORE_CTX, CTX_SKTRUSTED) X509_STORE_CTX_trusted_stack(STORE_CTX, CTX_SKTRUSTED)
116404#endif
116405
116406#if OPENSSL_VERSION_NUMBER < 0x1010000fL || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050000fL)
116407#define X509_STORE_CTX_get_check_issued(STORE_CTX) STORE_CTX->check_issued
116408#endif
116409
116410#if OPENSSL_VERSION_NUMBER < 0x1010000fL || ( defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050000fL)
116411#define get_pkey_rsa(evp) ((evp)->pkey.rsa)
116412#else
116413#define get_pkey_rsa(evp) EVP_PKEY_get0_RSA(evp)
116414#endif
116415
116416#if OPENSSL_VERSION_NUMBER < 0x1010000fL || defined(LIBRESSL_VERSION_NUMBER)
116417#define X509_get0_subject_key_id(PX509_CERT) (const ASN1_OCTET_STRING *)X509_get_ext_d2i(PX509_CERT, NID_subject_key_identifier, NULL, NULL);
116418#endif
116419
116420#if OPENSSL_VERSION_NUMBER < 0x2000000fL || defined(LIBRESSL_VERSION_NUMBER)
116421#define get_error_line_data(pFile, pLine, pData, pFlags) ERR_get_error_line_data(pFile, pLine, pData, pFlags)
116422#else
116423#define get_error_line_data(pFile, pLine, pData, pFlags) ERR_get_error_all(pFile, pLine, NULL, pData, pFlags)
116424#endif
116425
116426#endif /* defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL) */
116427
116428/**** amalgamated original file "/plugins/crypto/openssl/securitypolicy_openssl_common.c" ****/
116429
116430/* This Source Code Form is subject to the terms of the Mozilla Public
116431 * License, v. 2.0. If a copy of the MPL was not distributed with this
116432 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
116433 *
116434 * Copyright 2020 (c) Wind River Systems, Inc.
116435 * Copyright 2020 (c) basysKom GmbH
116436 * Copyright 2022 (c) Wind River Systems, Inc.
116437 * Copyright 2022 (c) Fraunhofer IOSB (Author: Noel Graf)
116438 */
116439
116440/*
116441modification history
116442--------------------
11644301feb20,lan written
116444*/
116445
116446
116447#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL)
116448
116449#include <openssl/rsa.h>
116450#include <openssl/evp.h>
116451#include <openssl/err.h>
116452#include <openssl/sha.h>
116453#include <openssl/x509.h>
116454#include <openssl/hmac.h>
116455#include <openssl/aes.h>
116456#include <openssl/pem.h>
116457
116458
116459#define SHA1_DIGEST_LENGTH 20 /* 160 bits */
116460#define RSA_DECRYPT_BUFFER_LENGTH 2048 /* bytes */
116461
116462/* Cast to prevent warnings in LibreSSL */
116463#define SHA256EVP() ((EVP_MD *)(uintptr_t)EVP_sha256())
116464
116465
116466/** P_SHA256 Context */
116467typedef struct UA_Openssl_P_SHA256_Ctx_ {
116468 size_t seedLen;
116469 size_t secretLen;
116470 UA_Byte A[32]; /* 32 bytes of SHA256 output */
116471 /*
116472 char seed[seedLen];
116473 char secret[secretLen]; */
116474} UA_Openssl_P_SHA256_Ctx;
116475
116476#define UA_Openssl_P_SHA256_SEED(ctx) ((ctx)->A+32)
116477#define UA_Openssl_P_SHA256_SECRET(ctx) ((ctx)->A+32+(ctx)->seedLen)
116478
116479/** P_SHA1 Context */
116480typedef struct UA_Openssl_P_SHA1_Ctx_ {
116481 size_t seedLen;
116482 size_t secretLen;
116483 UA_Byte A[SHA1_DIGEST_LENGTH]; /* 20 bytes of SHA1 output */
116484 /*
116485 char seed[seedLen];
116486 char secret[secretLen]; */
116487} UA_Openssl_P_SHA1_Ctx;
116488
116489#define UA_Openssl_P_SHA1_SEED(ctx) ((ctx)->A + SHA1_DIGEST_LENGTH)
116490#define UA_Openssl_P_SHA1_SECRET(ctx) ((ctx)->A + SHA1_DIGEST_LENGTH +(ctx)->seedLen)
116491
116492void
116493UA_Openssl_Init (void) {
116494 /* VxWorks7 has initialized the openssl. */
116495#ifndef __VXWORKS__
116496 static UA_Int16 bInit = 0;
116497 if (bInit == 1)
116498 return;
116499#if defined(OPENSSL_API_COMPAT) && (OPENSSL_API_COMPAT < 0x10100000L)
116500 /* only needed, if OpenSSL < V1.1 */
116501 OpenSSL_add_all_algorithms ();
116502 ERR_load_crypto_strings ();
116503#endif
116504 bInit = 1;
116505#endif
116506}
116507
116508static int UA_OpenSSL_RSA_Key_Size (EVP_PKEY * key){
116509#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
116510 return EVP_PKEY_get_size (pkey: key);
116511#else
116512 return RSA_size (get_pkey_rsa(key));
116513#endif
116514}
116515
116516/* UA_copyCertificate - allocalte the buffer, copy the certificate and
116517 * add a NULL to the end
116518 */
116519
116520UA_StatusCode
116521UA_copyCertificate (UA_ByteString * dst,
116522 const UA_ByteString * src) {
116523 UA_StatusCode retval = UA_ByteString_allocBuffer (bs: dst, length: src->length + 1);
116524 if (retval != UA_STATUSCODE_GOOD)
116525 return retval;
116526 (void) memcpy (dest: dst->data, src: src->data, n: src->length);
116527 dst->data[dst->length - 1] = '\0';
116528 dst->length--;
116529
116530 return UA_STATUSCODE_GOOD;
116531}
116532
116533static UA_StatusCode
116534UA_OpenSSL_RSA_Public_Verify(const UA_ByteString *message,
116535 const EVP_MD *evpMd, X509 *publicKeyX509,
116536 UA_Int16 padding, const UA_ByteString *signature) {
116537 EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
116538 if(!mdctx)
116539 return UA_STATUSCODE_BADOUTOFMEMORY;
116540
116541 UA_StatusCode ret = UA_STATUSCODE_GOOD;
116542 EVP_PKEY *evpPublicKey = X509_get_pubkey(x: publicKeyX509);
116543 if(!evpPublicKey) {
116544 ret = UA_STATUSCODE_BADOUTOFMEMORY;
116545 goto errout;
116546 }
116547
116548 EVP_PKEY_CTX *evpKeyCtx;
116549 int opensslRet = EVP_DigestVerifyInit(ctx: mdctx, pctx: &evpKeyCtx, type: evpMd,
116550 NULL, pkey: evpPublicKey);
116551 if(opensslRet != 1) {
116552 ret = UA_STATUSCODE_BADINTERNALERROR;
116553 goto errout;
116554 }
116555
116556 opensslRet = EVP_PKEY_CTX_set_rsa_padding(ctx: evpKeyCtx, pad_mode: padding);
116557 if(opensslRet != 1) {
116558 ret = UA_STATUSCODE_BADINTERNALERROR;
116559 goto errout;
116560 }
116561
116562 if(padding == RSA_PKCS1_PSS_PADDING) {
116563 opensslRet = EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx: evpKeyCtx, RSA_PSS_SALTLEN_DIGEST);
116564 if(opensslRet != 1) {
116565 ret = UA_STATUSCODE_BADINTERNALERROR;
116566 goto errout;
116567 }
116568 opensslRet = EVP_PKEY_CTX_set_rsa_mgf1_md(ctx: evpKeyCtx, SHA256EVP());
116569 if(opensslRet != 1) {
116570 ret = UA_STATUSCODE_BADINTERNALERROR;
116571 goto errout;
116572 }
116573 }
116574
116575 opensslRet = EVP_DigestVerifyUpdate (ctx: mdctx, data: message->data, dsize: message->length);
116576 if(opensslRet != 1) {
116577 ret = UA_STATUSCODE_BADINTERNALERROR;
116578 goto errout;
116579 }
116580
116581 opensslRet = EVP_DigestVerifyFinal(ctx: mdctx, sig: signature->data, siglen: signature->length);
116582 if(opensslRet != 1) {
116583 ret = UA_STATUSCODE_BADINTERNALERROR;
116584 goto errout;
116585 }
116586
116587errout:
116588 if(evpPublicKey)
116589 EVP_PKEY_free(pkey: evpPublicKey);
116590 if(mdctx)
116591 EVP_MD_CTX_destroy(mdctx);
116592 return ret;
116593}
116594
116595UA_StatusCode
116596UA_OpenSSL_RSA_PKCS1_V15_SHA256_Verify (const UA_ByteString * msg,
116597 X509 * publicKeyX509,
116598 const UA_ByteString * signature
116599 ) {
116600 return UA_OpenSSL_RSA_Public_Verify (message: msg, evpMd: EVP_sha256(), publicKeyX509,
116601 RSA_PKCS1_PADDING, signature);
116602}
116603
116604UA_StatusCode
116605UA_OpenSSL_RSA_PSS_SHA256_Verify (const UA_ByteString * msg,
116606 X509 * publicKeyX509,
116607 const UA_ByteString * signature
116608) {
116609 return UA_OpenSSL_RSA_Public_Verify (message: msg, evpMd: EVP_sha256(), publicKeyX509,
116610 RSA_PKCS1_PSS_PADDING, signature);
116611}
116612
116613/* Get certificate thumbprint, and allocate the buffer. */
116614
116615UA_StatusCode
116616UA_Openssl_X509_GetCertificateThumbprint (const UA_ByteString * certficate,
116617 UA_ByteString * pThumbprint,
116618 bool bThumbPrint) {
116619 if (bThumbPrint) {
116620 pThumbprint->length = SHA_DIGEST_LENGTH;
116621 UA_StatusCode ret = UA_ByteString_allocBuffer (bs: pThumbprint, length: pThumbprint->length);
116622 if (ret != UA_STATUSCODE_GOOD) {
116623 return ret;
116624 }
116625 }
116626 else {
116627 if (pThumbprint->length != SHA_DIGEST_LENGTH) {
116628 return UA_STATUSCODE_BADINTERNALERROR;
116629 }
116630 }
116631 X509 * x509Certificate = UA_OpenSSL_LoadCertificate(certificate: certficate);
116632
116633 if (x509Certificate == NULL) {
116634 if (bThumbPrint) {
116635 UA_ByteString_clear (p: pThumbprint);
116636 }
116637 return UA_STATUSCODE_BADINTERNALERROR;
116638 }
116639
116640 if (X509_digest (data: x509Certificate, type: EVP_sha1(), md: pThumbprint->data, NULL)
116641 != 1) {
116642 if (bThumbPrint) {
116643 UA_ByteString_clear (p: pThumbprint);
116644 }
116645 return UA_STATUSCODE_BADINTERNALERROR;
116646 }
116647 X509_free(a: x509Certificate);
116648
116649 return UA_STATUSCODE_GOOD;
116650}
116651
116652static UA_StatusCode
116653UA_Openssl_RSA_Private_Decrypt (UA_ByteString * data,
116654 EVP_PKEY * privateKey,
116655 UA_Int16 padding,
116656 UA_Boolean withSha256) {
116657 if (data == NULL || privateKey == NULL) {
116658 return UA_STATUSCODE_BADINVALIDARGUMENT;
116659 }
116660
116661 if (privateKey == NULL) {
116662 return UA_STATUSCODE_BADINVALIDARGUMENT;
116663 }
116664
116665 size_t keySize = (size_t) UA_OpenSSL_RSA_Key_Size (key: privateKey);
116666 size_t cipherOffset = 0;
116667 size_t outOffset = 0;
116668 unsigned char buf[RSA_DECRYPT_BUFFER_LENGTH];
116669 size_t decryptedBytes;
116670 EVP_PKEY_CTX * ctx;
116671 int opensslRet;
116672
116673 ctx = EVP_PKEY_CTX_new (pkey: privateKey, NULL);
116674 if (ctx == NULL) {
116675 return UA_STATUSCODE_BADOUTOFMEMORY;
116676 }
116677 opensslRet = EVP_PKEY_decrypt_init (ctx);
116678 if (opensslRet != 1) {
116679 EVP_PKEY_CTX_free (ctx);
116680 return UA_STATUSCODE_BADINTERNALERROR;
116681 }
116682 opensslRet = EVP_PKEY_CTX_set_rsa_padding (ctx, pad_mode: padding);
116683 if (opensslRet != 1) {
116684 EVP_PKEY_CTX_free (ctx);
116685 return UA_STATUSCODE_BADINTERNALERROR;
116686 }
116687 if(withSha256) {
116688 opensslRet = EVP_PKEY_CTX_set_rsa_oaep_md(ctx, SHA256EVP());
116689 if (opensslRet != 1) {
116690 return UA_STATUSCODE_BADINTERNALERROR;
116691 }
116692 opensslRet = EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, SHA256EVP());
116693 if (opensslRet != 1) {
116694 return UA_STATUSCODE_BADINTERNALERROR;
116695 }
116696 }
116697
116698 while (cipherOffset < data->length) {
116699 decryptedBytes = RSA_DECRYPT_BUFFER_LENGTH;
116700 opensslRet = EVP_PKEY_decrypt (ctx,
116701 out: buf, /* where to decrypt */
116702 outlen: &decryptedBytes,
116703 in: data->data + cipherOffset, /* what to decrypt */
116704 inlen: keySize
116705 );
116706 if (opensslRet != 1) {
116707 EVP_PKEY_CTX_free (ctx);
116708 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
116709 }
116710 (void) memcpy(dest: data->data + outOffset, src: buf, n: decryptedBytes);
116711 cipherOffset += (size_t) keySize;
116712 outOffset += decryptedBytes;
116713 }
116714 data->length = outOffset;
116715 EVP_PKEY_CTX_free (ctx);
116716
116717 return UA_STATUSCODE_GOOD;
116718}
116719
116720UA_StatusCode
116721UA_Openssl_RSA_Oaep_Decrypt (UA_ByteString * data,
116722 EVP_PKEY * privateKey) {
116723 return UA_Openssl_RSA_Private_Decrypt (data, privateKey,
116724 RSA_PKCS1_OAEP_PADDING, false);
116725}
116726
116727UA_StatusCode
116728UA_Openssl_RSA_Oaep_Sha2_Decrypt (UA_ByteString * data,
116729 EVP_PKEY * privateKey) {
116730 return UA_Openssl_RSA_Private_Decrypt (data, privateKey,
116731 RSA_PKCS1_OAEP_PADDING, true);
116732}
116733
116734static UA_StatusCode
116735UA_Openssl_RSA_Public_Encrypt (const UA_ByteString * message,
116736 X509 * publicX509,
116737 UA_Int16 padding,
116738 size_t paddingSize,
116739 UA_ByteString * encrypted,
116740 UA_Boolean withSha256) {
116741 EVP_PKEY_CTX * ctx = NULL;
116742 EVP_PKEY * evpPublicKey = NULL;
116743 int opensslRet;
116744 UA_StatusCode ret;
116745 size_t encryptedTextLen = 0;
116746 size_t dataPos = 0;
116747 size_t encryptedPos = 0;
116748 size_t bytesToEncrypt = 0;
116749 size_t encryptedBlockSize = 0;
116750 size_t keySize = 0;
116751
116752 evpPublicKey = X509_get_pubkey (x: publicX509);
116753 if (evpPublicKey == NULL) {
116754 ret = UA_STATUSCODE_BADOUTOFMEMORY;
116755 goto errout;
116756 }
116757 ctx = EVP_PKEY_CTX_new (pkey: evpPublicKey, NULL);
116758 if (ctx == NULL) {
116759 ret = UA_STATUSCODE_BADOUTOFMEMORY;
116760 goto errout;
116761 }
116762 opensslRet = EVP_PKEY_encrypt_init (ctx);
116763 if (opensslRet != 1) {
116764 ret = UA_STATUSCODE_BADINTERNALERROR;
116765 goto errout;
116766 }
116767 opensslRet = EVP_PKEY_CTX_set_rsa_padding (ctx, pad_mode: padding);
116768 if (opensslRet != 1) {
116769 ret = UA_STATUSCODE_BADINTERNALERROR;
116770 goto errout;
116771 }
116772 if(withSha256) {
116773 opensslRet = EVP_PKEY_CTX_set_rsa_oaep_md(ctx, SHA256EVP());
116774 if (opensslRet != 1) {
116775 ret = UA_STATUSCODE_BADINTERNALERROR;
116776 goto errout;
116777 }
116778 opensslRet = EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, SHA256EVP());
116779 if (opensslRet != 1) {
116780 ret = UA_STATUSCODE_BADINTERNALERROR;
116781 goto errout;
116782 }
116783 }
116784
116785 /* get the encrypted block size */
116786
116787 keySize = (size_t) UA_OpenSSL_RSA_Key_Size (key: evpPublicKey);
116788 if (keySize == 0) {
116789 ret = UA_STATUSCODE_BADINTERNALERROR;
116790 goto errout;
116791 }
116792
116793 switch (padding) {
116794 case RSA_PKCS1_OAEP_PADDING:
116795 case RSA_PKCS1_PADDING:
116796 if (keySize <= paddingSize) {
116797 ret = UA_STATUSCODE_BADINTERNALERROR;
116798 goto errout;
116799 }
116800 encryptedBlockSize = keySize - paddingSize;
116801 break;
116802 default:
116803 ret = UA_STATUSCODE_BADNOTSUPPORTED;
116804 goto errout;
116805 break;
116806 }
116807
116808 /* encrypt in reverse order so that [data] may alias [encrypted] */
116809
116810 dataPos = message->length;
116811 encryptedPos = ((dataPos - 1) / encryptedBlockSize + 1) * keySize;
116812 bytesToEncrypt = (dataPos - 1) % encryptedBlockSize + 1;
116813 encryptedTextLen = encryptedPos;
116814
116815 while (dataPos > 0) {
116816 size_t outlen = keySize;
116817 encryptedPos -= keySize;
116818 dataPos -= bytesToEncrypt;
116819 opensslRet = EVP_PKEY_encrypt (ctx, out: encrypted->data + encryptedPos, outlen: &outlen,
116820 in: message->data + dataPos, inlen: bytesToEncrypt);
116821
116822 if (opensslRet != 1) {
116823 ret = UA_STATUSCODE_BADINTERNALERROR;
116824 goto errout;
116825 }
116826 bytesToEncrypt = encryptedBlockSize;
116827 }
116828 encrypted->length = encryptedTextLen;
116829
116830 ret = UA_STATUSCODE_GOOD;
116831errout:
116832 if (evpPublicKey != NULL) {
116833 EVP_PKEY_free (pkey: evpPublicKey);
116834 }
116835 if (ctx != NULL) {
116836 EVP_PKEY_CTX_free (ctx);
116837 }
116838 return ret;
116839}
116840
116841UA_StatusCode
116842UA_Openssl_RSA_OAEP_Encrypt (UA_ByteString * data,
116843 size_t paddingSize,
116844 X509 * publicX509) {
116845 UA_ByteString message;
116846 UA_StatusCode ret;
116847
116848 ret = UA_ByteString_copy (src: data, dst: &message);
116849 if (ret != UA_STATUSCODE_GOOD) {
116850 return ret;
116851 }
116852 ret = UA_Openssl_RSA_Public_Encrypt (message: &message, publicX509,
116853 RSA_PKCS1_OAEP_PADDING,
116854 paddingSize,
116855 encrypted: data, false);
116856 UA_ByteString_clear (p: &message);
116857 return ret;
116858}
116859
116860UA_StatusCode
116861UA_Openssl_RSA_OAEP_SHA2_Encrypt (UA_ByteString * data,
116862 size_t paddingSize,
116863 X509 * publicX509) {
116864 UA_ByteString message;
116865 UA_StatusCode ret;
116866
116867 ret = UA_ByteString_copy (src: data, dst: &message);
116868 if (ret != UA_STATUSCODE_GOOD) {
116869 return ret;
116870 }
116871 ret = UA_Openssl_RSA_Public_Encrypt (message: &message, publicX509,
116872 RSA_PKCS1_OAEP_PADDING,
116873 paddingSize,
116874 encrypted: data, true);
116875 UA_ByteString_clear (p: &message);
116876 return ret;
116877}
116878
116879static UA_Openssl_P_SHA256_Ctx *
116880P_SHA256_Ctx_Create (const UA_ByteString * secret,
116881 const UA_ByteString * seed) {
116882 size_t size = (UA_Int32)sizeof (UA_Openssl_P_SHA256_Ctx) + secret->length +
116883 seed->length;
116884 UA_Openssl_P_SHA256_Ctx * ctx = (UA_Openssl_P_SHA256_Ctx *) UA_malloc (size: size);
116885 if (ctx == NULL) {
116886 return NULL;
116887 }
116888 ctx->secretLen = secret->length;
116889 ctx->seedLen = seed->length;
116890 (void) memcpy (UA_Openssl_P_SHA256_SEED(ctx), src: seed->data, n: seed->length);
116891 (void) memcpy (UA_Openssl_P_SHA256_SECRET(ctx), src: secret->data, n: secret->length);
116892 /* A(0) = seed
116893 A(n) = HMAC_HASH(secret, A(n-1)) */
116894
116895 if (HMAC (evp_md: EVP_sha256(), key: secret->data, key_len: (int) secret->length, data: seed->data,
116896 data_len: seed->length, md: ctx->A, NULL) == NULL) {
116897 UA_free (ptr: ctx);
116898 return NULL;
116899 }
116900
116901 return ctx;
116902}
116903
116904static UA_StatusCode
116905P_SHA256_Hash_Generate (UA_Openssl_P_SHA256_Ctx * ctx,
116906 UA_Byte * pHas
116907 ) {
116908 /* Calculate P_SHA256(n) = HMAC_SHA256(secret, A(n)+seed) */
116909 if (HMAC (evp_md: EVP_sha256(),UA_Openssl_P_SHA256_SECRET(ctx), key_len: (int) ctx->secretLen,
116910 data: ctx->A, data_len: sizeof (ctx->A) + ctx->seedLen, md: pHas, NULL) == NULL) {
116911 return UA_STATUSCODE_BADINTERNALERROR;
116912 }
116913
116914 /* Calculate A(n) = HMAC_SHA256(secret, A(n-1)) */
116915 if (HMAC (evp_md: EVP_sha256(),UA_Openssl_P_SHA256_SECRET(ctx), key_len: (int) ctx->secretLen,
116916 data: ctx->A, data_len: sizeof (ctx->A), md: ctx->A, NULL) == NULL) {
116917 return UA_STATUSCODE_BADINTERNALERROR;
116918 }
116919 return UA_STATUSCODE_GOOD;
116920}
116921
116922UA_StatusCode
116923UA_Openssl_Random_Key_PSHA256_Derive (const UA_ByteString * secret,
116924 const UA_ByteString * seed,
116925 UA_ByteString * out) {
116926 size_t keyLen = out->length;
116927 size_t iter = keyLen/32 + ((keyLen%32)?1:0);
116928 size_t bufferLen = iter * 32;
116929 size_t i;
116930 UA_StatusCode st;
116931
116932 UA_Byte * pBuffer = (UA_Byte *) UA_malloc (size: bufferLen);
116933 if (pBuffer == NULL) {
116934 return UA_STATUSCODE_BADOUTOFMEMORY;
116935 }
116936
116937 UA_Openssl_P_SHA256_Ctx * ctx = P_SHA256_Ctx_Create (secret, seed);
116938 if (ctx == NULL) {
116939 UA_free (ptr: pBuffer);
116940 return UA_STATUSCODE_BADOUTOFMEMORY;
116941 }
116942
116943 for (i = 0; i < iter; i++) {
116944 st = P_SHA256_Hash_Generate (ctx, pHas: pBuffer + (i * 32));
116945 if (st != UA_STATUSCODE_GOOD) {
116946 UA_free (ptr: pBuffer);
116947 UA_free (ptr: ctx);
116948 return st;
116949 }
116950 }
116951
116952 (void) memcpy (dest: out->data, src: pBuffer, n: keyLen);
116953 UA_free (ptr: pBuffer);
116954 UA_free (ptr: ctx);
116955 return UA_STATUSCODE_GOOD;
116956}
116957
116958/* return the key bytes */
116959UA_StatusCode
116960UA_Openssl_RSA_Public_GetKeyLength (X509 * publicKeyX509,
116961 UA_Int32 * keyLen) {
116962 EVP_PKEY * evpKey = X509_get_pubkey (x: publicKeyX509);
116963 if (evpKey == NULL) {
116964 return UA_STATUSCODE_BADINTERNALERROR;
116965 }
116966 *keyLen = UA_OpenSSL_RSA_Key_Size (key: evpKey);
116967
116968 EVP_PKEY_free (pkey: evpKey);
116969
116970 return UA_STATUSCODE_GOOD;
116971}
116972
116973UA_StatusCode
116974UA_Openssl_RSA_Private_GetKeyLength (EVP_PKEY * privateKey,
116975 UA_Int32 * keyLen) {
116976 if (privateKey == NULL) {
116977 return UA_STATUSCODE_BADINVALIDARGUMENT;
116978 }
116979 *keyLen = UA_OpenSSL_RSA_Key_Size (key: privateKey);
116980
116981 return UA_STATUSCODE_GOOD;
116982}
116983
116984static UA_StatusCode
116985UA_Openssl_RSA_Private_Sign (const UA_ByteString * message,
116986 EVP_PKEY * privateKey,
116987 const EVP_MD * evpMd,
116988 UA_Int16 padding,
116989 UA_ByteString * outSignature) {
116990 EVP_MD_CTX * mdctx = NULL;
116991 int opensslRet;
116992 EVP_PKEY_CTX * evpKeyCtx;
116993 UA_StatusCode ret;
116994
116995 mdctx = EVP_MD_CTX_create ();
116996 if (mdctx == NULL) {
116997 ret = UA_STATUSCODE_BADOUTOFMEMORY;
116998 goto errout;
116999 }
117000
117001 if (privateKey == NULL) {
117002 return UA_STATUSCODE_BADINVALIDARGUMENT;
117003 }
117004 opensslRet = EVP_DigestSignInit (ctx: mdctx, pctx: &evpKeyCtx, type: evpMd, NULL, pkey: privateKey);
117005 if (opensslRet != 1) {
117006 ret = UA_STATUSCODE_BADINTERNALERROR;
117007 goto errout;
117008 }
117009 EVP_PKEY_CTX_set_rsa_padding (ctx: evpKeyCtx, pad_mode: padding);
117010 if(padding == RSA_PKCS1_PSS_PADDING) {
117011 opensslRet = EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx: evpKeyCtx, RSA_PSS_SALTLEN_DIGEST); //RSA_PSS_SALTLEN_DIGEST
117012 if (opensslRet != 1) {
117013 ret = UA_STATUSCODE_BADINTERNALERROR;
117014 goto errout;
117015 }
117016 opensslRet = EVP_PKEY_CTX_set_rsa_mgf1_md(ctx: evpKeyCtx, SHA256EVP());
117017 if (opensslRet != 1) {
117018 ret = UA_STATUSCODE_BADINTERNALERROR;
117019 goto errout;
117020 }
117021 }
117022 opensslRet = EVP_DigestSignUpdate (ctx: mdctx, data: message->data, dsize: message->length);
117023 if (opensslRet != 1) {
117024 ret = UA_STATUSCODE_BADINTERNALERROR;
117025 goto errout;
117026 }
117027 opensslRet = EVP_DigestSignFinal (ctx: mdctx, sigret: outSignature->data, siglen: &outSignature->length);
117028 if (opensslRet != 1) {
117029 ret = UA_STATUSCODE_BADINTERNALERROR;
117030 goto errout;
117031 }
117032
117033 ret = UA_STATUSCODE_GOOD;
117034errout:
117035 if (mdctx != NULL) {
117036 EVP_MD_CTX_destroy (mdctx);
117037 }
117038 return ret;
117039}
117040
117041UA_StatusCode
117042UA_Openssl_RSA_PKCS1_V15_SHA256_Sign (const UA_ByteString * message,
117043 EVP_PKEY * privateKey,
117044 UA_ByteString * outSignature) {
117045 return UA_Openssl_RSA_Private_Sign (message, privateKey, evpMd: EVP_sha256(),
117046 RSA_PKCS1_PADDING , outSignature);
117047}
117048
117049UA_StatusCode
117050UA_Openssl_RSA_PSS_SHA256_Sign (const UA_ByteString * message,
117051 EVP_PKEY * privateKey,
117052 UA_ByteString * outSignature) {
117053 return UA_Openssl_RSA_Private_Sign (message, privateKey, evpMd: EVP_sha256(),
117054 RSA_PKCS1_PSS_PADDING, outSignature);
117055}
117056
117057UA_StatusCode
117058UA_OpenSSL_HMAC_SHA256_Verify (const UA_ByteString * message,
117059 const UA_ByteString * key,
117060 const UA_ByteString * signature
117061 ) {
117062 unsigned char buf[SHA256_DIGEST_LENGTH] = {0};
117063 UA_ByteString mac = {SHA256_DIGEST_LENGTH, buf};
117064
117065 if (HMAC (evp_md: EVP_sha256(), key: key->data, key_len: (int) key->length, data: message->data, data_len: message->length,
117066 md: mac.data, md_len: (unsigned int *) &mac.length) == NULL) {
117067 return UA_STATUSCODE_BADINTERNALERROR;
117068 }
117069 if (UA_ByteString_equal (p1: signature, p2: &mac)) {
117070 return UA_STATUSCODE_GOOD;
117071 }
117072 else {
117073 return UA_STATUSCODE_BADINTERNALERROR;
117074 }
117075}
117076
117077UA_StatusCode
117078UA_OpenSSL_HMAC_SHA256_Sign (const UA_ByteString * message,
117079 const UA_ByteString * key,
117080 UA_ByteString * signature
117081 ) {
117082 if (HMAC (evp_md: EVP_sha256(), key: key->data, key_len: (int) key->length, data: message->data,
117083 data_len: message->length,
117084 md: signature->data, md_len: (unsigned int *) &(signature->length)) == NULL) {
117085 return UA_STATUSCODE_BADINTERNALERROR;
117086 }
117087 return UA_STATUSCODE_GOOD;
117088}
117089
117090static UA_StatusCode
117091UA_OpenSSL_Decrypt (const UA_ByteString * iv,
117092 const UA_ByteString * key,
117093 const EVP_CIPHER * cipherAlg,
117094 UA_ByteString * data /* [in/out]*/) {
117095 UA_ByteString ivCopy = {0, NULL};
117096 UA_ByteString cipherTxt = {0, NULL};
117097 EVP_CIPHER_CTX * ctx = NULL;
117098 UA_StatusCode ret;
117099 int opensslRet;
117100 int outLen;
117101 int tmpLen;
117102
117103 /* copy the IV because the AES_cbc_encrypt function overwrites it. */
117104
117105 ret = UA_ByteString_copy (src: iv, dst: &ivCopy);
117106 if (ret != UA_STATUSCODE_GOOD) {
117107 goto errout;
117108 }
117109
117110 ret = UA_ByteString_copy (src: data, dst: &cipherTxt);
117111 if (ret != UA_STATUSCODE_GOOD) {
117112 goto errout;
117113 }
117114
117115 ctx = EVP_CIPHER_CTX_new ();
117116 if (ctx == NULL) {
117117 ret = UA_STATUSCODE_BADOUTOFMEMORY;
117118 goto errout;
117119 }
117120
117121 /* call EVP_* to decrypt */
117122
117123 opensslRet = EVP_DecryptInit_ex (ctx, cipher: cipherAlg, NULL, key: key->data, iv: ivCopy.data);
117124 if (opensslRet != 1) {
117125 ret = UA_STATUSCODE_BADINTERNALERROR;
117126 goto errout;
117127 }
117128 /* EVP_DecryptFinal() will return an error code if padding is enabled
117129 * and the final block is not correctly formatted.
117130 */
117131 EVP_CIPHER_CTX_set_padding (c: ctx, pad: 0);
117132 opensslRet = EVP_DecryptUpdate (ctx, out: data->data, outl: &outLen,
117133 in: cipherTxt.data, inl: (int) cipherTxt.length);
117134 if (opensslRet != 1) {
117135 ret = UA_STATUSCODE_BADINTERNALERROR;
117136 goto errout;
117137 }
117138 opensslRet = EVP_DecryptFinal_ex (ctx, outm: data->data + outLen, outl: &tmpLen);
117139 if (opensslRet != 1) {
117140 ret = UA_STATUSCODE_BADINTERNALERROR;
117141 goto errout;
117142 }
117143 outLen += tmpLen;
117144 data->length = (size_t) outLen;
117145 ret = UA_STATUSCODE_GOOD;
117146
117147errout:
117148 UA_ByteString_clear (p: &ivCopy);
117149 UA_ByteString_clear (p: &cipherTxt);
117150 if (ctx != NULL) {
117151 EVP_CIPHER_CTX_free(c: ctx);
117152 }
117153 return ret;
117154}
117155
117156static UA_StatusCode
117157UA_OpenSSL_Encrypt (const UA_ByteString * iv,
117158 const UA_ByteString * key,
117159 const EVP_CIPHER * cipherAlg,
117160 UA_ByteString * data /* [in/out]*/
117161 ) {
117162
117163 UA_ByteString ivCopy = {0, NULL};
117164 UA_ByteString plainTxt = {0, NULL};
117165 EVP_CIPHER_CTX * ctx = NULL;
117166 UA_StatusCode ret;
117167 int opensslRet;
117168 int outLen;
117169 int tmpLen;
117170
117171 /* copy the IV because the AES_cbc_encrypt function overwrites it. */
117172
117173 ret = UA_ByteString_copy (src: iv, dst: &ivCopy);
117174 if (ret != UA_STATUSCODE_GOOD) {
117175 goto errout;
117176 }
117177
117178 ret = UA_ByteString_copy (src: data, dst: &plainTxt);
117179 if (ret != UA_STATUSCODE_GOOD) {
117180 goto errout;
117181 }
117182
117183 ctx = EVP_CIPHER_CTX_new ();
117184 if (ctx == NULL) {
117185 ret = UA_STATUSCODE_BADOUTOFMEMORY;
117186 goto errout;
117187 }
117188
117189 /* call EVP_* to encrypt */
117190
117191 opensslRet = EVP_EncryptInit_ex (ctx, cipher: cipherAlg, NULL, key: key->data, iv: ivCopy.data);
117192 if (opensslRet != 1) {
117193 ret = UA_STATUSCODE_BADINTERNALERROR;
117194 goto errout;
117195 }
117196
117197 /* Disable padding. Padding is done in the stack before calling encryption.
117198 * Ensure that we have a multiple of the block size */
117199 if(data->length % (size_t)EVP_CIPHER_CTX_block_size(ctx)) {
117200 ret = UA_STATUSCODE_BADINTERNALERROR;
117201 goto errout;
117202 }
117203 opensslRet = EVP_CIPHER_CTX_set_padding(c: ctx, pad: 0);
117204 if (opensslRet != 1) {
117205 ret = UA_STATUSCODE_BADINTERNALERROR;
117206 goto errout;
117207 }
117208
117209 /* Encrypt the data */
117210 opensslRet = EVP_EncryptUpdate (ctx, out: data->data, outl: &outLen,
117211 in: plainTxt.data, inl: (int) plainTxt.length);
117212 if (opensslRet != 1) {
117213 ret = UA_STATUSCODE_BADINTERNALERROR;
117214 goto errout;
117215 }
117216
117217 /* Encrypt-final does nothing as padding is disabled */
117218 opensslRet = EVP_EncryptFinal_ex(ctx, out: data->data + outLen, outl: &tmpLen);
117219 if (opensslRet != 1) {
117220 ret = UA_STATUSCODE_BADINTERNALERROR;
117221 goto errout;
117222 }
117223 outLen += tmpLen;
117224 data->length = (size_t) outLen;
117225 ret = UA_STATUSCODE_GOOD;
117226
117227errout:
117228 UA_ByteString_clear (p: &ivCopy);
117229 UA_ByteString_clear (p: &plainTxt);
117230 if (ctx != NULL) {
117231 EVP_CIPHER_CTX_free(c: ctx);
117232 }
117233 return ret;
117234}
117235
117236UA_StatusCode
117237UA_OpenSSL_AES_256_CBC_Decrypt (const UA_ByteString * iv,
117238 const UA_ByteString * key,
117239 UA_ByteString * data /* [in/out]*/
117240 ) {
117241 return UA_OpenSSL_Decrypt (iv, key, cipherAlg: EVP_aes_256_cbc (), data);
117242}
117243
117244UA_StatusCode
117245UA_OpenSSL_AES_256_CBC_Encrypt (const UA_ByteString * iv,
117246 const UA_ByteString * key,
117247 UA_ByteString * data /* [in/out]*/
117248 ) {
117249 return UA_OpenSSL_Encrypt (iv, key, cipherAlg: EVP_aes_256_cbc (), data);
117250}
117251
117252UA_StatusCode
117253UA_OpenSSL_X509_compare (const UA_ByteString * cert,
117254 const X509 * bcert) {
117255 X509 * acert = UA_OpenSSL_LoadCertificate(certificate: cert);
117256 if (acert == NULL) {
117257 return UA_STATUSCODE_BADCERTIFICATEINVALID;
117258 }
117259 int opensslRet = X509_cmp (a: acert, b: bcert);
117260 X509_free (a: acert);
117261
117262 if (opensslRet == 0)
117263 return UA_STATUSCODE_GOOD;
117264 return UA_STATUSCODE_UNCERTAINSUBNORMAL;
117265}
117266
117267UA_StatusCode
117268UA_OpenSSL_RSA_PKCS1_V15_SHA1_Verify (const UA_ByteString * msg,
117269 X509 * publicKeyX509,
117270 const UA_ByteString * signature) {
117271 return UA_OpenSSL_RSA_Public_Verify(message: msg, evpMd: EVP_sha1(), publicKeyX509,
117272 RSA_PKCS1_PADDING, signature);
117273}
117274
117275UA_StatusCode
117276UA_Openssl_RSA_PKCS1_V15_SHA1_Sign (const UA_ByteString * message,
117277 EVP_PKEY * privateKey,
117278 UA_ByteString * outSignature) {
117279 return UA_Openssl_RSA_Private_Sign(message, privateKey, evpMd: EVP_sha1(),
117280 RSA_PKCS1_PADDING, outSignature);
117281}
117282
117283static UA_Openssl_P_SHA1_Ctx *
117284P_SHA1_Ctx_Create (const UA_ByteString * secret,
117285 const UA_ByteString * seed) {
117286 size_t size = (UA_Int32)sizeof (UA_Openssl_P_SHA1_Ctx) + secret->length +
117287 seed->length;
117288 UA_Openssl_P_SHA1_Ctx * ctx = (UA_Openssl_P_SHA1_Ctx *) UA_malloc (size: size);
117289 if (ctx == NULL) {
117290 return NULL;
117291 }
117292
117293 ctx->secretLen = secret->length;
117294 ctx->seedLen = seed->length;
117295 (void) memcpy (UA_Openssl_P_SHA1_SEED(ctx), src: seed->data, n: seed->length);
117296 (void) memcpy (UA_Openssl_P_SHA1_SECRET(ctx), src: secret->data, n: secret->length);
117297 /* A(0) = seed
117298 A(n) = HMAC_HASH(secret, A(n-1)) */
117299
117300 if (HMAC (evp_md: EVP_sha1(), key: secret->data, key_len: (int) secret->length, data: seed->data,
117301 data_len: seed->length, md: ctx->A, NULL) == NULL) {
117302 UA_free (ptr: ctx);
117303 return NULL;
117304 }
117305
117306 return ctx;
117307}
117308
117309static UA_StatusCode
117310P_SHA1_Hash_Generate (UA_Openssl_P_SHA1_Ctx * ctx,
117311 UA_Byte * pHas
117312 ) {
117313 /* Calculate P_SHA1(n) = HMAC_SHA1(secret, A(n)+seed) */
117314 if (HMAC (evp_md: EVP_sha1 (), UA_Openssl_P_SHA1_SECRET(ctx), key_len: (int) ctx->secretLen,
117315 data: ctx->A, data_len: sizeof (ctx->A) + ctx->seedLen, md: pHas, NULL) == NULL) {
117316 return UA_STATUSCODE_BADINTERNALERROR;
117317 }
117318
117319 /* Calculate A(n) = HMAC_SHA1(secret, A(n-1)) */
117320 if (HMAC (evp_md: EVP_sha1(), UA_Openssl_P_SHA1_SECRET(ctx), key_len: (int) ctx->secretLen,
117321 data: ctx->A, data_len: sizeof (ctx->A), md: ctx->A, NULL) == NULL) {
117322 return UA_STATUSCODE_BADINTERNALERROR;
117323 }
117324 return UA_STATUSCODE_GOOD;
117325}
117326
117327UA_StatusCode
117328UA_Openssl_Random_Key_PSHA1_Derive (const UA_ByteString * secret,
117329 const UA_ByteString * seed,
117330 UA_ByteString * out) {
117331 size_t keyLen = out->length;
117332 size_t iter = keyLen / SHA1_DIGEST_LENGTH + ((keyLen % SHA1_DIGEST_LENGTH)?1:0);
117333 size_t bufferLen = iter * SHA1_DIGEST_LENGTH;
117334 UA_Byte * pBuffer = (UA_Byte *) UA_malloc (size: bufferLen);
117335 if (pBuffer == NULL) {
117336 return UA_STATUSCODE_BADOUTOFMEMORY;
117337 }
117338
117339 UA_Openssl_P_SHA1_Ctx * ctx = P_SHA1_Ctx_Create (secret, seed);
117340 if (ctx == NULL) {
117341 UA_free (ptr: pBuffer);
117342 return UA_STATUSCODE_BADOUTOFMEMORY;
117343 }
117344
117345 size_t i;
117346 UA_StatusCode st;
117347
117348 for (i = 0; i < iter; i++) {
117349 st = P_SHA1_Hash_Generate (ctx, pHas: pBuffer + (i * SHA1_DIGEST_LENGTH));
117350 if (st != UA_STATUSCODE_GOOD) {
117351 UA_free (ptr: pBuffer);
117352 UA_free (ptr: ctx);
117353 return st;
117354 }
117355 }
117356
117357 (void) memcpy (dest: out->data, src: pBuffer, n: keyLen);
117358 UA_free (ptr: pBuffer);
117359 UA_free (ptr: ctx);
117360
117361 return UA_STATUSCODE_GOOD;
117362}
117363
117364UA_StatusCode
117365UA_OpenSSL_HMAC_SHA1_Verify (const UA_ByteString * message,
117366 const UA_ByteString * key,
117367 const UA_ByteString * signature
117368 ) {
117369 unsigned char buf[SHA1_DIGEST_LENGTH] = {0};
117370 UA_ByteString mac = {SHA1_DIGEST_LENGTH, buf};
117371
117372 if(HMAC (evp_md: EVP_sha1(), key: key->data, key_len: (int) key->length, data: message->data, data_len: message->length,
117373 md: mac.data, md_len: (unsigned int *) &mac.length) == NULL) {
117374 return UA_STATUSCODE_BADINTERNALERROR;
117375 }
117376 if (UA_ByteString_equal (p1: signature, p2: &mac)) {
117377 return UA_STATUSCODE_GOOD;
117378 }
117379 else {
117380 return UA_STATUSCODE_BADINTERNALERROR;
117381 }
117382}
117383
117384UA_StatusCode
117385UA_OpenSSL_HMAC_SHA1_Sign (const UA_ByteString * message,
117386 const UA_ByteString * key,
117387 UA_ByteString * signature
117388 ) {
117389 if (HMAC (evp_md: EVP_sha1(), key: key->data, key_len: (int) key->length, data: message->data,
117390 data_len: message->length,
117391 md: signature->data, md_len: (unsigned int *) &(signature->length)) == NULL) {
117392 return UA_STATUSCODE_BADINTERNALERROR;
117393 }
117394 return UA_STATUSCODE_GOOD;
117395}
117396
117397UA_StatusCode
117398UA_Openssl_RSA_PKCS1_V15_Decrypt (UA_ByteString * data,
117399 EVP_PKEY * privateKey) {
117400 return UA_Openssl_RSA_Private_Decrypt (data, privateKey,
117401 RSA_PKCS1_PADDING, false);
117402}
117403
117404UA_StatusCode
117405UA_Openssl_RSA_PKCS1_V15_Encrypt (UA_ByteString * data,
117406 size_t paddingSize,
117407 X509 * publicX509) {
117408 UA_ByteString message;
117409 UA_StatusCode ret = UA_ByteString_copy (src: data, dst: &message);
117410 if (ret != UA_STATUSCODE_GOOD) {
117411 return ret;
117412 }
117413 ret = UA_Openssl_RSA_Public_Encrypt (message: &message, publicX509,
117414 RSA_PKCS1_PADDING,
117415 paddingSize,
117416 encrypted: data, false);
117417 UA_ByteString_clear (p: &message);
117418 return ret;
117419}
117420
117421UA_StatusCode
117422UA_OpenSSL_AES_128_CBC_Decrypt (const UA_ByteString * iv,
117423 const UA_ByteString * key,
117424 UA_ByteString * data /* [in/out]*/
117425 ) {
117426 return UA_OpenSSL_Decrypt (iv, key, cipherAlg: EVP_aes_128_cbc (), data);
117427}
117428
117429UA_StatusCode
117430UA_OpenSSL_AES_128_CBC_Encrypt (const UA_ByteString * iv,
117431 const UA_ByteString * key,
117432 UA_ByteString * data /* [in/out]*/
117433 ) {
117434 return UA_OpenSSL_Encrypt (iv, key, cipherAlg: EVP_aes_128_cbc (), data);
117435}
117436
117437EVP_PKEY *
117438UA_OpenSSL_LoadPrivateKey(const UA_ByteString *privateKey) {
117439 const unsigned char * pkData = privateKey->data;
117440 long len = (long) privateKey->length;
117441 if(len == 0)
117442 return NULL;
117443
117444 EVP_PKEY *result = NULL;
117445
117446 if (len > 1 && pkData[0] == 0x30 && pkData[1] == 0x82) { // Magic number for DER encoded keys
117447 result = d2i_PrivateKey(EVP_PKEY_RSA, NULL,
117448 pp: &pkData, length: len);
117449 } else {
117450 BIO *bio = NULL;
117451 bio = BIO_new_mem_buf(buf: (void *) privateKey->data, len: (int) privateKey->length);
117452 result = PEM_read_bio_PrivateKey(out: bio, NULL, NULL, NULL);
117453 BIO_free(a: bio);
117454 }
117455
117456 return result;
117457}
117458
117459X509 *
117460UA_OpenSSL_LoadCertificate(const UA_ByteString *certificate) {
117461 X509 * result = NULL;
117462 const unsigned char *pData = certificate->data;
117463
117464 if (certificate->length > 1 && pData[0] == 0x30 && pData[1] == 0x82) { // Magic number for DER encoded files
117465 result = UA_OpenSSL_LoadDerCertificate(certificate);
117466 } else {
117467 result = UA_OpenSSL_LoadPemCertificate(certificate);
117468 }
117469
117470 return result;
117471}
117472
117473X509 *
117474UA_OpenSSL_LoadDerCertificate(const UA_ByteString *certificate) {
117475 const unsigned char *pData = certificate->data;
117476 return d2i_X509(NULL, in: &pData, len: (long) certificate->length);
117477}
117478
117479X509 *
117480UA_OpenSSL_LoadPemCertificate(const UA_ByteString *certificate) {
117481 X509 * result = NULL;
117482
117483 BIO* bio = NULL;
117484 bio = BIO_new_mem_buf(buf: (void *) certificate->data, len: (int) certificate->length);
117485 result = PEM_read_bio_X509(out: bio, NULL, NULL, NULL);
117486 BIO_free(a: bio);
117487
117488 return result;
117489}
117490
117491UA_StatusCode
117492UA_OpenSSL_LoadLocalCertificate(const UA_ByteString *certificate, UA_ByteString *target) {
117493 X509 *cert = UA_OpenSSL_LoadCertificate(certificate);
117494
117495 if (!cert) {
117496 UA_ByteString_init(p: target);
117497 return UA_STATUSCODE_BADINVALIDARGUMENT;
117498 }
117499
117500 unsigned char *derData = NULL;
117501 int length = i2d_X509(a: cert, out: &derData);
117502 X509_free(a: cert);
117503
117504 if (length > 0) {
117505 UA_ByteString temp;
117506 temp.length = (size_t) length;
117507 temp.data = derData;
117508 UA_ByteString_copy(src: &temp, dst: target);
117509 OPENSSL_free(derData);
117510 return UA_STATUSCODE_GOOD;
117511 } else {
117512 UA_ByteString_init(p: target);
117513 }
117514
117515 return UA_STATUSCODE_BADINVALIDARGUMENT;
117516}
117517
117518#endif
117519
117520/**** amalgamated original file "/plugins/crypto/openssl/ua_openssl_basic128rsa15.c" ****/
117521
117522/* This Source Code Form is subject to the terms of the Mozilla Public
117523 * License, v. 2.0. If a copy of the MPL was not distributed with this
117524 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
117525 *
117526 * Copyright 2020 (c) Wind River Systems, Inc.
117527 * Copyright 2020 (c) basysKom GmbH
117528 */
117529
117530
117531#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL)
117532
117533
117534#include <openssl/x509.h>
117535#include <openssl/rand.h>
117536#include <openssl/evp.h>
117537
117538#define UA_SHA1_LENGTH 20
117539#define UA_SECURITYPOLICY_BASIC128RSA15_RSAPADDING_LEN 11
117540#define UA_SECURITYPOLICY_BASIC128RSA15_SYM_ENCRYPTION_KEY_LENGTH 16
117541#define UA_SECURITYPOLICY_BASIC128RSA15_SYM_ENCRYPTION_BLOCK_SIZE 16
117542#define UA_SECURITYPOLICY_BASIC128RSA15_SYM_SIGNING_KEY_LENGTH 16
117543#define UA_SHA1_LENGTH 20
117544
117545typedef struct {
117546 EVP_PKEY * localPrivateKey;
117547 UA_ByteString localCertThumbprint;
117548 const UA_Logger * logger;
117549} Policy_Context_Basic128Rsa15;
117550
117551typedef struct {
117552 UA_ByteString localSymSigningKey;
117553 UA_ByteString localSymEncryptingKey;
117554 UA_ByteString localSymIv;
117555 UA_ByteString remoteSymSigningKey;
117556 UA_ByteString remoteSymEncryptingKey;
117557 UA_ByteString remoteSymIv;
117558
117559 Policy_Context_Basic128Rsa15 * policyContext;
117560 UA_ByteString remoteCertificate;
117561 X509 * remoteCertificateX509;
117562} Channel_Context_Basic128Rsa15;
117563
117564static UA_StatusCode
117565UA_Policy_Basic128Rsa15_New_Context (UA_SecurityPolicy * securityPolicy,
117566 const UA_ByteString localPrivateKey,
117567 const UA_Logger * logger) {
117568 Policy_Context_Basic128Rsa15 * context = (Policy_Context_Basic128Rsa15 *)
117569 UA_malloc (size: sizeof (Policy_Context_Basic128Rsa15));
117570 if (context == NULL) {
117571 return UA_STATUSCODE_BADOUTOFMEMORY;
117572 }
117573
117574 context->localPrivateKey = UA_OpenSSL_LoadPrivateKey(privateKey: &localPrivateKey);
117575
117576 if (!context->localPrivateKey) {
117577 UA_free(ptr: context);
117578 return UA_STATUSCODE_BADINVALIDARGUMENT;
117579 }
117580
117581 UA_StatusCode retval = UA_Openssl_X509_GetCertificateThumbprint (
117582 certficate: &securityPolicy->localCertificate,
117583 pThumbprint: &context->localCertThumbprint, true
117584 );
117585 if (retval != UA_STATUSCODE_GOOD) {
117586 EVP_PKEY_free(pkey: context->localPrivateKey);
117587 UA_free (ptr: context);
117588 return retval;
117589 }
117590
117591 context->logger = logger;
117592 securityPolicy->policyContext = context;
117593
117594 return UA_STATUSCODE_GOOD;
117595}
117596
117597static void
117598UA_Policy_Basic128Rsa15_Clear_Context (UA_SecurityPolicy *policy) {
117599 if (policy == NULL) {
117600 return;
117601 }
117602 UA_ByteString_clear(p: &policy->localCertificate);
117603
117604 Policy_Context_Basic128Rsa15 * ctx = (Policy_Context_Basic128Rsa15 *) policy->policyContext;
117605 if (ctx == NULL) {
117606 return;
117607 }
117608
117609 /* delete all allocated members in the context */
117610
117611 EVP_PKEY_free(pkey: ctx->localPrivateKey);
117612 UA_ByteString_clear(p: &ctx->localCertThumbprint);
117613 UA_free (ptr: ctx);
117614
117615 return;
117616}
117617
117618static UA_StatusCode
117619updateCertificateAndPrivateKey_sp_basic128rsa15(UA_SecurityPolicy *securityPolicy,
117620 const UA_ByteString newCertificate,
117621 const UA_ByteString newPrivateKey) {
117622 if(securityPolicy == NULL)
117623 return UA_STATUSCODE_BADINTERNALERROR;
117624
117625 if(securityPolicy->policyContext == NULL)
117626 return UA_STATUSCODE_BADINTERNALERROR;
117627
117628 Policy_Context_Basic128Rsa15 *pc =
117629 (Policy_Context_Basic128Rsa15 *)securityPolicy->policyContext;
117630
117631 UA_ByteString_clear(p: &securityPolicy->localCertificate);
117632
117633 UA_StatusCode retval = UA_OpenSSL_LoadLocalCertificate(
117634 certificate: &newCertificate, target: &securityPolicy->localCertificate);
117635
117636 if(retval != UA_STATUSCODE_GOOD)
117637 return retval;
117638
117639 /* Set the new private key */
117640 EVP_PKEY_free(pkey: pc->localPrivateKey);
117641
117642 pc->localPrivateKey = UA_OpenSSL_LoadPrivateKey(privateKey: &newPrivateKey);
117643
117644 if(!pc->localPrivateKey) {
117645 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
117646 goto error;
117647 }
117648
117649 UA_ByteString_clear(p: &pc->localCertThumbprint);
117650
117651 retval = UA_Openssl_X509_GetCertificateThumbprint(certficate: &securityPolicy->localCertificate,
117652 pThumbprint: &pc->localCertThumbprint, true);
117653 if(retval != UA_STATUSCODE_GOOD) {
117654 goto error;
117655 }
117656
117657 return retval;
117658
117659error:
117660 UA_LOG_ERROR(logger: securityPolicy->logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
117661 msg: "Could not update certificate and private key");
117662 if(securityPolicy->policyContext != NULL)
117663 UA_Policy_Basic128Rsa15_Clear_Context(policy: securityPolicy);
117664 return retval;
117665}
117666
117667/* create the channel context */
117668
117669static UA_StatusCode
117670UA_ChannelModule_Basic128Rsa15_New_Context (const UA_SecurityPolicy * securityPolicy,
117671 const UA_ByteString * remoteCertificate,
117672 void ** channelContext) {
117673 if (securityPolicy == NULL || remoteCertificate == NULL ||
117674 channelContext == NULL) {
117675 return UA_STATUSCODE_BADINTERNALERROR;
117676 }
117677 Channel_Context_Basic128Rsa15 * context = (Channel_Context_Basic128Rsa15 *)
117678 UA_malloc (size: sizeof (Channel_Context_Basic128Rsa15));
117679 if (context == NULL) {
117680 return UA_STATUSCODE_BADOUTOFMEMORY;
117681 }
117682
117683 UA_ByteString_init(p: &context->localSymSigningKey);
117684 UA_ByteString_init(p: &context->localSymEncryptingKey);
117685 UA_ByteString_init(p: &context->localSymIv);
117686 UA_ByteString_init(p: &context->remoteSymSigningKey);
117687 UA_ByteString_init(p: &context->remoteSymEncryptingKey);
117688 UA_ByteString_init(p: &context->remoteSymIv);
117689
117690 UA_StatusCode retval = UA_copyCertificate (dst: &context->remoteCertificate,
117691 src: remoteCertificate);
117692 if (retval != UA_STATUSCODE_GOOD) {
117693 UA_free (ptr: context);
117694 return retval;
117695 }
117696
117697 /* decode to X509 */
117698 context->remoteCertificateX509 = UA_OpenSSL_LoadCertificate(certificate: &context->remoteCertificate);
117699 if (context->remoteCertificateX509 == NULL) {
117700 UA_ByteString_clear (p: &context->remoteCertificate);
117701 UA_free (ptr: context);
117702 return UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE;
117703 }
117704
117705 context->policyContext = (Policy_Context_Basic128Rsa15 *)
117706 (securityPolicy->policyContext);
117707
117708 *channelContext = context;
117709
117710 UA_LOG_INFO (logger: securityPolicy->logger,
117711 category: UA_LOGCATEGORY_SECURITYPOLICY,
117712 msg: "The Basic128Rsa15 security policy channel with openssl is created.");
117713
117714 return UA_STATUSCODE_GOOD;
117715}
117716
117717/* delete the channel context */
117718
117719static void
117720UA_ChannelModule_Basic128Rsa15_Delete_Context (void * channelContext) {
117721 if (channelContext != NULL) {
117722 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *)
117723 channelContext;
117724 X509_free (a: cc->remoteCertificateX509);
117725 UA_ByteString_clear (p: &cc->remoteCertificate);
117726 UA_ByteString_clear (p: &cc->localSymSigningKey);
117727 UA_ByteString_clear (p: &cc->localSymEncryptingKey);
117728 UA_ByteString_clear (p: &cc->localSymIv);
117729 UA_ByteString_clear (p: &cc->remoteSymSigningKey);
117730 UA_ByteString_clear (p: &cc->remoteSymEncryptingKey);
117731 UA_ByteString_clear (p: &cc->remoteSymIv);
117732 UA_LOG_INFO (logger: cc->policyContext->logger,
117733 category: UA_LOGCATEGORY_SECURITYPOLICY,
117734 msg: "The Basic128Rsa15 security policy channel with openssl is deleted.");
117735
117736 UA_free (ptr: cc);
117737 }
117738}
117739
117740static UA_StatusCode
117741UA_ChannelModule_Basic128Rsa15_setLocalSymSigningKey (void * channelContext,
117742 const UA_ByteString * key) {
117743 if (key == NULL || channelContext == NULL) {
117744 return UA_STATUSCODE_BADINVALIDARGUMENT;
117745 }
117746
117747 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *) channelContext;
117748 UA_ByteString_clear(p: &cc->localSymSigningKey);
117749 return UA_ByteString_copy(src: key, dst: &cc->localSymSigningKey);
117750}
117751
117752static UA_StatusCode
117753UA_ChannelModule_Basic128Rsa15_setLocalSymEncryptingKey (void * channelContext,
117754 const UA_ByteString * key) {
117755 if (key == NULL || channelContext == NULL) {
117756 return UA_STATUSCODE_BADINVALIDARGUMENT;
117757 }
117758
117759 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *) channelContext;
117760 UA_ByteString_clear(p: &cc->localSymEncryptingKey);
117761 return UA_ByteString_copy(src: key, dst: &cc->localSymEncryptingKey);
117762}
117763
117764static UA_StatusCode
117765UA_ChannelModule_Basic128Rsa15_setLocalSymIv (void * channelContext,
117766 const UA_ByteString * iv) {
117767 if (iv == NULL || channelContext == NULL) {
117768 return UA_STATUSCODE_BADINVALIDARGUMENT;
117769 }
117770
117771 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *) channelContext;
117772 UA_ByteString_clear(p: &cc->localSymIv);
117773 return UA_ByteString_copy(src: iv, dst: &cc->localSymIv);
117774}
117775
117776static UA_StatusCode
117777UA_ChannelModule_Basic128Rsa15_setRemoteSymSigningKey (void * channelContext,
117778 const UA_ByteString * key) {
117779 if (key == NULL || channelContext == NULL) {
117780 return UA_STATUSCODE_BADINVALIDARGUMENT;
117781 }
117782
117783 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *) channelContext;
117784 UA_ByteString_clear(p: &cc->remoteSymSigningKey);
117785 return UA_ByteString_copy(src: key, dst: &cc->remoteSymSigningKey);
117786}
117787
117788static UA_StatusCode
117789UA_ChannelModule_Basic128Rsa15_setRemoteSymEncryptingKey (void * channelContext,
117790 const UA_ByteString * key) {
117791 if (key == NULL || channelContext == NULL) {
117792 return UA_STATUSCODE_BADINVALIDARGUMENT;
117793 }
117794
117795 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *) channelContext;
117796 UA_ByteString_clear(p: &cc->remoteSymEncryptingKey);
117797 return UA_ByteString_copy(src: key, dst: &cc->remoteSymEncryptingKey);
117798}
117799
117800static UA_StatusCode
117801UA_ChannelModule_Basic128Rsa15_setRemoteSymIv (void * channelContext,
117802 const UA_ByteString * key) {
117803 if (key == NULL || channelContext == NULL) {
117804 return UA_STATUSCODE_BADINVALIDARGUMENT;
117805 }
117806
117807 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *) channelContext;
117808 UA_ByteString_clear(p: &cc->remoteSymIv);
117809 return UA_ByteString_copy(src: key, dst: &cc->remoteSymIv);
117810}
117811
117812static UA_StatusCode
117813UA_ChannelModule_Basic128Rsa15_compareCertificate (const void * channelContext,
117814 const UA_ByteString * certificate) {
117815 if(channelContext == NULL || certificate == NULL) {
117816 return UA_STATUSCODE_BADINVALIDARGUMENT;
117817 }
117818
117819 const Channel_Context_Basic128Rsa15 * cc =
117820 (const Channel_Context_Basic128Rsa15 *) channelContext;
117821 return UA_OpenSSL_X509_compare (cert: certificate, bcert: cc->remoteCertificateX509);
117822}
117823
117824static UA_StatusCode
117825UA_Asy_Basic128Rsa15_compareCertificateThumbprint (const UA_SecurityPolicy * securityPolicy,
117826 const UA_ByteString * certificateThumbprint) {
117827 if (securityPolicy == NULL || certificateThumbprint == NULL) {
117828 return UA_STATUSCODE_BADINVALIDARGUMENT;
117829 }
117830 Policy_Context_Basic128Rsa15 *pc = (Policy_Context_Basic128Rsa15 *)
117831 securityPolicy->policyContext;
117832 if(!UA_ByteString_equal(p1: certificateThumbprint, p2: &pc->localCertThumbprint)) {
117833 return UA_STATUSCODE_BADCERTIFICATEINVALID;
117834 }
117835 return UA_STATUSCODE_GOOD;
117836}
117837
117838/* Generates a thumbprint for the specified certificate */
117839
117840static UA_StatusCode
117841UA_Asy_Basic128Rsa15_makeCertificateThumbprint (const UA_SecurityPolicy * securityPolicy,
117842 const UA_ByteString * certificate,
117843 UA_ByteString * thumbprint) {
117844 return UA_Openssl_X509_GetCertificateThumbprint (certficate: certificate,
117845 pThumbprint: thumbprint, false);
117846}
117847
117848static size_t
117849UA_AsySig_Basic128Rsa15_getRemoteSignatureSize (const void * channelContext) {
117850 if (channelContext == NULL) {
117851 return UA_STATUSCODE_BADINVALIDARGUMENT;
117852 }
117853
117854 const Channel_Context_Basic128Rsa15 * cc = (const Channel_Context_Basic128Rsa15 *) channelContext;
117855 UA_Int32 keyLen = 0;
117856 UA_Openssl_RSA_Public_GetKeyLength (publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
117857 return (size_t) keyLen;
117858}
117859
117860static size_t
117861UA_AsySig_Basic128Rsa15_getLocalSignatureSize (const void * channelContext) {
117862 if (channelContext == NULL) {
117863 return UA_STATUSCODE_BADINVALIDARGUMENT;
117864 }
117865
117866 const Channel_Context_Basic128Rsa15 * cc = (const Channel_Context_Basic128Rsa15 *) channelContext;
117867 Policy_Context_Basic128Rsa15 * pc = (Policy_Context_Basic128Rsa15 *) cc->policyContext;
117868 UA_Int32 keyLen = 0;
117869 UA_Openssl_RSA_Private_GetKeyLength (privateKey: pc->localPrivateKey, keyLen: &keyLen);
117870
117871 return (size_t) keyLen;
117872}
117873
117874static UA_StatusCode
117875UA_AsySig_Basic128Rsa15_Verify (void * channelContext,
117876 const UA_ByteString * message,
117877 const UA_ByteString * signature) {
117878 if (message == NULL || signature == NULL ||
117879 channelContext == NULL) {
117880 return UA_STATUSCODE_BADINVALIDARGUMENT;
117881 }
117882
117883 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *) channelContext;
117884 UA_StatusCode retval = UA_OpenSSL_RSA_PKCS1_V15_SHA1_Verify (msg: message,
117885 publicKeyX509: cc->remoteCertificateX509, signature);
117886
117887 return retval;
117888}
117889
117890static UA_StatusCode
117891UA_AsySig_Basic128Rsa15_Sign (void * channelContext,
117892 const UA_ByteString * message,
117893 UA_ByteString * signature) {
117894 if (channelContext == NULL || message == NULL || signature == NULL) {
117895 return UA_STATUSCODE_BADINVALIDARGUMENT;
117896 }
117897
117898 const Channel_Context_Basic128Rsa15 * cc = (const Channel_Context_Basic128Rsa15 *) channelContext;
117899 Policy_Context_Basic128Rsa15 *pc = cc->policyContext;
117900 return UA_Openssl_RSA_PKCS1_V15_SHA1_Sign (message, privateKey: pc->localPrivateKey, outSignature: signature);
117901}
117902
117903static size_t
117904UA_AsymEn_Basic128Rsa15_getRemotePlainTextBlockSize (const void *channelContext) {
117905 if (channelContext == NULL) {
117906 return UA_STATUSCODE_BADINVALIDARGUMENT;
117907 }
117908
117909 const Channel_Context_Basic128Rsa15 * cc = (const Channel_Context_Basic128Rsa15 *) channelContext;
117910 UA_Int32 keyLen = 0;
117911 UA_Openssl_RSA_Public_GetKeyLength (publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
117912 return (size_t) keyLen - UA_SECURITYPOLICY_BASIC128RSA15_RSAPADDING_LEN;
117913}
117914
117915static size_t
117916UA_AsymEn_Basic128Rsa15_getRemoteBlockSize (const void *channelContext) {
117917 if (channelContext == NULL) {
117918 return UA_STATUSCODE_BADINVALIDARGUMENT;
117919 }
117920
117921 const Channel_Context_Basic128Rsa15 * cc = (const Channel_Context_Basic128Rsa15 *) channelContext;
117922 UA_Int32 keyLen = 0;
117923 UA_Openssl_RSA_Public_GetKeyLength (publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
117924 return (size_t) keyLen;
117925}
117926
117927static size_t
117928UA_AsymEn_Basic128Rsa15_getRemoteKeyLength (const void *channelContext) {
117929 if (channelContext == NULL)
117930 return UA_STATUSCODE_BADINVALIDARGUMENT;
117931
117932 const Channel_Context_Basic128Rsa15 * cc = (const Channel_Context_Basic128Rsa15 *) channelContext;
117933 UA_Int32 keyLen = 0;
117934 UA_Openssl_RSA_Public_GetKeyLength (publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
117935 return (size_t) keyLen * 8;
117936}
117937
117938static size_t
117939UA_AsymEn_Basic128Rsa15_getLocalKeyLength (const void *channelContext) {
117940 if (channelContext == NULL)
117941 return UA_STATUSCODE_BADINVALIDARGUMENT;
117942
117943 const Channel_Context_Basic128Rsa15 *cc = (const Channel_Context_Basic128Rsa15 *) channelContext;
117944 Policy_Context_Basic128Rsa15 *pc = cc->policyContext;
117945 UA_Int32 keyLen = 0;
117946 UA_Openssl_RSA_Private_GetKeyLength (privateKey: pc->localPrivateKey, keyLen: &keyLen);
117947 return (size_t) keyLen * 8;
117948}
117949
117950static UA_StatusCode
117951UA_AsymEn_Basic128Rsa15_Decrypt (void * channelContext,
117952 UA_ByteString * data) {
117953 if (channelContext == NULL || data == NULL) {
117954 return UA_STATUSCODE_BADINVALIDARGUMENT;
117955 }
117956
117957 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *) channelContext;
117958 UA_StatusCode ret = UA_Openssl_RSA_PKCS1_V15_Decrypt (data,
117959 privateKey: cc->policyContext->localPrivateKey);
117960 return ret;
117961}
117962
117963static UA_StatusCode
117964UA_AsymEn_Basic128Rsa15_Encrypt (void * channelContext,
117965 UA_ByteString * data) {
117966 if (channelContext == NULL || data == NULL)
117967 return UA_STATUSCODE_BADINVALIDARGUMENT;
117968
117969 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *) channelContext;
117970 return UA_Openssl_RSA_PKCS1_V15_Encrypt (data,
117971 UA_SECURITYPOLICY_BASIC128RSA15_RSAPADDING_LEN,
117972 publicX509: cc->remoteCertificateX509);
117973}
117974
117975static UA_StatusCode
117976UA_Sym_Basic128Rsa15_generateNonce(void *policyContext,
117977 UA_ByteString *out) {
117978 UA_Int32 rc = RAND_bytes(buf: out->data, num: (int) out->length);
117979 if (rc != 1) {
117980 return UA_STATUSCODE_BADUNEXPECTEDERROR;
117981 }
117982 return UA_STATUSCODE_GOOD;
117983}
117984
117985static UA_StatusCode
117986UA_Sym_Basic128Rsa15_generateKey(void *policyContext,
117987 const UA_ByteString *secret,
117988 const UA_ByteString *seed,
117989 UA_ByteString *out) {
117990 return UA_Openssl_Random_Key_PSHA1_Derive(secret, seed, out);
117991}
117992
117993static size_t
117994UA_SymEn_Basic128Rsa15_getLocalKeyLength (const void *channelContext) {
117995 /* 16 bytes 128 bits */
117996 return UA_SECURITYPOLICY_BASIC128RSA15_SYM_ENCRYPTION_KEY_LENGTH;
117997}
117998
117999static size_t
118000UA_SymEn_Basic128Rsa15_getBlockSize (const void *channelContext) {
118001 return UA_SECURITYPOLICY_BASIC128RSA15_SYM_ENCRYPTION_BLOCK_SIZE;
118002}
118003
118004static size_t
118005UA_SymEn_Basic128Rsa15_getRemoteKeyLength (const void * channelContext) {
118006 return UA_SECURITYPOLICY_BASIC128RSA15_SYM_ENCRYPTION_KEY_LENGTH;
118007}
118008
118009static UA_StatusCode
118010UA_SymEn_Basic128Rsa15_Encrypt (void *channelContext,
118011 UA_ByteString *data) {
118012 if(channelContext == NULL || data == NULL)
118013 return UA_STATUSCODE_BADINVALIDARGUMENT;
118014
118015 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *) channelContext;
118016 return UA_OpenSSL_AES_128_CBC_Encrypt (iv: &cc->localSymIv, key: &cc->localSymEncryptingKey, data);
118017}
118018
118019static UA_StatusCode
118020UA_SymEn_Basic128Rsa15_Decrypt (void * channelContext,
118021 UA_ByteString * data) {
118022 if(channelContext == NULL || data == NULL)
118023 return UA_STATUSCODE_BADINVALIDARGUMENT;
118024 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *) channelContext;
118025 return UA_OpenSSL_AES_128_CBC_Decrypt (iv: &cc->remoteSymIv, key: &cc->remoteSymEncryptingKey, data);
118026}
118027
118028static size_t
118029UA_SymSig_Basic128Rsa15_getKeyLength (const void *channelContext) {
118030 return UA_SECURITYPOLICY_BASIC128RSA15_SYM_SIGNING_KEY_LENGTH;
118031}
118032
118033static size_t
118034UA_SymSig_Basic128Rsa15_getSignatureSize (const void *channelContext) {
118035 return UA_SHA1_LENGTH;
118036}
118037
118038static UA_StatusCode
118039UA_SymSig_Basic128Rsa15_Verify (void * channelContext,
118040 const UA_ByteString * message,
118041 const UA_ByteString * signature) {
118042 if (channelContext == NULL || message == NULL || signature == NULL)
118043 return UA_STATUSCODE_BADINVALIDARGUMENT;
118044
118045 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *) channelContext;
118046 return UA_OpenSSL_HMAC_SHA1_Verify (message,
118047 key: &cc->remoteSymSigningKey,
118048 signature);
118049}
118050
118051static UA_StatusCode
118052UA_SymSig_Basic128Rsa15_Sign (void * channelContext,
118053 const UA_ByteString * message,
118054 UA_ByteString * signature) {
118055 if (channelContext == NULL || message == NULL || signature == NULL)
118056 return UA_STATUSCODE_BADINVALIDARGUMENT;
118057
118058 Channel_Context_Basic128Rsa15 * cc = (Channel_Context_Basic128Rsa15 *) channelContext;
118059 return UA_OpenSSL_HMAC_SHA1_Sign (message, key: &cc->localSymSigningKey, signature);
118060}
118061
118062/* the main entry of Basic128Rsa15 */
118063
118064UA_StatusCode
118065UA_SecurityPolicy_Basic128Rsa15 (UA_SecurityPolicy * policy,
118066 const UA_ByteString localCertificate,
118067 const UA_ByteString localPrivateKey,
118068 const UA_Logger * logger) {
118069
118070 UA_LOG_WARNING(logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
118071 msg: "!! WARNING !! The Basic128Rsa15 SecurityPolicy is unsecure. "
118072 "There are known attacks that break the encryption.");
118073
118074 UA_SecurityPolicyAsymmetricModule * const asymmetricModule = &policy->asymmetricModule;
118075 UA_SecurityPolicySymmetricModule * const symmetricModule = &policy->symmetricModule;
118076 UA_SecurityPolicyChannelModule * const channelModule = &policy->channelModule;
118077 UA_StatusCode retval;
118078
118079 UA_LOG_INFO (logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
118080 msg: "The Basic128Rsa15 security policy with openssl is added.");
118081
118082 UA_Openssl_Init ();
118083 memset(s: policy, c: 0, n: sizeof(UA_SecurityPolicy));
118084 policy->logger = logger;
118085 policy->policyUri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15\0");
118086
118087 /* set ChannelModule context */
118088
118089 channelModule->newContext = UA_ChannelModule_Basic128Rsa15_New_Context;
118090 channelModule->deleteContext = UA_ChannelModule_Basic128Rsa15_Delete_Context;
118091
118092 channelModule->setLocalSymSigningKey = UA_ChannelModule_Basic128Rsa15_setLocalSymSigningKey;
118093 channelModule->setLocalSymEncryptingKey = UA_ChannelModule_Basic128Rsa15_setLocalSymEncryptingKey;
118094 channelModule->setLocalSymIv = UA_ChannelModule_Basic128Rsa15_setLocalSymIv;
118095 channelModule->setRemoteSymSigningKey = UA_ChannelModule_Basic128Rsa15_setRemoteSymSigningKey;
118096 channelModule->setRemoteSymEncryptingKey = UA_ChannelModule_Basic128Rsa15_setRemoteSymEncryptingKey;
118097 channelModule->setRemoteSymIv = UA_ChannelModule_Basic128Rsa15_setRemoteSymIv;
118098 channelModule->compareCertificate = UA_ChannelModule_Basic128Rsa15_compareCertificate;
118099
118100 retval = UA_OpenSSL_LoadLocalCertificate(certificate: &localCertificate, target: &policy->localCertificate);
118101
118102 if (retval != UA_STATUSCODE_GOOD)
118103 return retval;
118104
118105 /* asymmetricModule */
118106
118107 asymmetricModule->compareCertificateThumbprint = UA_Asy_Basic128Rsa15_compareCertificateThumbprint;
118108 asymmetricModule->makeCertificateThumbprint = UA_Asy_Basic128Rsa15_makeCertificateThumbprint;
118109
118110 /* AsymmetricModule - signature algorithm */
118111
118112 UA_SecurityPolicySignatureAlgorithm * asySigAlgorithm =
118113 &asymmetricModule->cryptoModule.signatureAlgorithm;
118114 asySigAlgorithm->uri = UA_STRING(chars: "http://www.w3.org/2000/09/xmldsig#rsa-sha1\0");
118115 asySigAlgorithm->getRemoteSignatureSize = UA_AsySig_Basic128Rsa15_getRemoteSignatureSize;
118116 asySigAlgorithm->getLocalSignatureSize = UA_AsySig_Basic128Rsa15_getLocalSignatureSize;
118117 asySigAlgorithm->getLocalKeyLength = NULL;
118118 asySigAlgorithm->getRemoteKeyLength = NULL;
118119 asySigAlgorithm->verify = UA_AsySig_Basic128Rsa15_Verify;
118120 asySigAlgorithm->sign = UA_AsySig_Basic128Rsa15_Sign;
118121
118122 /* AsymmetricModule encryption algorithm */
118123
118124 UA_SecurityPolicyEncryptionAlgorithm * asymEncryAlg =
118125 &asymmetricModule->cryptoModule.encryptionAlgorithm;
118126 asymEncryAlg->uri = UA_STRING(chars: "http://www.w3.org/2001/04/xmlenc#rsa-1_5\0");
118127 asymEncryAlg->getRemotePlainTextBlockSize = UA_AsymEn_Basic128Rsa15_getRemotePlainTextBlockSize;
118128 asymEncryAlg->getRemoteBlockSize = UA_AsymEn_Basic128Rsa15_getRemoteBlockSize;
118129 asymEncryAlg->getRemoteKeyLength = UA_AsymEn_Basic128Rsa15_getRemoteKeyLength;
118130 asymEncryAlg->getLocalKeyLength = UA_AsymEn_Basic128Rsa15_getLocalKeyLength;
118131 asymEncryAlg->decrypt = UA_AsymEn_Basic128Rsa15_Decrypt;
118132 asymEncryAlg->encrypt = UA_AsymEn_Basic128Rsa15_Encrypt;
118133
118134 /* SymmetricModule */
118135
118136 symmetricModule->secureChannelNonceLength = 16; /* 128 bits*/
118137 symmetricModule->generateNonce = UA_Sym_Basic128Rsa15_generateNonce;
118138 symmetricModule->generateKey = UA_Sym_Basic128Rsa15_generateKey;
118139
118140 /* Symmetric encryption Algorithm */
118141
118142 UA_SecurityPolicyEncryptionAlgorithm * symEncryptionAlgorithm =
118143 &symmetricModule->cryptoModule.encryptionAlgorithm;
118144 symEncryptionAlgorithm->uri = UA_STRING(chars: "http://www.w3.org/2001/04/xmlenc#aes128-cbc\0");
118145 symEncryptionAlgorithm->getLocalKeyLength = UA_SymEn_Basic128Rsa15_getLocalKeyLength;
118146 symEncryptionAlgorithm->getRemoteKeyLength = UA_SymEn_Basic128Rsa15_getRemoteKeyLength;
118147 symEncryptionAlgorithm->getRemoteBlockSize = UA_SymEn_Basic128Rsa15_getBlockSize;
118148 symEncryptionAlgorithm->getRemotePlainTextBlockSize = UA_SymEn_Basic128Rsa15_getBlockSize;
118149 symEncryptionAlgorithm->decrypt = UA_SymEn_Basic128Rsa15_Decrypt;
118150 symEncryptionAlgorithm->encrypt = UA_SymEn_Basic128Rsa15_Encrypt;
118151
118152 /* Symmetric signature Algorithm */
118153
118154 UA_SecurityPolicySignatureAlgorithm * symSignatureAlgorithm =
118155 &symmetricModule->cryptoModule.signatureAlgorithm;
118156 symSignatureAlgorithm->uri = UA_STRING(chars: "http://www.w3.org/2000/09/xmldsig#hmac-sha1\0");
118157 symSignatureAlgorithm->getLocalKeyLength = UA_SymSig_Basic128Rsa15_getKeyLength;
118158 symSignatureAlgorithm->getRemoteKeyLength = UA_SymSig_Basic128Rsa15_getKeyLength;
118159 symSignatureAlgorithm->getRemoteSignatureSize = UA_SymSig_Basic128Rsa15_getSignatureSize;
118160 symSignatureAlgorithm->getLocalSignatureSize = UA_SymSig_Basic128Rsa15_getSignatureSize;
118161
118162 symSignatureAlgorithm->verify = UA_SymSig_Basic128Rsa15_Verify;
118163 symSignatureAlgorithm->sign = UA_SymSig_Basic128Rsa15_Sign;
118164
118165 /* set the policy context */
118166
118167 retval = UA_Policy_Basic128Rsa15_New_Context (securityPolicy: policy, localPrivateKey, logger);
118168 if (retval != UA_STATUSCODE_GOOD) {
118169 UA_ByteString_clear (p: &policy->localCertificate);
118170 return retval;
118171 }
118172 policy->updateCertificateAndPrivateKey =
118173 updateCertificateAndPrivateKey_sp_basic128rsa15;
118174 policy->clear = UA_Policy_Basic128Rsa15_Clear_Context;
118175
118176 /* Use the same signature algorithm as the asymmetric component for
118177 certificate signing (see standard) */
118178 policy->certificateSigningAlgorithm = policy->asymmetricModule.cryptoModule.signatureAlgorithm;
118179
118180 return UA_STATUSCODE_GOOD;
118181}
118182
118183#endif
118184
118185/**** amalgamated original file "/plugins/crypto/openssl/ua_openssl_basic256.c" ****/
118186
118187/* This Source Code Form is subject to the terms of the Mozilla Public
118188 * License, v. 2.0. If a copy of the MPL was not distributed with this
118189 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
118190 *
118191 * Copyright 2020 (c) Wind River Systems, Inc.
118192 * Copyright 2020 (c) basysKom GmbH
118193 */
118194
118195
118196#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL)
118197
118198
118199#include <openssl/x509.h>
118200#include <openssl/rand.h>
118201
118202#define UA_SECURITYPOLICY_BASIC256SHA1_RSAPADDING_LEN 42
118203#define UA_SECURITYPOLICY_BASIC256_SYM_ENCRYPTION_KEY_LENGTH 32
118204#define UA_SECURITYPOLICY_BASIC256_SYM_ENCRYPTION_BLOCK_SIZE 16
118205#define UA_SECURITYPOLICY_BASIC256_SYM_SIGNING_KEY_LENGTH 24
118206#define UA_SHA1_LENGTH 20
118207
118208typedef struct {
118209 EVP_PKEY * localPrivateKey;
118210 UA_ByteString localCertThumbprint;
118211 const UA_Logger * logger;
118212} Policy_Context_Basic256;
118213
118214typedef struct {
118215 UA_ByteString localSymSigningKey;
118216 UA_ByteString localSymEncryptingKey;
118217 UA_ByteString localSymIv;
118218 UA_ByteString remoteSymSigningKey;
118219 UA_ByteString remoteSymEncryptingKey;
118220 UA_ByteString remoteSymIv;
118221
118222 Policy_Context_Basic256 * policyContext;
118223 UA_ByteString remoteCertificate;
118224 X509 * remoteCertificateX509;
118225} Channel_Context_Basic256;
118226
118227static UA_StatusCode
118228UA_Policy_Basic256_New_Context (UA_SecurityPolicy * securityPolicy,
118229 const UA_ByteString localPrivateKey,
118230 const UA_Logger * logger) {
118231 Policy_Context_Basic256 * context = (Policy_Context_Basic256 *)
118232 UA_malloc (size: sizeof (Policy_Context_Basic256));
118233 if (context == NULL) {
118234 return UA_STATUSCODE_BADOUTOFMEMORY;
118235 }
118236
118237 context->localPrivateKey = UA_OpenSSL_LoadPrivateKey(privateKey: &localPrivateKey);
118238
118239 if (!context->localPrivateKey) {
118240 UA_free (ptr: context);
118241 return UA_STATUSCODE_BADINVALIDARGUMENT;
118242 }
118243
118244 UA_StatusCode retval = UA_Openssl_X509_GetCertificateThumbprint (
118245 certficate: &securityPolicy->localCertificate,
118246 pThumbprint: &context->localCertThumbprint, true
118247 );
118248 if (retval != UA_STATUSCODE_GOOD) {
118249 EVP_PKEY_free(pkey: context->localPrivateKey);
118250 UA_free (ptr: context);
118251 return retval;
118252 }
118253
118254 context->logger = logger;
118255 securityPolicy->policyContext = context;
118256
118257 return UA_STATUSCODE_GOOD;
118258}
118259
118260static void
118261UA_Policy_Basic256_Clear_Context (UA_SecurityPolicy *policy) {
118262 if (policy == NULL) {
118263 return;
118264 }
118265 UA_ByteString_clear(p: &policy->localCertificate);
118266
118267 Policy_Context_Basic256 * ctx = (Policy_Context_Basic256 *) policy->policyContext;
118268 if (ctx == NULL) {
118269 return;
118270 }
118271
118272 /* delete all allocated members in the context */
118273
118274 EVP_PKEY_free(pkey: ctx->localPrivateKey);
118275 UA_ByteString_clear(p: &ctx->localCertThumbprint);
118276 UA_free (ptr: ctx);
118277
118278 return;
118279}
118280
118281static UA_StatusCode
118282updateCertificateAndPrivateKey_sp_basic256(UA_SecurityPolicy *securityPolicy,
118283 const UA_ByteString newCertificate,
118284 const UA_ByteString newPrivateKey) {
118285 if(securityPolicy == NULL)
118286 return UA_STATUSCODE_BADINTERNALERROR;
118287
118288 if(securityPolicy->policyContext == NULL)
118289 return UA_STATUSCODE_BADINTERNALERROR;
118290
118291 Policy_Context_Basic256 *pc =
118292 (Policy_Context_Basic256 *)securityPolicy->policyContext;
118293
118294 UA_ByteString_clear(p: &securityPolicy->localCertificate);
118295
118296 UA_StatusCode retval = UA_OpenSSL_LoadLocalCertificate(
118297 certificate: &newCertificate, target: &securityPolicy->localCertificate);
118298
118299 if(retval != UA_STATUSCODE_GOOD)
118300 return retval;
118301
118302 /* Set the new private key */
118303 EVP_PKEY_free(pkey: pc->localPrivateKey);
118304
118305 pc->localPrivateKey = UA_OpenSSL_LoadPrivateKey(privateKey: &newPrivateKey);
118306
118307 if(!pc->localPrivateKey) {
118308 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
118309 goto error;
118310 }
118311
118312 UA_ByteString_clear(p: &pc->localCertThumbprint);
118313
118314 retval = UA_Openssl_X509_GetCertificateThumbprint(certficate: &securityPolicy->localCertificate,
118315 pThumbprint: &pc->localCertThumbprint, true);
118316 if(retval != UA_STATUSCODE_GOOD) {
118317 goto error;
118318 }
118319
118320 return retval;
118321
118322error:
118323 UA_LOG_ERROR(logger: securityPolicy->logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
118324 msg: "Could not update certificate and private key");
118325 if(securityPolicy->policyContext != NULL)
118326 UA_Policy_Basic256_Clear_Context(policy: securityPolicy);
118327 return retval;
118328}
118329
118330/* create the channel context */
118331
118332static UA_StatusCode
118333UA_ChannelModule_Basic256_New_Context (const UA_SecurityPolicy * securityPolicy,
118334 const UA_ByteString * remoteCertificate,
118335 void ** channelContext) {
118336 if (securityPolicy == NULL || remoteCertificate == NULL ||
118337 channelContext == NULL) {
118338 return UA_STATUSCODE_BADINTERNALERROR;
118339 }
118340 Channel_Context_Basic256 * context = (Channel_Context_Basic256 *)
118341 UA_malloc (size: sizeof (Channel_Context_Basic256));
118342 if (context == NULL) {
118343 return UA_STATUSCODE_BADOUTOFMEMORY;
118344 }
118345
118346 UA_ByteString_init(p: &context->localSymSigningKey);
118347 UA_ByteString_init(p: &context->localSymEncryptingKey);
118348 UA_ByteString_init(p: &context->localSymIv);
118349 UA_ByteString_init(p: &context->remoteSymSigningKey);
118350 UA_ByteString_init(p: &context->remoteSymEncryptingKey);
118351 UA_ByteString_init(p: &context->remoteSymIv);
118352
118353 UA_StatusCode retval = UA_copyCertificate (dst: &context->remoteCertificate,
118354 src: remoteCertificate);
118355 if (retval != UA_STATUSCODE_GOOD) {
118356 UA_free (ptr: context);
118357 return retval;
118358 }
118359
118360 /* decode to X509 */
118361 context->remoteCertificateX509 = UA_OpenSSL_LoadCertificate(certificate: &context->remoteCertificate);
118362 if (context->remoteCertificateX509 == NULL) {
118363 UA_ByteString_clear (p: &context->remoteCertificate);
118364 UA_free (ptr: context);
118365 return UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE;
118366 }
118367
118368 context->policyContext = (Policy_Context_Basic256 *)
118369 (securityPolicy->policyContext);
118370
118371 *channelContext = context;
118372
118373 UA_LOG_INFO (logger: securityPolicy->logger,
118374 category: UA_LOGCATEGORY_SECURITYPOLICY,
118375 msg: "The basic256 security policy channel with openssl is created.");
118376
118377 return UA_STATUSCODE_GOOD;
118378}
118379
118380/* delete the channel context */
118381
118382static void
118383UA_ChannelModule_Basic256_Delete_Context (void * channelContext) {
118384 if (channelContext != NULL) {
118385 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *)
118386 channelContext;
118387 X509_free (a: cc->remoteCertificateX509);
118388 UA_ByteString_clear (p: &cc->remoteCertificate);
118389 UA_ByteString_clear (p: &cc->localSymSigningKey);
118390 UA_ByteString_clear (p: &cc->localSymEncryptingKey);
118391 UA_ByteString_clear (p: &cc->localSymIv);
118392 UA_ByteString_clear (p: &cc->remoteSymSigningKey);
118393 UA_ByteString_clear (p: &cc->remoteSymEncryptingKey);
118394 UA_ByteString_clear (p: &cc->remoteSymIv);
118395 UA_LOG_INFO (logger: cc->policyContext->logger,
118396 category: UA_LOGCATEGORY_SECURITYPOLICY,
118397 msg: "The basic256 security policy channel with openssl is deleted.");
118398
118399 UA_free (ptr: cc);
118400 }
118401}
118402
118403/* Compares the supplied certificate with the certificate
118404 * in the endpoint context
118405 */
118406
118407static UA_StatusCode
118408UA_Asy_Basic256_compareCertificateThumbprint (const UA_SecurityPolicy * securityPolicy,
118409 const UA_ByteString * certificateThumbprint) {
118410 if (securityPolicy == NULL || certificateThumbprint == NULL) {
118411 return UA_STATUSCODE_BADINVALIDARGUMENT;
118412 }
118413 Policy_Context_Basic256 *pc = (Policy_Context_Basic256 *)
118414 securityPolicy->policyContext;
118415 if(!UA_ByteString_equal(p1: certificateThumbprint, p2: &pc->localCertThumbprint)) {
118416 return UA_STATUSCODE_BADCERTIFICATEINVALID;
118417 }
118418 return UA_STATUSCODE_GOOD;
118419}
118420
118421/* Generates a thumbprint for the specified certificate */
118422
118423static UA_StatusCode
118424UA_Asy_Basic256_makeCertificateThumbprint (const UA_SecurityPolicy * securityPolicy,
118425 const UA_ByteString * certificate,
118426 UA_ByteString * thumbprint) {
118427 return UA_Openssl_X509_GetCertificateThumbprint (certficate: certificate,
118428 pThumbprint: thumbprint, false);
118429}
118430
118431static UA_StatusCode
118432UA_ChannelModule_Basic256_setLocalSymSigningKey (void * channelContext,
118433 const UA_ByteString * key) {
118434 if (key == NULL || channelContext == NULL) {
118435 return UA_STATUSCODE_BADINVALIDARGUMENT;
118436 }
118437
118438 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118439 UA_ByteString_clear(p: &cc->localSymSigningKey);
118440 return UA_ByteString_copy(src: key, dst: &cc->localSymSigningKey);
118441}
118442
118443static UA_StatusCode
118444UA_ChannelModule_Basic256_setLocalSymEncryptingKey (void * channelContext,
118445 const UA_ByteString * key) {
118446 if (key == NULL || channelContext == NULL) {
118447 return UA_STATUSCODE_BADINVALIDARGUMENT;
118448 }
118449
118450 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118451 UA_ByteString_clear(p: &cc->localSymEncryptingKey);
118452 return UA_ByteString_copy(src: key, dst: &cc->localSymEncryptingKey);
118453}
118454
118455static UA_StatusCode
118456UA_ChannelModule_Basic256_setLocalSymIv (void * channelContext,
118457 const UA_ByteString * iv) {
118458 if (iv == NULL || channelContext == NULL) {
118459 return UA_STATUSCODE_BADINVALIDARGUMENT;
118460 }
118461
118462 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118463 UA_ByteString_clear(p: &cc->localSymIv);
118464 return UA_ByteString_copy(src: iv, dst: &cc->localSymIv);
118465}
118466
118467static UA_StatusCode
118468UA_ChannelModule_Basic256_setRemoteSymSigningKey (void * channelContext,
118469 const UA_ByteString * key) {
118470 if (key == NULL || channelContext == NULL) {
118471 return UA_STATUSCODE_BADINVALIDARGUMENT;
118472 }
118473
118474 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118475 UA_ByteString_clear(p: &cc->remoteSymSigningKey);
118476 return UA_ByteString_copy(src: key, dst: &cc->remoteSymSigningKey);
118477}
118478
118479static UA_StatusCode
118480UA_ChannelModule_Basic256_setRemoteSymEncryptingKey (void * channelContext,
118481 const UA_ByteString * key) {
118482 if (key == NULL || channelContext == NULL) {
118483 return UA_STATUSCODE_BADINVALIDARGUMENT;
118484 }
118485
118486 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118487 UA_ByteString_clear(p: &cc->remoteSymEncryptingKey);
118488 return UA_ByteString_copy(src: key, dst: &cc->remoteSymEncryptingKey);
118489}
118490
118491static UA_StatusCode
118492UA_ChannelModule_Basic256_setRemoteSymIv (void * channelContext,
118493 const UA_ByteString * key) {
118494 if (key == NULL || channelContext == NULL) {
118495 return UA_STATUSCODE_BADINVALIDARGUMENT;
118496 }
118497
118498 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118499 UA_ByteString_clear(p: &cc->remoteSymIv);
118500 return UA_ByteString_copy(src: key, dst: &cc->remoteSymIv);
118501}
118502
118503static UA_StatusCode
118504UA_ChannelModule_Basic256_compareCertificate (const void * channelContext,
118505 const UA_ByteString * certificate) {
118506 if(channelContext == NULL || certificate == NULL) {
118507 return UA_STATUSCODE_BADINVALIDARGUMENT;
118508 }
118509
118510 const Channel_Context_Basic256 * cc =
118511 (const Channel_Context_Basic256 *) channelContext;
118512 return UA_OpenSSL_X509_compare (cert: certificate, bcert: cc->remoteCertificateX509);
118513}
118514
118515static size_t
118516UA_AsySig_Basic256_getRemoteSignatureSize (const void *channelContext) {
118517 if (channelContext == NULL) {
118518 return UA_STATUSCODE_BADINVALIDARGUMENT;
118519 }
118520
118521 const Channel_Context_Basic256 * cc = (const Channel_Context_Basic256 *) channelContext;
118522 UA_Int32 keyLen = 0;
118523 UA_Openssl_RSA_Public_GetKeyLength (publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
118524 return (size_t) keyLen;
118525}
118526
118527static size_t
118528UA_AsySig_Basic256_getLocalSignatureSize (const void *channelContext) {
118529 if (channelContext == NULL) {
118530 return UA_STATUSCODE_BADINVALIDARGUMENT;
118531 }
118532
118533 const Channel_Context_Basic256 * cc = (const Channel_Context_Basic256 *) channelContext;
118534 Policy_Context_Basic256 * pc = cc->policyContext;
118535 UA_Int32 keyLen = 0;
118536 UA_Openssl_RSA_Private_GetKeyLength (privateKey: pc->localPrivateKey, keyLen: &keyLen);
118537
118538 return (size_t) keyLen;
118539}
118540
118541static UA_StatusCode
118542UA_AsySig_Basic256_Verify (void * channelContext,
118543 const UA_ByteString * message,
118544 const UA_ByteString * signature) {
118545 if (message == NULL || signature == NULL || channelContext == NULL) {
118546 return UA_STATUSCODE_BADINVALIDARGUMENT;
118547 }
118548
118549 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118550 UA_StatusCode retval = UA_OpenSSL_RSA_PKCS1_V15_SHA1_Verify (msg: message,
118551 publicKeyX509: cc->remoteCertificateX509, signature);
118552 return retval;
118553}
118554
118555static UA_StatusCode
118556UA_AsySig_Basic256_Sign (void * channelContext,
118557 const UA_ByteString * message,
118558 UA_ByteString * signature) {
118559 if (channelContext == NULL || message == NULL || signature == NULL) {
118560 return UA_STATUSCODE_BADINVALIDARGUMENT;
118561 }
118562
118563 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118564 Policy_Context_Basic256 * pc = cc->policyContext;
118565 return UA_Openssl_RSA_PKCS1_V15_SHA1_Sign (message, privateKey: pc->localPrivateKey,
118566 outSignature: signature);
118567}
118568
118569static size_t
118570UA_AsymEn_Basic256_getRemotePlainTextBlockSize (const void *channelContext) {
118571 if (channelContext == NULL) {
118572 return UA_STATUSCODE_BADINVALIDARGUMENT;
118573 }
118574
118575 const Channel_Context_Basic256 * cc = (const Channel_Context_Basic256 *) channelContext;
118576 UA_Int32 keyLen = 0;
118577 UA_Openssl_RSA_Public_GetKeyLength (publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
118578 return (size_t) keyLen - UA_SECURITYPOLICY_BASIC256SHA1_RSAPADDING_LEN;
118579}
118580
118581static size_t
118582UA_AsymEn_Basic256_getRemoteBlockSize (const void *channelContext) {
118583 if (channelContext == NULL) {
118584 return UA_STATUSCODE_BADINVALIDARGUMENT;
118585 }
118586
118587 const Channel_Context_Basic256 * cc = (const Channel_Context_Basic256 *) channelContext;
118588 UA_Int32 keyLen = 0;
118589 UA_Openssl_RSA_Public_GetKeyLength (publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
118590 return (size_t) keyLen;
118591}
118592
118593static size_t
118594UA_AsymEn_Basic256_getRemoteKeyLength (const void *channelContext) {
118595 if (channelContext == NULL)
118596 return UA_STATUSCODE_BADINVALIDARGUMENT;
118597
118598 const Channel_Context_Basic256 * cc = (const Channel_Context_Basic256 *) channelContext;
118599 UA_Int32 keyLen = 0;
118600 UA_Openssl_RSA_Public_GetKeyLength (publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
118601 return (size_t) keyLen * 8;
118602}
118603
118604static size_t
118605UA_AsymEn_Basic256_getLocalKeyLength (const void *channelContext) {
118606 if (channelContext == NULL)
118607 return UA_STATUSCODE_BADINVALIDARGUMENT;
118608
118609 const Channel_Context_Basic256 *cc = (const Channel_Context_Basic256 *) channelContext;
118610 Policy_Context_Basic256 *pc = cc->policyContext;
118611 UA_Int32 keyLen = 0;
118612 UA_Openssl_RSA_Private_GetKeyLength (privateKey: pc->localPrivateKey, keyLen: &keyLen);
118613
118614 return (size_t) keyLen * 8;
118615}
118616
118617static UA_StatusCode
118618UA_AsymEn_Basic256_Decrypt (void * channelContext,
118619 UA_ByteString * data) {
118620 if (channelContext == NULL || data == NULL) {
118621 return UA_STATUSCODE_BADINVALIDARGUMENT;
118622 }
118623
118624 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118625 UA_StatusCode ret = UA_Openssl_RSA_Oaep_Decrypt (data,
118626 privateKey: cc->policyContext->localPrivateKey);
118627 return ret;
118628}
118629
118630static UA_StatusCode
118631UA_AsymEn_Basic256_Encrypt (void * channelContext,
118632 UA_ByteString * data) {
118633 if (channelContext == NULL || data == NULL) {
118634 return UA_STATUSCODE_BADINVALIDARGUMENT;
118635 }
118636
118637 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118638 return UA_Openssl_RSA_OAEP_Encrypt (data, UA_SECURITYPOLICY_BASIC256SHA1_RSAPADDING_LEN,
118639 publicX509: cc->remoteCertificateX509);
118640}
118641
118642static UA_StatusCode
118643UA_Sym_Basic256_generateNonce(void *policyContext,
118644 UA_ByteString *out) {
118645 UA_Int32 rc = RAND_bytes(buf: out->data, num: (int) out->length);
118646 if (rc != 1) {
118647 return UA_STATUSCODE_BADUNEXPECTEDERROR;
118648 }
118649 return UA_STATUSCODE_GOOD;
118650}
118651
118652static UA_StatusCode
118653UA_Sym_Basic256_generateKey(void *policyContext, const UA_ByteString *secret,
118654 const UA_ByteString *seed, UA_ByteString *out) {
118655 return UA_Openssl_Random_Key_PSHA1_Derive(secret, seed, out);
118656}
118657
118658static size_t
118659UA_SymEn_Basic256_getLocalKeyLength (const void * channelContext) {
118660 /* 32 bytes 256 bits */
118661 return UA_SECURITYPOLICY_BASIC256_SYM_ENCRYPTION_KEY_LENGTH;
118662}
118663
118664static size_t
118665UA_SymEn_Basic256_getBlockSize (const void * channelContext) {
118666 return UA_SECURITYPOLICY_BASIC256_SYM_ENCRYPTION_BLOCK_SIZE;
118667}
118668
118669static size_t
118670UA_SymEn_Basic256_getRemoteKeyLength (const void * channelContext) {
118671 /* 32 bytes 256 bits */
118672 return UA_SECURITYPOLICY_BASIC256_SYM_ENCRYPTION_KEY_LENGTH;
118673}
118674
118675static UA_StatusCode
118676UA_SymEn_Basic256_Encrypt (void * channelContext,
118677 UA_ByteString * data) {
118678 if(channelContext == NULL || data == NULL)
118679 return UA_STATUSCODE_BADINVALIDARGUMENT;
118680
118681 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118682 return UA_OpenSSL_AES_256_CBC_Encrypt (iv: &cc->localSymIv, key: &cc->localSymEncryptingKey, data);
118683}
118684
118685static UA_StatusCode
118686UA_SymEn_Basic256_Decrypt (void * channelContext,
118687 UA_ByteString * data) {
118688 if(channelContext == NULL || data == NULL)
118689 return UA_STATUSCODE_BADINVALIDARGUMENT;
118690 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118691 return UA_OpenSSL_AES_256_CBC_Decrypt (iv: &cc->remoteSymIv, key: &cc->remoteSymEncryptingKey, data);
118692}
118693
118694static size_t
118695UA_SymSig_Basic256_getKeyLength (const void * channelContext) {
118696 return UA_SECURITYPOLICY_BASIC256_SYM_SIGNING_KEY_LENGTH;
118697}
118698
118699static size_t
118700UA_SymSig_Basic256_getSignatureSize (const void * channelContext) {
118701 return UA_SHA1_LENGTH;
118702}
118703
118704static UA_StatusCode
118705UA_SymSig_Basic256_Verify (void * channelContext,
118706 const UA_ByteString * message,
118707 const UA_ByteString * signature) {
118708 if (channelContext == NULL ||
118709 message == NULL || signature == NULL)
118710 return UA_STATUSCODE_BADINVALIDARGUMENT;
118711
118712 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118713 return UA_OpenSSL_HMAC_SHA1_Verify (message,
118714 key: &cc->remoteSymSigningKey,
118715 signature);
118716}
118717
118718static UA_StatusCode
118719UA_SymSig_Basic256_Sign (void * channelContext,
118720 const UA_ByteString * message,
118721 UA_ByteString * signature) {
118722 if (channelContext == NULL || message == NULL || signature == NULL)
118723 return UA_STATUSCODE_BADINVALIDARGUMENT;
118724
118725 Channel_Context_Basic256 * cc = (Channel_Context_Basic256 *) channelContext;
118726 return UA_OpenSSL_HMAC_SHA1_Sign (message, key: &cc->localSymSigningKey, signature);
118727}
118728
118729/* the main entry of Basic256 */
118730
118731UA_StatusCode
118732UA_SecurityPolicy_Basic256 (UA_SecurityPolicy * policy,
118733 const UA_ByteString localCertificate,
118734 const UA_ByteString localPrivateKey,
118735 const UA_Logger * logger) {
118736
118737 UA_LOG_WARNING(logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
118738 msg: "!! WARNING !! The Basic256 SecurityPolicy is unsecure. "
118739 "There are known attacks that break the encryption.");
118740
118741 UA_SecurityPolicyAsymmetricModule * const asymmetricModule = &policy->asymmetricModule;
118742 UA_SecurityPolicySymmetricModule * const symmetricModule = &policy->symmetricModule;
118743 UA_SecurityPolicyChannelModule * const channelModule = &policy->channelModule;
118744 UA_StatusCode retval;
118745
118746 UA_LOG_INFO (logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
118747 msg: "The basic256 security policy with openssl is added.");
118748
118749 UA_Openssl_Init ();
118750 memset(s: policy, c: 0, n: sizeof(UA_SecurityPolicy));
118751 policy->logger = logger;
118752 policy->policyUri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Basic256\0");
118753
118754 /* set ChannelModule context */
118755
118756 channelModule->newContext = UA_ChannelModule_Basic256_New_Context;
118757 channelModule->deleteContext = UA_ChannelModule_Basic256_Delete_Context;
118758
118759 channelModule->setLocalSymSigningKey = UA_ChannelModule_Basic256_setLocalSymSigningKey;
118760 channelModule->setLocalSymEncryptingKey = UA_ChannelModule_Basic256_setLocalSymEncryptingKey;
118761 channelModule->setLocalSymIv = UA_ChannelModule_Basic256_setLocalSymIv;
118762 channelModule->setRemoteSymSigningKey = UA_ChannelModule_Basic256_setRemoteSymSigningKey;
118763 channelModule->setRemoteSymEncryptingKey = UA_ChannelModule_Basic256_setRemoteSymEncryptingKey;
118764 channelModule->setRemoteSymIv = UA_ChannelModule_Basic256_setRemoteSymIv;
118765 channelModule->compareCertificate = UA_ChannelModule_Basic256_compareCertificate;
118766
118767 retval = UA_OpenSSL_LoadLocalCertificate(certificate: &localCertificate, target: &policy->localCertificate);
118768
118769 if (retval != UA_STATUSCODE_GOOD)
118770 return retval;
118771
118772 /* asymmetricModule */
118773
118774 asymmetricModule->compareCertificateThumbprint = UA_Asy_Basic256_compareCertificateThumbprint;
118775 asymmetricModule->makeCertificateThumbprint = UA_Asy_Basic256_makeCertificateThumbprint;
118776
118777 /* AsymmetricModule - signature algorithm */
118778
118779 UA_SecurityPolicySignatureAlgorithm * asySigAlgorithm =
118780 &asymmetricModule->cryptoModule.signatureAlgorithm;
118781 asySigAlgorithm->uri = UA_STRING(chars: "http://www.w3.org/2000/09/xmldsig#rsa-sha1\0");
118782 asySigAlgorithm->getRemoteSignatureSize = UA_AsySig_Basic256_getRemoteSignatureSize;
118783 asySigAlgorithm->getLocalSignatureSize = UA_AsySig_Basic256_getLocalSignatureSize;
118784 asySigAlgorithm->verify = UA_AsySig_Basic256_Verify;
118785 asySigAlgorithm->sign = UA_AsySig_Basic256_Sign;
118786 asySigAlgorithm->getLocalKeyLength = NULL;
118787 asySigAlgorithm->getRemoteKeyLength = NULL;
118788
118789 /* AsymmetricModule encryption algorithm */
118790
118791 UA_SecurityPolicyEncryptionAlgorithm * asymEncryAlg =
118792 &asymmetricModule->cryptoModule.encryptionAlgorithm;
118793 asymEncryAlg->uri = UA_STRING(chars: "http://www.w3.org/2001/04/xmlenc#rsa-oaep\0");
118794 asymEncryAlg->getRemotePlainTextBlockSize = UA_AsymEn_Basic256_getRemotePlainTextBlockSize;
118795 asymEncryAlg->getRemoteBlockSize = UA_AsymEn_Basic256_getRemoteBlockSize;
118796 asymEncryAlg->getRemoteKeyLength = UA_AsymEn_Basic256_getRemoteKeyLength;
118797 asymEncryAlg->getLocalKeyLength = UA_AsymEn_Basic256_getLocalKeyLength;
118798 asymEncryAlg->decrypt = UA_AsymEn_Basic256_Decrypt;
118799 asymEncryAlg->encrypt = UA_AsymEn_Basic256_Encrypt;
118800
118801 /* SymmetricModule */
118802
118803 symmetricModule->secureChannelNonceLength = 32;
118804 symmetricModule->generateNonce = UA_Sym_Basic256_generateNonce;
118805 symmetricModule->generateKey = UA_Sym_Basic256_generateKey;
118806
118807 /* Symmetric encryption Algorithm */
118808
118809 UA_SecurityPolicyEncryptionAlgorithm * symEncryptionAlgorithm =
118810 &symmetricModule->cryptoModule.encryptionAlgorithm;
118811 symEncryptionAlgorithm->uri = UA_STRING(chars: "http://www.w3.org/2001/04/xmlenc#aes256-cbc\0");
118812 symEncryptionAlgorithm->getLocalKeyLength = UA_SymEn_Basic256_getLocalKeyLength;
118813 symEncryptionAlgorithm->getRemoteKeyLength = UA_SymEn_Basic256_getRemoteKeyLength;
118814 symEncryptionAlgorithm->getRemoteBlockSize = UA_SymEn_Basic256_getBlockSize;
118815 symEncryptionAlgorithm->getRemotePlainTextBlockSize = UA_SymEn_Basic256_getBlockSize;
118816 symEncryptionAlgorithm->decrypt = UA_SymEn_Basic256_Decrypt;
118817 symEncryptionAlgorithm->encrypt = UA_SymEn_Basic256_Encrypt;
118818
118819 /* Symmetric signature Algorithm */
118820
118821 UA_SecurityPolicySignatureAlgorithm * symSignatureAlgorithm =
118822 &symmetricModule->cryptoModule.signatureAlgorithm;
118823 symSignatureAlgorithm->uri = UA_STRING(chars: "http://www.w3.org/2000/09/xmldsig#hmac-sha1\0");
118824 symSignatureAlgorithm->getLocalKeyLength = UA_SymSig_Basic256_getKeyLength;
118825 symSignatureAlgorithm->getRemoteKeyLength = UA_SymSig_Basic256_getKeyLength;
118826 symSignatureAlgorithm->getRemoteSignatureSize = UA_SymSig_Basic256_getSignatureSize;
118827 symSignatureAlgorithm->getLocalSignatureSize = UA_SymSig_Basic256_getSignatureSize;
118828 symSignatureAlgorithm->verify = UA_SymSig_Basic256_Verify;
118829 symSignatureAlgorithm->sign = UA_SymSig_Basic256_Sign;
118830
118831 /* set the policy context */
118832
118833 retval = UA_Policy_Basic256_New_Context (securityPolicy: policy, localPrivateKey, logger);
118834 if (retval != UA_STATUSCODE_GOOD) {
118835 UA_ByteString_clear (p: &policy->localCertificate);
118836 return retval;
118837 }
118838 policy->updateCertificateAndPrivateKey = updateCertificateAndPrivateKey_sp_basic256;
118839 policy->clear = UA_Policy_Basic256_Clear_Context;
118840
118841 /* Use the same signature algorithm as the asymmetric component for
118842 certificate signing (see standard) */
118843 policy->certificateSigningAlgorithm = policy->asymmetricModule.cryptoModule.signatureAlgorithm;
118844
118845 return UA_STATUSCODE_GOOD;
118846}
118847
118848#endif
118849
118850/**** amalgamated original file "/plugins/crypto/openssl/ua_openssl_basic256sha256.c" ****/
118851
118852/* This Source Code Form is subject to the terms of the Mozilla Public
118853 * License, v. 2.0. If a copy of the MPL was not distributed with this
118854 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
118855 *
118856 * Copyright 2020 (c) Wind River Systems, Inc.
118857 * Copyright 2020 (c) basysKom GmbH
118858 */
118859
118860
118861#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL)
118862
118863
118864#include <openssl/hmac.h>
118865#include <openssl/sha.h>
118866#include <openssl/rsa.h>
118867#include <openssl/x509.h>
118868#include <openssl/rand.h>
118869#include <openssl/rsa.h>
118870
118871#define UA_SHA256_LENGTH 32 /* 256 bit */
118872#define UA_SECURITYPOLICY_BASIC256SHA256_RSAPADDING_LEN 42
118873#define UA_SECURITYPOLICY_BASIC256SHA256_SYM_SIGNING_KEY_LENGTH 32
118874#define UA_SECURITYPOLICY_BASIC256SHA256_SYM_ENCRYPTION_KEY_LENGTH 32
118875#define UA_SECURITYPOLICY_BASIC256SHA256_SYM_ENCRYPTION_BLOCK_SIZE 16
118876#define UA_SECURITYPOLICY_BASIC256SHA256_SYM_PLAIN_TEXT_BLOCK_SIZE 16
118877#define UA_SECURITYPOLICY_BASIC256SHA256_MINASYMKEYLENGTH 256
118878#define UA_SECURITYPOLICY_BASIC256SHA256_MAXASYMKEYLENGTH 512
118879
118880typedef struct {
118881 EVP_PKEY *localPrivateKey;
118882 UA_ByteString localCertThumbprint;
118883 const UA_Logger *logger;
118884} Policy_Context_Basic256Sha256;
118885
118886typedef struct {
118887 UA_ByteString localSymSigningKey;
118888 UA_ByteString localSymEncryptingKey;
118889 UA_ByteString localSymIv;
118890 UA_ByteString remoteSymSigningKey;
118891 UA_ByteString remoteSymEncryptingKey;
118892 UA_ByteString remoteSymIv;
118893
118894 Policy_Context_Basic256Sha256 *policyContext;
118895 UA_ByteString remoteCertificate;
118896 X509 *remoteCertificateX509; /* X509 */
118897} Channel_Context_Basic256Sha256;
118898
118899/* create the policy context */
118900
118901static UA_StatusCode
118902UA_Policy_New_Context(UA_SecurityPolicy * securityPolicy,
118903 const UA_ByteString localPrivateKey,
118904 const UA_Logger *logger) {
118905 Policy_Context_Basic256Sha256 *context = (Policy_Context_Basic256Sha256 *)
118906 UA_malloc(size: sizeof(Policy_Context_Basic256Sha256));
118907 if(context == NULL)
118908 return UA_STATUSCODE_BADOUTOFMEMORY;
118909 context->localPrivateKey = UA_OpenSSL_LoadPrivateKey(privateKey: &localPrivateKey);
118910
118911 if(!context->localPrivateKey) {
118912 UA_free(ptr: context);
118913 return UA_STATUSCODE_BADINVALIDARGUMENT;
118914 }
118915
118916 UA_StatusCode retval =
118917 UA_Openssl_X509_GetCertificateThumbprint(certficate: &securityPolicy->localCertificate,
118918 pThumbprint: &context->localCertThumbprint, true);
118919 if(retval != UA_STATUSCODE_GOOD) {
118920 EVP_PKEY_free(pkey: context->localPrivateKey);
118921 UA_free(ptr: context);
118922 return retval;
118923 }
118924
118925 context->logger = logger;
118926 securityPolicy->policyContext = context;
118927 return UA_STATUSCODE_GOOD;
118928}
118929
118930/* Clear the policy context */
118931static void
118932UA_Policy_Clear_Context(UA_SecurityPolicy *policy) {
118933 if(policy == NULL)
118934 return;
118935
118936 UA_ByteString_clear(p: &policy->localCertificate);
118937
118938 /* Delete all allocated members in the context */
118939 Policy_Context_Basic256Sha256 *pc =
118940 (Policy_Context_Basic256Sha256 *) policy->policyContext;
118941 EVP_PKEY_free(pkey: pc->localPrivateKey);
118942 UA_ByteString_clear(p: &pc->localCertThumbprint);
118943 UA_free(ptr: pc);
118944 return;
118945}
118946
118947static UA_StatusCode
118948updateCertificateAndPrivateKey_sp_basic256sha256(UA_SecurityPolicy *securityPolicy,
118949 const UA_ByteString newCertificate,
118950 const UA_ByteString newPrivateKey) {
118951 if(securityPolicy == NULL)
118952 return UA_STATUSCODE_BADINTERNALERROR;
118953
118954 if(securityPolicy->policyContext == NULL)
118955 return UA_STATUSCODE_BADINTERNALERROR;
118956
118957 Policy_Context_Basic256Sha256 *pc =
118958 (Policy_Context_Basic256Sha256 *)securityPolicy->policyContext;
118959
118960 UA_ByteString_clear(p: &securityPolicy->localCertificate);
118961
118962 UA_StatusCode retval = UA_OpenSSL_LoadLocalCertificate(
118963 certificate: &newCertificate, target: &securityPolicy->localCertificate);
118964
118965 if(retval != UA_STATUSCODE_GOOD)
118966 return retval;
118967
118968 /* Set the new private key */
118969 EVP_PKEY_free(pkey: pc->localPrivateKey);
118970
118971 pc->localPrivateKey = UA_OpenSSL_LoadPrivateKey(privateKey: &newPrivateKey);
118972
118973 if(!pc->localPrivateKey) {
118974 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
118975 goto error;
118976 }
118977
118978 UA_ByteString_clear(p: &pc->localCertThumbprint);
118979
118980 retval = UA_Openssl_X509_GetCertificateThumbprint(certficate: &securityPolicy->localCertificate,
118981 pThumbprint: &pc->localCertThumbprint, true);
118982 if(retval != UA_STATUSCODE_GOOD) {
118983 goto error;
118984 }
118985
118986 return retval;
118987
118988error:
118989 UA_LOG_ERROR(logger: securityPolicy->logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
118990 msg: "Could not update certificate and private key");
118991 if(securityPolicy->policyContext != NULL)
118992 UA_Policy_Clear_Context(policy: securityPolicy);
118993 return retval;
118994}
118995
118996/* create the channel context */
118997
118998static UA_StatusCode
118999UA_ChannelModule_New_Context(const UA_SecurityPolicy * securityPolicy,
119000 const UA_ByteString * remoteCertificate,
119001 void ** channelContext) {
119002 if(securityPolicy == NULL || remoteCertificate == NULL || channelContext == NULL)
119003 return UA_STATUSCODE_BADINTERNALERROR;
119004
119005 Channel_Context_Basic256Sha256 *context = (Channel_Context_Basic256Sha256 *)
119006 UA_malloc(size: sizeof(Channel_Context_Basic256Sha256));
119007 if(context == NULL)
119008 return UA_STATUSCODE_BADOUTOFMEMORY;
119009
119010 UA_ByteString_init(p: &context->localSymSigningKey);
119011 UA_ByteString_init(p: &context->localSymEncryptingKey);
119012 UA_ByteString_init(p: &context->localSymIv);
119013 UA_ByteString_init(p: &context->remoteSymSigningKey);
119014 UA_ByteString_init(p: &context->remoteSymEncryptingKey);
119015 UA_ByteString_init(p: &context->remoteSymIv);
119016
119017 UA_StatusCode retval =
119018 UA_copyCertificate(dst: &context->remoteCertificate, src: remoteCertificate);
119019 if(retval != UA_STATUSCODE_GOOD) {
119020 UA_free(ptr: context);
119021 return retval;
119022 }
119023
119024 /* decode to X509 */
119025 context->remoteCertificateX509 = UA_OpenSSL_LoadCertificate(certificate: &context->remoteCertificate);
119026 if(context->remoteCertificateX509 == NULL) {
119027 UA_ByteString_clear(p: &context->remoteCertificate);
119028 UA_free(ptr: context);
119029 return UA_STATUSCODE_BADINTERNALERROR;
119030 }
119031
119032 context->policyContext =
119033 (Policy_Context_Basic256Sha256 *)securityPolicy->policyContext;
119034 *channelContext = context;
119035
119036 UA_LOG_INFO(logger: securityPolicy->logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
119037 msg: "The basic256sha256 security policy channel with openssl is created.");
119038
119039 return UA_STATUSCODE_GOOD;
119040}
119041
119042/* delete the channel context */
119043
119044static void
119045UA_ChannelModule_Delete_Context(void * channelContext) {
119046 if(!channelContext)
119047 return;
119048
119049 Channel_Context_Basic256Sha256 * cc = (Channel_Context_Basic256Sha256 *)channelContext;
119050 X509_free(a: cc->remoteCertificateX509);
119051 UA_ByteString_clear(p: &cc->remoteCertificate);
119052 UA_ByteString_clear(p: &cc->localSymSigningKey);
119053 UA_ByteString_clear(p: &cc->localSymEncryptingKey);
119054 UA_ByteString_clear(p: &cc->localSymIv);
119055 UA_ByteString_clear(p: &cc->remoteSymSigningKey);
119056 UA_ByteString_clear(p: &cc->remoteSymEncryptingKey);
119057 UA_ByteString_clear(p: &cc->remoteSymIv);
119058
119059 UA_LOG_INFO(logger: cc->policyContext->logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
119060 msg: "The basic256sha256 security policy channel with openssl is deleted.");
119061 UA_free(ptr: cc);
119062}
119063
119064/* Verifies the signature of the message using the provided keys in the context.
119065 * AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256 */
119066static UA_StatusCode
119067UA_AsySig_Basic256Sha256_Verify(void *channelContext,
119068 const UA_ByteString *message,
119069 const UA_ByteString *signature) {
119070 if(message == NULL || signature == NULL || channelContext == NULL)
119071 return UA_STATUSCODE_BADINTERNALERROR;
119072
119073 Channel_Context_Basic256Sha256 * cc =
119074 (Channel_Context_Basic256Sha256 *) channelContext;
119075 return UA_OpenSSL_RSA_PKCS1_V15_SHA256_Verify(msg: message, publicKeyX509: cc->remoteCertificateX509,
119076 signature);
119077}
119078
119079/* Compares the supplied certificate with the certificate
119080 * in the endpoint context
119081 */
119082
119083static UA_StatusCode
119084UA_compareCertificateThumbprint(const UA_SecurityPolicy * securityPolicy,
119085 const UA_ByteString * certificateThumbprint) {
119086 if(securityPolicy == NULL || certificateThumbprint == NULL)
119087 return UA_STATUSCODE_BADINVALIDARGUMENT;
119088 Policy_Context_Basic256Sha256 *pc = (Policy_Context_Basic256Sha256 *)
119089 securityPolicy->policyContext;
119090 if(!UA_ByteString_equal(p1: certificateThumbprint, p2: &pc->localCertThumbprint))
119091 return UA_STATUSCODE_BADCERTIFICATEINVALID;
119092 return UA_STATUSCODE_GOOD;
119093}
119094
119095/* Generates a thumbprint for the specified certificate */
119096
119097static UA_StatusCode
119098UA_makeCertificateThumbprint(const UA_SecurityPolicy * securityPolicy,
119099 const UA_ByteString * certificate,
119100 UA_ByteString * thumbprint) {
119101 return UA_Openssl_X509_GetCertificateThumbprint(certficate: certificate, pThumbprint: thumbprint, false);
119102}
119103
119104static UA_StatusCode
119105UA_Asym_Basic256Sha256_Decrypt(void * channelContext, UA_ByteString * data) {
119106 if(channelContext == NULL || data == NULL)
119107 return UA_STATUSCODE_BADINVALIDARGUMENT;
119108
119109 Channel_Context_Basic256Sha256 * cc =
119110 (Channel_Context_Basic256Sha256 *) channelContext;
119111 return UA_Openssl_RSA_Oaep_Decrypt(data, privateKey: cc->policyContext->localPrivateKey);
119112}
119113
119114static size_t
119115UA_Asym_Basic256Sha256_getRemoteSignatureSize(const void *channelContext) {
119116 if(channelContext == NULL)
119117 return UA_STATUSCODE_BADINTERNALERROR;
119118
119119 const Channel_Context_Basic256Sha256 * cc =
119120 (const Channel_Context_Basic256Sha256 *) channelContext;
119121 UA_Int32 keyLen = 0;
119122 UA_Openssl_RSA_Public_GetKeyLength(publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
119123 return (size_t) keyLen;
119124}
119125
119126static size_t
119127UA_AsySig_Basic256Sha256_getLocalSignatureSize(const void *channelContext) {
119128 if(channelContext == NULL)
119129 return UA_STATUSCODE_BADINTERNALERROR;
119130
119131 const Channel_Context_Basic256Sha256 *cc =
119132 (const Channel_Context_Basic256Sha256 *) channelContext;
119133 Policy_Context_Basic256Sha256 * pc = cc->policyContext;
119134 UA_Int32 keyLen = 0;
119135 UA_Openssl_RSA_Private_GetKeyLength(privateKey: pc->localPrivateKey, keyLen: &keyLen);
119136 return (size_t) keyLen;
119137}
119138
119139static size_t
119140UA_AsymEn_Basic256Sha256_getRemotePlainTextBlockSize(const void *channelContext) {
119141 if(channelContext == NULL)
119142 return UA_STATUSCODE_BADINTERNALERROR;
119143
119144 const Channel_Context_Basic256Sha256 *cc =
119145 (const Channel_Context_Basic256Sha256 *) channelContext;
119146 UA_Int32 keyLen = 0;
119147 UA_Openssl_RSA_Public_GetKeyLength(publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
119148 return (size_t) keyLen - UA_SECURITYPOLICY_BASIC256SHA256_RSAPADDING_LEN;
119149}
119150
119151static size_t
119152UA_AsymEn_Basic256Sha256_getRemoteBlockSize(const void *channelContext) {
119153 if(channelContext == NULL)
119154 return UA_STATUSCODE_BADINTERNALERROR;
119155
119156 const Channel_Context_Basic256Sha256 * cc =
119157 (const Channel_Context_Basic256Sha256 *) channelContext;
119158 UA_Int32 keyLen = 0;
119159 UA_Openssl_RSA_Public_GetKeyLength(publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
119160 return (size_t) keyLen;
119161}
119162
119163static size_t
119164UA_AsymEn_Basic256Sha256_getRemoteKeyLength(const void *channelContext) {
119165 if(channelContext == NULL)
119166 return UA_STATUSCODE_BADINTERNALERROR;
119167
119168 const Channel_Context_Basic256Sha256 *cc =
119169 (const Channel_Context_Basic256Sha256 *) channelContext;
119170 UA_Int32 keyLen = 0;
119171 UA_Openssl_RSA_Public_GetKeyLength(publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
119172 return (size_t) keyLen * 8;
119173}
119174
119175static UA_StatusCode
119176UA_Sym_Basic256Sha256_generateNonce(void *policyContext,
119177 UA_ByteString *out) {
119178 UA_Int32 rc = RAND_bytes(buf: out->data, num: (int) out->length);
119179 if(rc != 1)
119180 return UA_STATUSCODE_BADUNEXPECTEDERROR;
119181 return UA_STATUSCODE_GOOD;
119182}
119183
119184static size_t
119185UA_SymEn_Basic256Sha256_getLocalKeyLength(const void *channelContext) {
119186 /* 32 bytes 256 bits */
119187 return UA_SECURITYPOLICY_BASIC256SHA256_SYM_ENCRYPTION_KEY_LENGTH;
119188}
119189
119190static size_t
119191UA_SymSig_Basic256Sha256_getLocalKeyLength(const void *channelContext) {
119192 /* 32 bytes 256 bits */
119193 return UA_SECURITYPOLICY_BASIC256SHA256_SYM_SIGNING_KEY_LENGTH;
119194}
119195
119196static UA_StatusCode
119197UA_Sym_Basic256Sha256_generateKey(void *policyContext,
119198 const UA_ByteString *secret,
119199 const UA_ByteString *seed,
119200 UA_ByteString *out) {
119201 return UA_Openssl_Random_Key_PSHA256_Derive(secret, seed, out);
119202}
119203
119204static UA_StatusCode
119205UA_ChannelModule_Basic256Sha256_setLocalSymSigningKey(void * channelContext,
119206 const UA_ByteString * key) {
119207 if(key == NULL || channelContext == NULL)
119208 return UA_STATUSCODE_BADINTERNALERROR;
119209 Channel_Context_Basic256Sha256 * cc = (Channel_Context_Basic256Sha256 *) channelContext;
119210 UA_ByteString_clear(p: &cc->localSymSigningKey);
119211 return UA_ByteString_copy(src: key, dst: &cc->localSymSigningKey);
119212}
119213
119214static UA_StatusCode
119215UA_ChannelM_Basic256Sha256_setLocalSymEncryptingKey(void * channelContext,
119216 const UA_ByteString * key) {
119217 if(key == NULL || channelContext == NULL)
119218 return UA_STATUSCODE_BADINTERNALERROR;
119219 Channel_Context_Basic256Sha256 * cc = (Channel_Context_Basic256Sha256 *) channelContext;
119220 UA_ByteString_clear(p: &cc->localSymEncryptingKey);
119221 return UA_ByteString_copy(src: key, dst: &cc->localSymEncryptingKey);
119222}
119223
119224static UA_StatusCode
119225UA_ChannelM_Basic256Sha256_setLocalSymIv(void * channelContext,
119226 const UA_ByteString * iv) {
119227 if(iv == NULL || channelContext == NULL)
119228 return UA_STATUSCODE_BADINTERNALERROR;
119229 Channel_Context_Basic256Sha256 * cc = (Channel_Context_Basic256Sha256 *) channelContext;
119230 UA_ByteString_clear(p: &cc->localSymIv);
119231 return UA_ByteString_copy(src: iv, dst: &cc->localSymIv);
119232}
119233
119234static size_t
119235UA_SymEn_Basic256Sha256_getRemoteKeyLength(const void * channelContext) {
119236 /* 32 bytes 256 bits */
119237 return UA_SECURITYPOLICY_BASIC256SHA256_SYM_ENCRYPTION_KEY_LENGTH;
119238}
119239
119240static size_t
119241UA_SymEn_Basic256Sha256_getBlockSize(const void *channelContext) {
119242 return UA_SECURITYPOLICY_BASIC256SHA256_SYM_ENCRYPTION_BLOCK_SIZE;
119243}
119244
119245static size_t
119246UA_SymSig_Basic256Sha256_getRemoteKeyLength(const void * channelContext) {
119247 /* 32 bytes 256 bits */
119248 return UA_SECURITYPOLICY_BASIC256SHA256_SYM_SIGNING_KEY_LENGTH;
119249}
119250
119251static UA_StatusCode
119252UA_ChannelM_Basic256Sha256_setRemoteSymSigningKey(void *channelContext,
119253 const UA_ByteString * key) {
119254 if(key == NULL || channelContext == NULL)
119255 return UA_STATUSCODE_BADINTERNALERROR;
119256 Channel_Context_Basic256Sha256 * cc = (Channel_Context_Basic256Sha256 *) channelContext;
119257 UA_ByteString_clear(p: &cc->remoteSymSigningKey);
119258 return UA_ByteString_copy(src: key, dst: &cc->remoteSymSigningKey);
119259}
119260
119261static UA_StatusCode
119262UA_ChannelM_Basic256Sha256_setRemoteSymEncryptingKey(void *channelContext,
119263 const UA_ByteString * key) {
119264 if(key == NULL || channelContext == NULL)
119265 return UA_STATUSCODE_BADINTERNALERROR;
119266 Channel_Context_Basic256Sha256 * cc = (Channel_Context_Basic256Sha256 *) channelContext;
119267 UA_ByteString_clear(p: &cc->remoteSymEncryptingKey);
119268 return UA_ByteString_copy(src: key, dst: &cc->remoteSymEncryptingKey);
119269}
119270
119271static UA_StatusCode
119272UA_ChannelM_Basic256Sha256_setRemoteSymIv(void *channelContext,
119273 const UA_ByteString * key) {
119274 if(key == NULL || channelContext == NULL)
119275 return UA_STATUSCODE_BADINTERNALERROR;
119276 Channel_Context_Basic256Sha256 * cc = (Channel_Context_Basic256Sha256 *) channelContext;
119277 UA_ByteString_clear(p: &cc->remoteSymIv);
119278 return UA_ByteString_copy(src: key, dst: &cc->remoteSymIv);
119279}
119280
119281static UA_StatusCode
119282UA_AsySig_Basic256Sha256_sign(void *channelContext, const UA_ByteString * message,
119283 UA_ByteString *signature) {
119284 if(channelContext == NULL || message == NULL || signature == NULL)
119285 return UA_STATUSCODE_BADINTERNALERROR;
119286 Channel_Context_Basic256Sha256 *cc = (Channel_Context_Basic256Sha256 *) channelContext;
119287 Policy_Context_Basic256Sha256 *pc = cc->policyContext;
119288 return UA_Openssl_RSA_PKCS1_V15_SHA256_Sign(message, privateKey: pc->localPrivateKey, outSignature: signature);
119289}
119290
119291static UA_StatusCode
119292UA_AsymEn_Basic256Sha256_encrypt(void *channelContext, UA_ByteString *data) {
119293 if(channelContext == NULL || data == NULL)
119294 return UA_STATUSCODE_BADINTERNALERROR;
119295 Channel_Context_Basic256Sha256 * cc =
119296 (Channel_Context_Basic256Sha256 *) channelContext;
119297 return UA_Openssl_RSA_OAEP_Encrypt(data, UA_SECURITYPOLICY_BASIC256SHA256_RSAPADDING_LEN,
119298 publicX509: cc->remoteCertificateX509);
119299}
119300
119301static size_t
119302UA_SymSig_Basic256Sha256_getRemoteSignatureSize(const void *channelContext) {
119303 return UA_SHA256_LENGTH;
119304}
119305
119306static UA_StatusCode
119307UA_SymSig_Basic256Sha256_verify(void *channelContext, const UA_ByteString *message,
119308 const UA_ByteString *signature) {
119309 if(channelContext == NULL || message == NULL || signature == NULL)
119310 return UA_STATUSCODE_BADINTERNALERROR;
119311
119312 Channel_Context_Basic256Sha256 * cc = (Channel_Context_Basic256Sha256 *) channelContext;
119313 return UA_OpenSSL_HMAC_SHA256_Verify(message, key: &cc->remoteSymSigningKey, signature);
119314}
119315
119316static UA_StatusCode
119317UA_SymSig_Basic256Sha256_sign(void *channelContext, const UA_ByteString *message,
119318 UA_ByteString *signature) {
119319 if(channelContext == NULL || message == NULL || signature == NULL)
119320 return UA_STATUSCODE_BADINTERNALERROR;
119321
119322 Channel_Context_Basic256Sha256 * cc = (Channel_Context_Basic256Sha256 *) channelContext;
119323 return UA_OpenSSL_HMAC_SHA256_Sign(message, key: &cc->localSymSigningKey, signature);
119324}
119325
119326static size_t
119327UA_SymSig_Basic256Sha256_getLocalSignatureSize(const void * channelContext) {
119328 return UA_SHA256_LENGTH;
119329}
119330
119331static UA_StatusCode
119332UA_SymEn_Basic256Sha256_decrypt(void *channelContext, UA_ByteString *data) {
119333 if(channelContext == NULL || data == NULL)
119334 return UA_STATUSCODE_BADINTERNALERROR;
119335 Channel_Context_Basic256Sha256 * cc = (Channel_Context_Basic256Sha256 *) channelContext;
119336 return UA_OpenSSL_AES_256_CBC_Decrypt(iv: &cc->remoteSymIv,
119337 key: &cc->remoteSymEncryptingKey, data);
119338}
119339
119340static UA_StatusCode
119341UA_SymEn_Basic256Sha256_encrypt(void *channelContext, UA_ByteString *data) {
119342 if(channelContext == NULL || data == NULL)
119343 return UA_STATUSCODE_BADINTERNALERROR;
119344
119345 Channel_Context_Basic256Sha256 * cc = (Channel_Context_Basic256Sha256 *) channelContext;
119346 return UA_OpenSSL_AES_256_CBC_Encrypt(iv: &cc->localSymIv, key: &cc->localSymEncryptingKey, data);
119347}
119348
119349static UA_StatusCode
119350UA_ChannelM_Basic256Sha256_compareCertificate(const void *channelContext,
119351 const UA_ByteString *certificate) {
119352 if(channelContext == NULL || certificate == NULL)
119353 return UA_STATUSCODE_BADINTERNALERROR;
119354
119355 const Channel_Context_Basic256Sha256 * cc =
119356 (const Channel_Context_Basic256Sha256 *) channelContext;
119357 return UA_OpenSSL_X509_compare(cert: certificate, bcert: cc->remoteCertificateX509);
119358}
119359
119360static size_t
119361UA_AsymEn_Basic256Sha256_getLocalKeyLength(const void *channelContext) {
119362 if(channelContext == NULL)
119363 return UA_STATUSCODE_BADINTERNALERROR;
119364
119365 const Channel_Context_Basic256Sha256 * cc =
119366 (const Channel_Context_Basic256Sha256 *) channelContext;
119367 Policy_Context_Basic256Sha256 *pc = cc->policyContext;
119368 UA_Int32 keyLen = 0;
119369 UA_Openssl_RSA_Private_GetKeyLength(privateKey: pc->localPrivateKey, keyLen: &keyLen);
119370 return (size_t) keyLen * 8;
119371}
119372
119373/* the main entry of Basic256Sha256 */
119374
119375UA_StatusCode
119376UA_SecurityPolicy_Basic256Sha256(UA_SecurityPolicy *policy,
119377 const UA_ByteString localCertificate,
119378 const UA_ByteString localPrivateKey,
119379 const UA_Logger *logger) {
119380 UA_SecurityPolicyAsymmetricModule *asymmetricModule = &policy->asymmetricModule;
119381 UA_SecurityPolicySymmetricModule *symmetricModule = &policy->symmetricModule;
119382 UA_SecurityPolicyChannelModule *channelModule = &policy->channelModule;
119383 UA_LOG_INFO(logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
119384 msg: "The basic256sha256 security policy with openssl is added.");
119385
119386 UA_Openssl_Init();
119387 memset(s: policy, c: 0, n: sizeof(UA_SecurityPolicy));
119388 policy->logger = logger;
119389 policy->policyUri =
119390 UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256\0");
119391
119392 /* Set ChannelModule context */
119393 channelModule->newContext = UA_ChannelModule_New_Context;
119394 channelModule->deleteContext = UA_ChannelModule_Delete_Context;
119395 channelModule->setLocalSymSigningKey =
119396 UA_ChannelModule_Basic256Sha256_setLocalSymSigningKey;
119397 channelModule->setLocalSymEncryptingKey =
119398 UA_ChannelM_Basic256Sha256_setLocalSymEncryptingKey;
119399 channelModule->setLocalSymIv = UA_ChannelM_Basic256Sha256_setLocalSymIv;
119400 channelModule->setRemoteSymSigningKey =
119401 UA_ChannelM_Basic256Sha256_setRemoteSymSigningKey;
119402 channelModule->setRemoteSymEncryptingKey =
119403 UA_ChannelM_Basic256Sha256_setRemoteSymEncryptingKey;
119404 channelModule->setRemoteSymIv = UA_ChannelM_Basic256Sha256_setRemoteSymIv;
119405 channelModule->compareCertificate = UA_ChannelM_Basic256Sha256_compareCertificate;
119406 UA_StatusCode retval =
119407 UA_OpenSSL_LoadLocalCertificate(certificate: &localCertificate, target: &policy->localCertificate);
119408 if(retval != UA_STATUSCODE_GOOD)
119409 return retval;
119410
119411 /* AsymmetricModule - signature algorithm */
119412 UA_SecurityPolicySignatureAlgorithm *asySigAlgorithm =
119413 &asymmetricModule->cryptoModule.signatureAlgorithm;
119414 asySigAlgorithm->uri = UA_STRING(chars: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\0");
119415 asySigAlgorithm->verify = UA_AsySig_Basic256Sha256_Verify;
119416 asySigAlgorithm->sign = UA_AsySig_Basic256Sha256_sign;
119417 asySigAlgorithm->getLocalSignatureSize = UA_AsySig_Basic256Sha256_getLocalSignatureSize;
119418 asySigAlgorithm->getRemoteSignatureSize = UA_Asym_Basic256Sha256_getRemoteSignatureSize;
119419 asySigAlgorithm->getLocalKeyLength = NULL;
119420 asySigAlgorithm->getRemoteKeyLength = NULL;
119421
119422 /* AsymmetricModule encryption algorithm */
119423 UA_SecurityPolicyEncryptionAlgorithm *asymEncryAlg =
119424 &asymmetricModule->cryptoModule.encryptionAlgorithm;
119425 asymEncryAlg->uri = UA_STRING(chars: "http://www.w3.org/2001/04/xmlenc#rsa-oaep\0");
119426 asymEncryAlg->encrypt = UA_AsymEn_Basic256Sha256_encrypt;
119427 asymEncryAlg->decrypt = UA_Asym_Basic256Sha256_Decrypt;
119428 asymEncryAlg->getLocalKeyLength = UA_AsymEn_Basic256Sha256_getLocalKeyLength;
119429 asymEncryAlg->getRemoteKeyLength = UA_AsymEn_Basic256Sha256_getRemoteKeyLength;
119430 asymEncryAlg->getRemoteBlockSize = UA_AsymEn_Basic256Sha256_getRemoteBlockSize;
119431 asymEncryAlg->getRemotePlainTextBlockSize =
119432 UA_AsymEn_Basic256Sha256_getRemotePlainTextBlockSize;
119433
119434 /* AsymmetricModule */
119435 asymmetricModule->compareCertificateThumbprint = UA_compareCertificateThumbprint;
119436 asymmetricModule->makeCertificateThumbprint = UA_makeCertificateThumbprint;
119437
119438 /* SymmetricModule */
119439 symmetricModule->secureChannelNonceLength = 32;
119440 symmetricModule->generateNonce = UA_Sym_Basic256Sha256_generateNonce;
119441 symmetricModule->generateKey = UA_Sym_Basic256Sha256_generateKey;
119442
119443 /* Symmetric encryption Algorithm */
119444 UA_SecurityPolicyEncryptionAlgorithm *symEncryptionAlgorithm =
119445 &symmetricModule->cryptoModule.encryptionAlgorithm;
119446 symEncryptionAlgorithm->uri =
119447 UA_STRING(chars: "http://www.w3.org/2001/04/xmlenc#aes256-cbc\0");
119448 symEncryptionAlgorithm->encrypt = UA_SymEn_Basic256Sha256_encrypt;
119449 symEncryptionAlgorithm->decrypt = UA_SymEn_Basic256Sha256_decrypt;
119450 symEncryptionAlgorithm->getLocalKeyLength = UA_SymEn_Basic256Sha256_getLocalKeyLength;
119451 symEncryptionAlgorithm->getRemoteKeyLength = UA_SymEn_Basic256Sha256_getRemoteKeyLength;
119452 symEncryptionAlgorithm->getRemoteBlockSize = UA_SymEn_Basic256Sha256_getBlockSize;
119453 symEncryptionAlgorithm->getRemotePlainTextBlockSize = UA_SymEn_Basic256Sha256_getBlockSize;
119454
119455 /* Symmetric signature Algorithm */
119456 UA_SecurityPolicySignatureAlgorithm *symSignatureAlgorithm =
119457 &symmetricModule->cryptoModule.signatureAlgorithm;
119458 symSignatureAlgorithm->uri =
119459 UA_STRING(chars: "http://www.w3.org/2000/09/xmldsig#hmac-sha2-256\0");
119460 symSignatureAlgorithm->verify = UA_SymSig_Basic256Sha256_verify;
119461 symSignatureAlgorithm->sign = UA_SymSig_Basic256Sha256_sign;
119462 symSignatureAlgorithm->getLocalSignatureSize =
119463 UA_SymSig_Basic256Sha256_getLocalSignatureSize;
119464 symSignatureAlgorithm->getRemoteSignatureSize =
119465 UA_SymSig_Basic256Sha256_getRemoteSignatureSize;
119466 symSignatureAlgorithm->getLocalKeyLength =
119467 UA_SymSig_Basic256Sha256_getLocalKeyLength;
119468 symSignatureAlgorithm->getRemoteKeyLength =
119469 UA_SymSig_Basic256Sha256_getRemoteKeyLength;
119470
119471 policy->updateCertificateAndPrivateKey =
119472 updateCertificateAndPrivateKey_sp_basic256sha256;
119473 policy->clear = UA_Policy_Clear_Context;
119474 retval = UA_Policy_New_Context(securityPolicy: policy, localPrivateKey, logger);
119475 if(retval != UA_STATUSCODE_GOOD) {
119476 UA_ByteString_clear(p: &policy->localCertificate);
119477 return retval;
119478 }
119479
119480 /* Use the same signature algorithm as the asymmetric component for
119481 * certificate signing (see standard) */
119482 policy->certificateSigningAlgorithm =
119483 policy->asymmetricModule.cryptoModule.signatureAlgorithm;
119484
119485 return UA_STATUSCODE_GOOD;
119486}
119487
119488#endif
119489
119490/**** amalgamated original file "/plugins/crypto/openssl/ua_openssl_aes128sha256rsaoaep.c" ****/
119491
119492/* This Source Code Form is subject to the terms of the Mozilla Public
119493 * License, v. 2.0. If a copy of the MPL was not distributed with this
119494 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
119495 *
119496 * Copyright 2020 (c) Wind River Systems, Inc.
119497 */
119498
119499
119500#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL)
119501
119502
119503#include <openssl/hmac.h>
119504#include <openssl/sha.h>
119505#include <openssl/rsa.h>
119506#include <openssl/x509.h>
119507#include <openssl/rand.h>
119508#include <openssl/rsa.h>
119509
119510#define UA_SHA256_LENGTH 32 /* 256 bit */
119511#define UA_SECURITYPOLICY_AES128SHA256RSAOAEP_RSAPADDING_LEN 42
119512#define UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_SIGNING_KEY_LENGTH 32
119513#define UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_ENCRYPTION_KEY_LENGTH 16
119514#define UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_ENCRYPTION_BLOCK_SIZE 16
119515#define UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_PLAIN_TEXT_BLOCK_SIZE 16
119516#define UA_SECURITYPOLICY_AES128SHA256RSAOAEP_MINASYMKEYLENGTH 256
119517#define UA_SECURITYPOLICY_AES128SHA256RSAOAEP_MAXASYMKEYLENGTH 512
119518
119519typedef struct {
119520 EVP_PKEY *localPrivateKey;
119521 UA_ByteString localCertThumbprint;
119522 const UA_Logger *logger;
119523} Policy_Context_Aes128Sha256RsaOaep;
119524
119525typedef struct {
119526 UA_ByteString localSymSigningKey;
119527 UA_ByteString localSymEncryptingKey;
119528 UA_ByteString localSymIv;
119529 UA_ByteString remoteSymSigningKey;
119530 UA_ByteString remoteSymEncryptingKey;
119531 UA_ByteString remoteSymIv;
119532
119533 Policy_Context_Aes128Sha256RsaOaep *policyContext;
119534 UA_ByteString remoteCertificate;
119535 X509 *remoteCertificateX509; /* X509 */
119536} Channel_Context_Aes128Sha256RsaOaep;
119537
119538/* create the policy context */
119539
119540static UA_StatusCode
119541UA_Policy_Aes128Sha256RsaOaep_New_Context(UA_SecurityPolicy *securityPolicy,
119542 const UA_ByteString localPrivateKey,
119543 const UA_Logger *logger) {
119544 Policy_Context_Aes128Sha256RsaOaep *context =
119545 (Policy_Context_Aes128Sha256RsaOaep *)UA_malloc(
119546 size: sizeof(Policy_Context_Aes128Sha256RsaOaep));
119547 if(context == NULL) {
119548 return UA_STATUSCODE_BADOUTOFMEMORY;
119549 }
119550
119551 context->localPrivateKey = UA_OpenSSL_LoadPrivateKey(privateKey: &localPrivateKey);
119552 if (!context->localPrivateKey) {
119553 UA_free(ptr: context);
119554 return UA_STATUSCODE_BADINVALIDARGUMENT;
119555 }
119556
119557 UA_StatusCode retval = UA_Openssl_X509_GetCertificateThumbprint(
119558 certficate: &securityPolicy->localCertificate, pThumbprint: &context->localCertThumbprint, true);
119559 if(retval != UA_STATUSCODE_GOOD) {
119560 EVP_PKEY_free(pkey: context->localPrivateKey);
119561 UA_free(ptr: context);
119562 return retval;
119563 }
119564
119565 context->logger = logger;
119566 securityPolicy->policyContext = context;
119567
119568 return UA_STATUSCODE_GOOD;
119569}
119570
119571/* clear the policy context */
119572
119573static void
119574UA_Policy_Aes128Sha256RsaOaep_Clear_Context(UA_SecurityPolicy *policy) {
119575 if(policy == NULL)
119576 return;
119577
119578 UA_ByteString_clear(p: &policy->localCertificate);
119579
119580 /* delete all allocated members in the context */
119581
119582 Policy_Context_Aes128Sha256RsaOaep *pc =
119583 (Policy_Context_Aes128Sha256RsaOaep *)policy->policyContext;
119584 if (pc == NULL) {
119585 return;
119586 }
119587
119588 EVP_PKEY_free(pkey: pc->localPrivateKey);
119589 UA_ByteString_clear(p: &pc->localCertThumbprint);
119590 UA_free(ptr: pc);
119591
119592 return;
119593}
119594
119595static UA_StatusCode
119596updateCertificateAndPrivateKey_sp_aes128sha256rsaoaep(UA_SecurityPolicy *securityPolicy,
119597 const UA_ByteString newCertificate,
119598 const UA_ByteString newPrivateKey) {
119599 if(securityPolicy == NULL)
119600 return UA_STATUSCODE_BADINTERNALERROR;
119601
119602 if(securityPolicy->policyContext == NULL)
119603 return UA_STATUSCODE_BADINTERNALERROR;
119604
119605 Policy_Context_Aes128Sha256RsaOaep *pc =
119606 (Policy_Context_Aes128Sha256RsaOaep *)securityPolicy->policyContext;
119607
119608 UA_ByteString_clear(p: &securityPolicy->localCertificate);
119609
119610 UA_StatusCode retval = UA_OpenSSL_LoadLocalCertificate(
119611 certificate: &newCertificate, target: &securityPolicy->localCertificate);
119612
119613 if(retval != UA_STATUSCODE_GOOD)
119614 return retval;
119615
119616 /* Set the new private key */
119617 EVP_PKEY_free(pkey: pc->localPrivateKey);
119618
119619 pc->localPrivateKey = UA_OpenSSL_LoadPrivateKey(privateKey: &newPrivateKey);
119620
119621 if(!pc->localPrivateKey) {
119622 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
119623 goto error;
119624 }
119625
119626 UA_ByteString_clear(p: &pc->localCertThumbprint);
119627
119628 retval = UA_Openssl_X509_GetCertificateThumbprint(certficate: &securityPolicy->localCertificate,
119629 pThumbprint: &pc->localCertThumbprint, true);
119630 if(retval != UA_STATUSCODE_GOOD) {
119631 goto error;
119632 }
119633
119634 return retval;
119635
119636error:
119637 UA_LOG_ERROR(logger: securityPolicy->logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
119638 msg: "Could not update certificate and private key");
119639 if(securityPolicy->policyContext != NULL)
119640 UA_Policy_Aes128Sha256RsaOaep_Clear_Context(policy: securityPolicy);
119641 return retval;
119642}
119643
119644/* create the channel context */
119645
119646static UA_StatusCode
119647UA_ChannelModule_Aes128Sha256RsaOaep_New_Context(const UA_SecurityPolicy *securityPolicy,
119648 const UA_ByteString *remoteCertificate,
119649 void **channelContext) {
119650 if(securityPolicy == NULL || remoteCertificate == NULL || channelContext == NULL) {
119651 return UA_STATUSCODE_BADINTERNALERROR;
119652 }
119653 Channel_Context_Aes128Sha256RsaOaep *context =
119654 (Channel_Context_Aes128Sha256RsaOaep *)UA_malloc(
119655 size: sizeof(Channel_Context_Aes128Sha256RsaOaep));
119656 if(context == NULL) {
119657 return UA_STATUSCODE_BADOUTOFMEMORY;
119658 }
119659
119660 UA_ByteString_init(p: &context->localSymSigningKey);
119661 UA_ByteString_init(p: &context->localSymEncryptingKey);
119662 UA_ByteString_init(p: &context->localSymIv);
119663 UA_ByteString_init(p: &context->remoteSymSigningKey);
119664 UA_ByteString_init(p: &context->remoteSymEncryptingKey);
119665 UA_ByteString_init(p: &context->remoteSymIv);
119666
119667 UA_StatusCode retval =
119668 UA_copyCertificate(dst: &context->remoteCertificate, src: remoteCertificate);
119669 if(retval != UA_STATUSCODE_GOOD) {
119670 UA_free(ptr: context);
119671 return retval;
119672 }
119673
119674 /* decode to X509 */
119675 context->remoteCertificateX509 = UA_OpenSSL_LoadCertificate(certificate: &context->remoteCertificate);
119676 if (context->remoteCertificateX509 == NULL) {
119677 UA_ByteString_clear (p: &context->remoteCertificate);
119678 UA_free (ptr: context);
119679 return UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE;
119680 }
119681
119682 context->policyContext =
119683 (Policy_Context_Aes128Sha256RsaOaep *)(securityPolicy->policyContext);
119684
119685 *channelContext = context;
119686
119687 UA_LOG_INFO(
119688 logger: securityPolicy->logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
119689 msg: "The Aes128Sha256RsaOaep security policy channel with openssl is created.");
119690
119691 return UA_STATUSCODE_GOOD;
119692}
119693
119694/* delete the channel context */
119695
119696static void
119697UA_ChannelModule_Aes128Sha256RsaOaep_Delete_Context(void *channelContext) {
119698 if(channelContext != NULL) {
119699 Channel_Context_Aes128Sha256RsaOaep *cc =
119700 (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119701 X509_free(a: cc->remoteCertificateX509);
119702 UA_ByteString_clear(p: &cc->remoteCertificate);
119703 UA_ByteString_clear(p: &cc->localSymSigningKey);
119704 UA_ByteString_clear(p: &cc->localSymEncryptingKey);
119705 UA_ByteString_clear(p: &cc->localSymIv);
119706 UA_ByteString_clear(p: &cc->remoteSymSigningKey);
119707 UA_ByteString_clear(p: &cc->remoteSymEncryptingKey);
119708 UA_ByteString_clear(p: &cc->remoteSymIv);
119709
119710 UA_LOG_INFO(
119711 logger: cc->policyContext->logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
119712 msg: "The Aes128Sha256RsaOaep security policy channel with openssl is deleted.");
119713 UA_free(ptr: cc);
119714 }
119715}
119716
119717/* Verifies the signature of the message using the provided keys in the context.
119718 * AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256
119719 */
119720
119721static UA_StatusCode
119722UA_AsySig_Aes128Sha256RsaOaep_Verify(void *channelContext, const UA_ByteString *message,
119723 const UA_ByteString *signature) {
119724 if(message == NULL || signature == NULL || channelContext == NULL) {
119725 return UA_STATUSCODE_BADINTERNALERROR;
119726 }
119727
119728 Channel_Context_Aes128Sha256RsaOaep *cc =
119729 (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119730 UA_StatusCode retval = UA_OpenSSL_RSA_PKCS1_V15_SHA256_Verify(
119731 msg: message, publicKeyX509: cc->remoteCertificateX509, signature);
119732
119733 return retval;
119734}
119735
119736/* Compares the supplied certificate with the certificate
119737 * in the endpoint context
119738 */
119739
119740static UA_StatusCode
119741UA_compareCertificateThumbprint_Aes128Sha256RsaOaep(const UA_SecurityPolicy *securityPolicy,
119742 const UA_ByteString *certificateThumbprint) {
119743 if(securityPolicy == NULL || certificateThumbprint == NULL) {
119744 return UA_STATUSCODE_BADINVALIDARGUMENT;
119745 }
119746 Policy_Context_Aes128Sha256RsaOaep *pc =
119747 (Policy_Context_Aes128Sha256RsaOaep *)securityPolicy->policyContext;
119748 if(!UA_ByteString_equal(p1: certificateThumbprint, p2: &pc->localCertThumbprint))
119749 return UA_STATUSCODE_BADCERTIFICATEINVALID;
119750 return UA_STATUSCODE_GOOD;
119751}
119752
119753/* Generates a thumbprint for the specified certificate */
119754
119755static UA_StatusCode
119756UA_makeCertificateThumbprint_Aes128Sha256RsaOaep(const UA_SecurityPolicy *securityPolicy,
119757 const UA_ByteString *certificate,
119758 UA_ByteString *thumbprint) {
119759 return UA_Openssl_X509_GetCertificateThumbprint(certficate: certificate, pThumbprint: thumbprint, false);
119760}
119761
119762static UA_StatusCode
119763UA_Asym_Aes128Sha256RsaOaep_Decrypt(void *channelContext, UA_ByteString *data) {
119764 if(channelContext == NULL || data == NULL)
119765 return UA_STATUSCODE_BADINVALIDARGUMENT;
119766
119767 Channel_Context_Aes128Sha256RsaOaep *cc = (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119768 UA_StatusCode ret = UA_Openssl_RSA_Oaep_Decrypt(data, privateKey: cc->policyContext->localPrivateKey);
119769 return ret;
119770}
119771
119772static size_t
119773UA_Asym_Aes128Sha256RsaOaep_getRemoteSignatureSize(const void *channelContext) {
119774 if(channelContext == NULL)
119775 return UA_STATUSCODE_BADINTERNALERROR;
119776
119777 const Channel_Context_Aes128Sha256RsaOaep *cc = (const Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119778 UA_Int32 keyLen = 0;
119779 UA_Openssl_RSA_Public_GetKeyLength(publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
119780 return (size_t)keyLen;
119781}
119782
119783static size_t
119784UA_AsySig_Aes128Sha256RsaOaep_getLocalSignatureSize(const void *channelContext) {
119785 if(channelContext == NULL)
119786 return UA_STATUSCODE_BADINTERNALERROR;
119787
119788 const Channel_Context_Aes128Sha256RsaOaep *cc = (const Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119789 Policy_Context_Aes128Sha256RsaOaep *pc = cc->policyContext;
119790 UA_Int32 keyLen = 0;
119791 UA_Openssl_RSA_Private_GetKeyLength(privateKey: pc->localPrivateKey, keyLen: &keyLen);
119792 return (size_t)keyLen;
119793}
119794
119795static size_t
119796UA_AsymEn_Aes128Sha256RsaOaep_getRemotePlainTextBlockSize(const void *channelContext) {
119797 if(channelContext == NULL)
119798 return UA_STATUSCODE_BADINTERNALERROR;
119799
119800 const Channel_Context_Aes128Sha256RsaOaep *cc =
119801 (const Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119802 UA_Int32 keyLen = 0;
119803 UA_Openssl_RSA_Public_GetKeyLength(publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
119804 return (size_t)keyLen - UA_SECURITYPOLICY_AES128SHA256RSAOAEP_RSAPADDING_LEN;
119805}
119806
119807static size_t
119808UA_AsymEn_Aes128Sha256RsaOaep_getRemoteBlockSize(const void *channelContext) {
119809 if(channelContext == NULL)
119810 return UA_STATUSCODE_BADINTERNALERROR;
119811
119812 const Channel_Context_Aes128Sha256RsaOaep *cc =
119813 (const Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119814 UA_Int32 keyLen = 0;
119815 UA_Openssl_RSA_Public_GetKeyLength(publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
119816 return (size_t)keyLen;
119817}
119818
119819static size_t
119820UA_AsymEn_Aes128Sha256RsaOaep_getRemoteKeyLength(const void *channelContext) {
119821 if(channelContext == NULL)
119822 return UA_STATUSCODE_BADINTERNALERROR;
119823
119824 const Channel_Context_Aes128Sha256RsaOaep *cc =
119825 (const Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119826 UA_Int32 keyLen = 0;
119827 UA_Openssl_RSA_Public_GetKeyLength(publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
119828 return (size_t)keyLen * 8;
119829}
119830
119831static UA_StatusCode
119832UA_Sym_Aes128Sha256RsaOaep_generateNonce(void *policyContext,
119833 UA_ByteString *out) {
119834 UA_Int32 rc = RAND_bytes(buf: out->data, num: (int)out->length);
119835 if(rc != 1) {
119836 return UA_STATUSCODE_BADUNEXPECTEDERROR;
119837 }
119838 return UA_STATUSCODE_GOOD;
119839}
119840
119841static size_t
119842UA_SymEn_Aes128Sha256RsaOaep_getLocalKeyLength(const void *channelContext) {
119843 /* 32 bytes 256 bits */
119844 return UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_ENCRYPTION_KEY_LENGTH;
119845}
119846
119847static size_t
119848UA_SymSig_Aes128Sha256RsaOaep_getLocalKeyLength(const void *channelContext) {
119849 /* 32 bytes 256 bits */
119850 return UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_SIGNING_KEY_LENGTH;
119851}
119852
119853static UA_StatusCode
119854UA_Sym_Aes128Sha256RsaOaep_generateKey(void *policyContext,
119855 const UA_ByteString *secret,
119856 const UA_ByteString *seed, UA_ByteString *out) {
119857 return UA_Openssl_Random_Key_PSHA256_Derive(secret, seed, out);
119858}
119859
119860static UA_StatusCode
119861UA_ChannelModule_Aes128Sha256RsaOaep_setLocalSymSigningKey(void *channelContext,
119862 const UA_ByteString *key) {
119863 if(key == NULL || channelContext == NULL)
119864 return UA_STATUSCODE_BADINTERNALERROR;
119865 Channel_Context_Aes128Sha256RsaOaep *cc =
119866 (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119867 UA_ByteString_clear(p: &cc->localSymSigningKey);
119868 return UA_ByteString_copy(src: key, dst: &cc->localSymSigningKey);
119869}
119870
119871static UA_StatusCode
119872UA_ChannelM_Aes128Sha256RsaOaep_setLocalSymEncryptingKey(void *channelContext,
119873 const UA_ByteString *key) {
119874 if(key == NULL || channelContext == NULL)
119875 return UA_STATUSCODE_BADINTERNALERROR;
119876 Channel_Context_Aes128Sha256RsaOaep *cc =
119877 (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119878 UA_ByteString_clear(p: &cc->localSymEncryptingKey);
119879 return UA_ByteString_copy(src: key, dst: &cc->localSymEncryptingKey);
119880}
119881
119882static UA_StatusCode
119883UA_ChannelM_Aes128Sha256RsaOaep_setLocalSymIv(void *channelContext,
119884 const UA_ByteString *iv) {
119885 if(iv == NULL || channelContext == NULL)
119886 return UA_STATUSCODE_BADINTERNALERROR;
119887 Channel_Context_Aes128Sha256RsaOaep *cc =
119888 (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119889 UA_ByteString_clear(p: &cc->localSymIv);
119890 return UA_ByteString_copy(src: iv, dst: &cc->localSymIv);
119891}
119892
119893static size_t
119894UA_SymEn_Aes128Sha256RsaOaep_getRemoteKeyLength(const void *channelContext) {
119895 /* 32 bytes 256 bits */
119896 return UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_ENCRYPTION_KEY_LENGTH;
119897}
119898
119899static size_t
119900UA_SymEn_Aes128Sha256RsaOaep_getBlockSize(const void *channelContext) {
119901 return UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_ENCRYPTION_BLOCK_SIZE;
119902}
119903
119904static size_t
119905UA_SymSig_Aes128Sha256RsaOaep_getRemoteKeyLength(const void *channelContext) {
119906 /* 32 bytes 256 bits */
119907 return UA_SECURITYPOLICY_AES128SHA256RSAOAEP_SYM_SIGNING_KEY_LENGTH;
119908}
119909
119910static UA_StatusCode
119911UA_ChannelM_Aes128Sha256RsaOaep_setRemoteSymSigningKey(void *channelContext,
119912 const UA_ByteString *key) {
119913 if(key == NULL || channelContext == NULL)
119914 return UA_STATUSCODE_BADINTERNALERROR;
119915 Channel_Context_Aes128Sha256RsaOaep *cc =
119916 (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119917 UA_ByteString_clear(p: &cc->remoteSymSigningKey);
119918 return UA_ByteString_copy(src: key, dst: &cc->remoteSymSigningKey);
119919}
119920
119921static UA_StatusCode
119922UA_ChannelM_Aes128Sha256RsaOaep_setRemoteSymEncryptingKey(void *channelContext,
119923 const UA_ByteString *key) {
119924 if(key == NULL || channelContext == NULL)
119925 return UA_STATUSCODE_BADINTERNALERROR;
119926 Channel_Context_Aes128Sha256RsaOaep *cc =
119927 (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119928 UA_ByteString_clear(p: &cc->remoteSymEncryptingKey);
119929 return UA_ByteString_copy(src: key, dst: &cc->remoteSymEncryptingKey);
119930}
119931
119932static UA_StatusCode
119933UA_ChannelM_Aes128Sha256RsaOaep_setRemoteSymIv(void *channelContext,
119934 const UA_ByteString *key) {
119935 if(key == NULL || channelContext == NULL)
119936 return UA_STATUSCODE_BADINTERNALERROR;
119937 Channel_Context_Aes128Sha256RsaOaep *cc = (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119938 UA_ByteString_clear(p: &cc->remoteSymIv);
119939 return UA_ByteString_copy(src: key, dst: &cc->remoteSymIv);
119940}
119941
119942static UA_StatusCode
119943UA_AsySig_Aes128Sha256RsaOaep_sign(void *channelContext, const UA_ByteString *message,
119944 UA_ByteString *signature) {
119945 if(channelContext == NULL || message == NULL ||
119946 signature == NULL)
119947 return UA_STATUSCODE_BADINTERNALERROR;
119948 Channel_Context_Aes128Sha256RsaOaep *cc = (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119949 Policy_Context_Aes128Sha256RsaOaep *pc = cc->policyContext;
119950 return UA_Openssl_RSA_PKCS1_V15_SHA256_Sign(message, privateKey: pc->localPrivateKey, outSignature: signature);
119951}
119952
119953static UA_StatusCode
119954UA_AsymEn_Aes128Sha256RsaOaep_encrypt(void *channelContext, UA_ByteString *data) {
119955 if(channelContext == NULL || data == NULL)
119956 return UA_STATUSCODE_BADINTERNALERROR;
119957 Channel_Context_Aes128Sha256RsaOaep *cc =
119958 (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119959 return UA_Openssl_RSA_OAEP_Encrypt(
119960 data, UA_SECURITYPOLICY_AES128SHA256RSAOAEP_RSAPADDING_LEN,
119961 publicX509: cc->remoteCertificateX509);
119962}
119963
119964static size_t
119965UA_SymSig_Aes128Sha256RsaOaep_getRemoteSignatureSize(const void *channelContext) {
119966 return UA_SHA256_LENGTH;
119967}
119968
119969static UA_StatusCode
119970UA_SymSig_Aes128Sha256RsaOaep_verify(void *channelContext, const UA_ByteString *message,
119971 const UA_ByteString *signature) {
119972 if(channelContext == NULL || message == NULL ||
119973 signature == NULL)
119974 return UA_STATUSCODE_BADINTERNALERROR;
119975
119976 Channel_Context_Aes128Sha256RsaOaep *cc =
119977 (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119978 return UA_OpenSSL_HMAC_SHA256_Verify(message, key: &cc->remoteSymSigningKey, signature);
119979}
119980
119981static UA_StatusCode
119982UA_SymSig_Aes128Sha256RsaOaep_sign(void *channelContext, const UA_ByteString *message,
119983 UA_ByteString *signature) {
119984 if(channelContext == NULL || message == NULL ||
119985 signature == NULL)
119986 return UA_STATUSCODE_BADINTERNALERROR;
119987
119988 Channel_Context_Aes128Sha256RsaOaep *cc =
119989 (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
119990 return UA_OpenSSL_HMAC_SHA256_Sign(message, key: &cc->localSymSigningKey, signature);
119991}
119992
119993static size_t
119994UA_SymSig_Aes128Sha256RsaOaep_getLocalSignatureSize(const void *channelContext) {
119995 return UA_SHA256_LENGTH;
119996}
119997
119998static UA_StatusCode
119999UA_SymEn_Aes128Sha256RsaOaep_decrypt(void *channelContext, UA_ByteString *data) {
120000 if(channelContext == NULL || data == NULL)
120001 return UA_STATUSCODE_BADINTERNALERROR;
120002 Channel_Context_Aes128Sha256RsaOaep *cc =
120003 (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
120004 return UA_OpenSSL_AES_128_CBC_Decrypt(iv: &cc->remoteSymIv, key: &cc->remoteSymEncryptingKey,
120005 data);
120006}
120007
120008static UA_StatusCode
120009UA_SymEn_Aes128Sha256RsaOaep_encrypt(void *channelContext, UA_ByteString *data) {
120010 if(channelContext == NULL || data == NULL)
120011 return UA_STATUSCODE_BADINTERNALERROR;
120012
120013 Channel_Context_Aes128Sha256RsaOaep *cc =
120014 (Channel_Context_Aes128Sha256RsaOaep *)channelContext;
120015 return UA_OpenSSL_AES_128_CBC_Encrypt(iv: &cc->localSymIv, key: &cc->localSymEncryptingKey,
120016 data);
120017}
120018
120019static UA_StatusCode
120020UA_ChannelM_Aes128Sha256RsaOaep_compareCertificate(const void *channelContext,
120021 const UA_ByteString *certificate) {
120022 if(channelContext == NULL || certificate == NULL)
120023 return UA_STATUSCODE_BADINTERNALERROR;
120024
120025 const Channel_Context_Aes128Sha256RsaOaep *cc = (const Channel_Context_Aes128Sha256RsaOaep *)channelContext;
120026 return UA_OpenSSL_X509_compare(cert: certificate, bcert: cc->remoteCertificateX509);
120027}
120028
120029static size_t
120030UA_AsymEn_Aes128Sha256RsaOaep_getLocalKeyLength(const void *channelContext) {
120031 if(channelContext == NULL)
120032 return UA_STATUSCODE_BADINTERNALERROR;
120033
120034 const Channel_Context_Aes128Sha256RsaOaep *cc = (const Channel_Context_Aes128Sha256RsaOaep *)channelContext;
120035 Policy_Context_Aes128Sha256RsaOaep *pc = cc->policyContext;
120036 UA_Int32 keyLen = 0;
120037 UA_Openssl_RSA_Private_GetKeyLength(privateKey: pc->localPrivateKey, keyLen: &keyLen);
120038 return (size_t)keyLen * 8;
120039}
120040
120041/* the main entry of Aes128Sha256RsaOaep */
120042
120043UA_StatusCode
120044UA_SecurityPolicy_Aes128Sha256RsaOaep(UA_SecurityPolicy *policy,
120045 const UA_ByteString localCertificate,
120046 const UA_ByteString localPrivateKey,
120047 const UA_Logger *logger) {
120048
120049 UA_SecurityPolicyAsymmetricModule *const asymmetricModule = &policy->asymmetricModule;
120050 UA_SecurityPolicySymmetricModule *const symmetricModule = &policy->symmetricModule;
120051 UA_SecurityPolicyChannelModule *const channelModule = &policy->channelModule;
120052 UA_StatusCode retval;
120053
120054 UA_LOG_INFO(logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
120055 msg: "The Aes128Sha256RsaOaep security policy with openssl is added.");
120056
120057 UA_Openssl_Init();
120058 memset(s: policy, c: 0, n: sizeof(UA_SecurityPolicy));
120059 policy->logger = logger;
120060 policy->policyUri =
120061 UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaep\0");
120062
120063 /* set ChannelModule context */
120064
120065 channelModule->newContext = UA_ChannelModule_Aes128Sha256RsaOaep_New_Context;
120066 channelModule->deleteContext = UA_ChannelModule_Aes128Sha256RsaOaep_Delete_Context;
120067 channelModule->setLocalSymSigningKey =
120068 UA_ChannelModule_Aes128Sha256RsaOaep_setLocalSymSigningKey;
120069 channelModule->setLocalSymEncryptingKey =
120070 UA_ChannelM_Aes128Sha256RsaOaep_setLocalSymEncryptingKey;
120071 channelModule->setLocalSymIv = UA_ChannelM_Aes128Sha256RsaOaep_setLocalSymIv;
120072 channelModule->setRemoteSymSigningKey =
120073 UA_ChannelM_Aes128Sha256RsaOaep_setRemoteSymSigningKey;
120074 channelModule->setRemoteSymEncryptingKey =
120075 UA_ChannelM_Aes128Sha256RsaOaep_setRemoteSymEncryptingKey;
120076 channelModule->setRemoteSymIv = UA_ChannelM_Aes128Sha256RsaOaep_setRemoteSymIv;
120077 channelModule->compareCertificate =
120078 UA_ChannelM_Aes128Sha256RsaOaep_compareCertificate;
120079
120080 /* Load and convert to DER if necessary */
120081 retval =
120082 UA_OpenSSL_LoadLocalCertificate(certificate: &localCertificate, target: &policy->localCertificate);
120083 if(retval != UA_STATUSCODE_GOOD)
120084 return retval;
120085
120086 /* AsymmetricModule - signature algorithm */
120087
120088 UA_SecurityPolicySignatureAlgorithm *asySigAlgorithm =
120089 &asymmetricModule->cryptoModule.signatureAlgorithm;
120090 asySigAlgorithm->uri =
120091 UA_STRING(chars: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\0");
120092 asySigAlgorithm->verify = UA_AsySig_Aes128Sha256RsaOaep_Verify;
120093 asySigAlgorithm->getRemoteSignatureSize =
120094 UA_Asym_Aes128Sha256RsaOaep_getRemoteSignatureSize;
120095 asySigAlgorithm->getLocalSignatureSize =
120096 UA_AsySig_Aes128Sha256RsaOaep_getLocalSignatureSize;
120097 asySigAlgorithm->sign = UA_AsySig_Aes128Sha256RsaOaep_sign;
120098 asySigAlgorithm->getLocalKeyLength = NULL;
120099 asySigAlgorithm->getRemoteKeyLength = NULL;
120100
120101 /* AsymmetricModule encryption algorithm */
120102
120103 UA_SecurityPolicyEncryptionAlgorithm *asymEncryAlg =
120104 &asymmetricModule->cryptoModule.encryptionAlgorithm;
120105 asymEncryAlg->uri = UA_STRING(chars: "http://www.w3.org/2001/04/xmlenc#rsa-oaep\0");
120106 asymEncryAlg->decrypt = UA_Asym_Aes128Sha256RsaOaep_Decrypt;
120107 asymEncryAlg->getRemotePlainTextBlockSize =
120108 UA_AsymEn_Aes128Sha256RsaOaep_getRemotePlainTextBlockSize;
120109 asymEncryAlg->getRemoteBlockSize = UA_AsymEn_Aes128Sha256RsaOaep_getRemoteBlockSize;
120110 asymEncryAlg->getRemoteKeyLength = UA_AsymEn_Aes128Sha256RsaOaep_getRemoteKeyLength;
120111 asymEncryAlg->encrypt = UA_AsymEn_Aes128Sha256RsaOaep_encrypt;
120112 asymEncryAlg->getLocalKeyLength = UA_AsymEn_Aes128Sha256RsaOaep_getLocalKeyLength;
120113
120114 /* asymmetricModule */
120115
120116 asymmetricModule->compareCertificateThumbprint =
120117 UA_compareCertificateThumbprint_Aes128Sha256RsaOaep;
120118 asymmetricModule->makeCertificateThumbprint =
120119 UA_makeCertificateThumbprint_Aes128Sha256RsaOaep;
120120
120121 /* SymmetricModule */
120122
120123 symmetricModule->secureChannelNonceLength = 32;
120124 symmetricModule->generateNonce = UA_Sym_Aes128Sha256RsaOaep_generateNonce;
120125 symmetricModule->generateKey = UA_Sym_Aes128Sha256RsaOaep_generateKey;
120126
120127 /* Symmetric encryption Algorithm */
120128
120129 UA_SecurityPolicyEncryptionAlgorithm *symEncryptionAlgorithm =
120130 &symmetricModule->cryptoModule.encryptionAlgorithm;
120131 symEncryptionAlgorithm->uri =
120132 UA_STRING(chars: "http://www.w3.org/2001/04/xmlenc#aes128-cbc\0");
120133 symEncryptionAlgorithm->getLocalKeyLength = UA_SymEn_Aes128Sha256RsaOaep_getLocalKeyLength;
120134 symEncryptionAlgorithm->getRemoteKeyLength = UA_SymEn_Aes128Sha256RsaOaep_getRemoteKeyLength;
120135 symEncryptionAlgorithm->getRemoteBlockSize = UA_SymEn_Aes128Sha256RsaOaep_getBlockSize;
120136 symEncryptionAlgorithm->getRemotePlainTextBlockSize = UA_SymEn_Aes128Sha256RsaOaep_getBlockSize;
120137 symEncryptionAlgorithm->decrypt = UA_SymEn_Aes128Sha256RsaOaep_decrypt;
120138 symEncryptionAlgorithm->encrypt = UA_SymEn_Aes128Sha256RsaOaep_encrypt;
120139
120140 /* Symmetric signature Algorithm */
120141
120142 UA_SecurityPolicySignatureAlgorithm *symSignatureAlgorithm =
120143 &symmetricModule->cryptoModule.signatureAlgorithm;
120144 symSignatureAlgorithm->uri = UA_STRING(chars: "http://www.w3.org/2000/09/xmldsig#hmac-sha2-256\0");
120145 symSignatureAlgorithm->getLocalKeyLength = UA_SymSig_Aes128Sha256RsaOaep_getLocalKeyLength;
120146 symSignatureAlgorithm->getRemoteKeyLength = UA_SymSig_Aes128Sha256RsaOaep_getRemoteKeyLength;
120147 symSignatureAlgorithm->getRemoteSignatureSize = UA_SymSig_Aes128Sha256RsaOaep_getRemoteSignatureSize;
120148 symSignatureAlgorithm->verify = UA_SymSig_Aes128Sha256RsaOaep_verify;
120149 symSignatureAlgorithm->sign = UA_SymSig_Aes128Sha256RsaOaep_sign;
120150 symSignatureAlgorithm->getLocalSignatureSize = UA_SymSig_Aes128Sha256RsaOaep_getLocalSignatureSize;
120151
120152 retval = UA_Policy_Aes128Sha256RsaOaep_New_Context(securityPolicy: policy, localPrivateKey, logger);
120153 if(retval != UA_STATUSCODE_GOOD) {
120154 UA_ByteString_clear(p: &policy->localCertificate);
120155 return retval;
120156 }
120157 policy->updateCertificateAndPrivateKey =
120158 updateCertificateAndPrivateKey_sp_aes128sha256rsaoaep;
120159 policy->clear = UA_Policy_Aes128Sha256RsaOaep_Clear_Context;
120160
120161 /* Use the same signature algorithm as the asymmetric component for
120162 certificate signing (see standard) */
120163
120164 policy->certificateSigningAlgorithm =
120165 policy->asymmetricModule.cryptoModule.signatureAlgorithm;
120166
120167 return UA_STATUSCODE_GOOD;
120168}
120169
120170#endif
120171
120172/**** amalgamated original file "/plugins/crypto/openssl/ua_openssl_aes256sha256rsapss.c" ****/
120173
120174/* This Source Code Form is subject to the terms of the Mozilla Public
120175 * License, v. 2.0. If a copy of the MPL was not distributed with this
120176 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
120177 *
120178 * Copyright 2022 (c) Fraunhofer IOSB (Author: Noel Graf)
120179 */
120180
120181
120182#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL)
120183
120184
120185#include <openssl/hmac.h>
120186#include <openssl/sha.h>
120187#include <openssl/rsa.h>
120188#include <openssl/x509.h>
120189#include <openssl/rand.h>
120190#include <openssl/rsa.h>
120191
120192#define UA_SHA256_LENGTH 32 /* 256 bit */
120193#define UA_SECURITYPOLICY_AES256SHA256RSAPSS_RSAPADDING_LEN 66
120194#define UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_SIGNING_KEY_LENGTH 32
120195#define UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_ENCRYPTION_KEY_LENGTH 32
120196#define UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_ENCRYPTION_BLOCK_SIZE 16
120197#define UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_PLAIN_TEXT_BLOCK_SIZE 16
120198#define UA_SECURITYPOLICY_AES256SHA256RSAPSS_MINASYMKEYLENGTH 256
120199#define UA_SECURITYPOLICY_AES256SHA256RSAPSS_MAXASYMKEYLENGTH 512
120200
120201typedef struct {
120202 EVP_PKEY *localPrivateKey;
120203 UA_ByteString localCertThumbprint;
120204 const UA_Logger *logger;
120205} Policy_Context_Aes256Sha256RsaPss;
120206
120207typedef struct {
120208 UA_ByteString localSymSigningKey;
120209 UA_ByteString localSymEncryptingKey;
120210 UA_ByteString localSymIv;
120211 UA_ByteString remoteSymSigningKey;
120212 UA_ByteString remoteSymEncryptingKey;
120213 UA_ByteString remoteSymIv;
120214
120215 Policy_Context_Aes256Sha256RsaPss *policyContext;
120216 UA_ByteString remoteCertificate;
120217 X509 *remoteCertificateX509; /* X509 */
120218} Channel_Context_Aes256Sha256RsaPss;
120219
120220/* create the policy context */
120221
120222static UA_StatusCode
120223UA_Policy_Aes256Sha256RsaPss_New_Context(UA_SecurityPolicy *securityPolicy,
120224 const UA_ByteString localPrivateKey,
120225 const UA_Logger *logger) {
120226 Policy_Context_Aes256Sha256RsaPss *context =
120227 (Policy_Context_Aes256Sha256RsaPss *)UA_malloc(
120228 size: sizeof(Policy_Context_Aes256Sha256RsaPss));
120229 if(context == NULL) {
120230 return UA_STATUSCODE_BADOUTOFMEMORY;
120231 }
120232
120233 context->localPrivateKey = UA_OpenSSL_LoadPrivateKey(privateKey: &localPrivateKey);
120234 if (!context->localPrivateKey) {
120235 UA_free(ptr: context);
120236 return UA_STATUSCODE_BADINVALIDARGUMENT;
120237 }
120238
120239 UA_StatusCode retval = UA_Openssl_X509_GetCertificateThumbprint(
120240 certficate: &securityPolicy->localCertificate, pThumbprint: &context->localCertThumbprint, true);
120241 if(retval != UA_STATUSCODE_GOOD) {
120242 EVP_PKEY_free(pkey: context->localPrivateKey);
120243 UA_free(ptr: context);
120244 return retval;
120245 }
120246
120247 context->logger = logger;
120248 securityPolicy->policyContext = context;
120249
120250 return UA_STATUSCODE_GOOD;
120251}
120252
120253/* clear the policy context */
120254
120255static void
120256UA_Policy_Aes256Sha256RsaPss_Clear_Context(UA_SecurityPolicy *policy) {
120257 if(policy == NULL)
120258 return;
120259
120260 UA_ByteString_clear(p: &policy->localCertificate);
120261
120262 /* delete all allocated members in the context */
120263
120264 Policy_Context_Aes256Sha256RsaPss *pc =
120265 (Policy_Context_Aes256Sha256RsaPss *)policy->policyContext;
120266 if (pc == NULL) {
120267 return;
120268 }
120269
120270 EVP_PKEY_free(pkey: pc->localPrivateKey);
120271 UA_ByteString_clear(p: &pc->localCertThumbprint);
120272 UA_free(ptr: pc);
120273
120274 return;
120275}
120276
120277static UA_StatusCode
120278updateCertificateAndPrivateKey_sp_aes128sha256rsapss(UA_SecurityPolicy *securityPolicy,
120279 const UA_ByteString newCertificate,
120280 const UA_ByteString newPrivateKey) {
120281 if(securityPolicy == NULL)
120282 return UA_STATUSCODE_BADINTERNALERROR;
120283
120284 if(securityPolicy->policyContext == NULL)
120285 return UA_STATUSCODE_BADINTERNALERROR;
120286
120287 Policy_Context_Aes256Sha256RsaPss *pc =
120288 (Policy_Context_Aes256Sha256RsaPss *)securityPolicy->policyContext;
120289
120290 UA_ByteString_clear(p: &securityPolicy->localCertificate);
120291
120292 UA_StatusCode retval = UA_OpenSSL_LoadLocalCertificate(
120293 certificate: &newCertificate, target: &securityPolicy->localCertificate);
120294
120295 if(retval != UA_STATUSCODE_GOOD)
120296 return retval;
120297
120298 /* Set the new private key */
120299 EVP_PKEY_free(pkey: pc->localPrivateKey);
120300
120301 pc->localPrivateKey = UA_OpenSSL_LoadPrivateKey(privateKey: &newPrivateKey);
120302 if(!pc->localPrivateKey) {
120303 retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED;
120304 goto error;
120305 }
120306
120307 UA_ByteString_clear(p: &pc->localCertThumbprint);
120308
120309 retval = UA_Openssl_X509_GetCertificateThumbprint(certficate: &securityPolicy->localCertificate,
120310 pThumbprint: &pc->localCertThumbprint, true);
120311 if(retval != UA_STATUSCODE_GOOD) {
120312 goto error;
120313 }
120314
120315 return retval;
120316
120317error:
120318 UA_LOG_ERROR(logger: securityPolicy->logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
120319 msg: "Could not update certificate and private key");
120320 if(securityPolicy->policyContext != NULL)
120321 UA_Policy_Aes256Sha256RsaPss_Clear_Context(policy: securityPolicy);
120322 return retval;
120323}
120324
120325/* create the channel context */
120326
120327static UA_StatusCode
120328UA_ChannelModule_Aes256Sha256RsaPss_New_Context(const UA_SecurityPolicy *securityPolicy,
120329 const UA_ByteString *remoteCertificate,
120330 void **channelContext) {
120331 if(securityPolicy == NULL || remoteCertificate == NULL || channelContext == NULL) {
120332 return UA_STATUSCODE_BADINTERNALERROR;
120333 }
120334 Channel_Context_Aes256Sha256RsaPss *context =
120335 (Channel_Context_Aes256Sha256RsaPss *)UA_malloc(
120336 size: sizeof(Channel_Context_Aes256Sha256RsaPss));
120337 if(context == NULL) {
120338 return UA_STATUSCODE_BADOUTOFMEMORY;
120339 }
120340
120341 UA_ByteString_init(p: &context->localSymSigningKey);
120342 UA_ByteString_init(p: &context->localSymEncryptingKey);
120343 UA_ByteString_init(p: &context->localSymIv);
120344 UA_ByteString_init(p: &context->remoteSymSigningKey);
120345 UA_ByteString_init(p: &context->remoteSymEncryptingKey);
120346 UA_ByteString_init(p: &context->remoteSymIv);
120347
120348 UA_StatusCode retval =
120349 UA_copyCertificate(dst: &context->remoteCertificate, src: remoteCertificate);
120350 if(retval != UA_STATUSCODE_GOOD) {
120351 UA_free(ptr: context);
120352 return retval;
120353 }
120354
120355 /* decode to X509 */
120356 context->remoteCertificateX509 = UA_OpenSSL_LoadCertificate(certificate: &context->remoteCertificate);
120357 if (context->remoteCertificateX509 == NULL) {
120358 UA_ByteString_clear (p: &context->remoteCertificate);
120359 UA_free (ptr: context);
120360 return UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE;
120361 }
120362
120363 context->policyContext =
120364 (Policy_Context_Aes256Sha256RsaPss *)(securityPolicy->policyContext);
120365
120366 *channelContext = context;
120367
120368 UA_LOG_INFO(
120369 logger: securityPolicy->logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
120370 msg: "The Aes256Sha256RsaPss security policy channel with openssl is created.");
120371
120372 return UA_STATUSCODE_GOOD;
120373}
120374
120375/* delete the channel context */
120376
120377static void
120378UA_ChannelModule_Aes256Sha256RsaPss_Delete_Context(void *channelContext) {
120379 if(channelContext != NULL) {
120380 Channel_Context_Aes256Sha256RsaPss *cc =
120381 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120382 X509_free(a: cc->remoteCertificateX509);
120383 UA_ByteString_clear(p: &cc->remoteCertificate);
120384 UA_ByteString_clear(p: &cc->localSymSigningKey);
120385 UA_ByteString_clear(p: &cc->localSymEncryptingKey);
120386 UA_ByteString_clear(p: &cc->localSymIv);
120387 UA_ByteString_clear(p: &cc->remoteSymSigningKey);
120388 UA_ByteString_clear(p: &cc->remoteSymEncryptingKey);
120389 UA_ByteString_clear(p: &cc->remoteSymIv);
120390
120391 UA_LOG_INFO(
120392 logger: cc->policyContext->logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
120393 msg: "The Aes256Sha256RsaPss security policy channel with openssl is deleted.");
120394 UA_free(ptr: cc);
120395 }
120396}
120397
120398/* Verifies the signature of the message using the provided keys in the context.
120399 * AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256
120400 */
120401
120402static UA_StatusCode
120403UA_AsySig_Aes256Sha256RsaPss_Verify(void *channelContext, const UA_ByteString *message,
120404 const UA_ByteString *signature) {
120405 if(message == NULL || signature == NULL || channelContext == NULL) {
120406 return UA_STATUSCODE_BADINTERNALERROR;
120407 }
120408
120409 Channel_Context_Aes256Sha256RsaPss *cc =
120410 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120411 UA_StatusCode retval = UA_OpenSSL_RSA_PSS_SHA256_Verify(
120412 msg: message, publicKeyX509: cc->remoteCertificateX509, signature);
120413
120414 return retval;
120415}
120416
120417/* Compares the supplied certificate with the certificate
120418 * in the endpoint context
120419 */
120420
120421static UA_StatusCode
120422UA_compareCertificateThumbprint_Aes256Sha256RsaPss(const UA_SecurityPolicy *securityPolicy,
120423 const UA_ByteString *certificateThumbprint) {
120424 if(securityPolicy == NULL || certificateThumbprint == NULL) {
120425 return UA_STATUSCODE_BADINVALIDARGUMENT;
120426 }
120427 Policy_Context_Aes256Sha256RsaPss *pc =
120428 (Policy_Context_Aes256Sha256RsaPss *)securityPolicy->policyContext;
120429 if(!UA_ByteString_equal(p1: certificateThumbprint, p2: &pc->localCertThumbprint))
120430 return UA_STATUSCODE_BADCERTIFICATEINVALID;
120431 return UA_STATUSCODE_GOOD;
120432}
120433
120434/* Generates a thumbprint for the specified certificate */
120435
120436static UA_StatusCode
120437UA_makeCertificateThumbprint_Aes256Sha256RsaPss(const UA_SecurityPolicy *securityPolicy,
120438 const UA_ByteString *certificate,
120439 UA_ByteString *thumbprint) {
120440 return UA_Openssl_X509_GetCertificateThumbprint(certficate: certificate, pThumbprint: thumbprint, false);
120441}
120442
120443static UA_StatusCode
120444UA_Asym_Aes256Sha256RsaPss_Decrypt(void *channelContext, UA_ByteString *data) {
120445 if(channelContext == NULL || data == NULL)
120446 return UA_STATUSCODE_BADINVALIDARGUMENT;
120447
120448 Channel_Context_Aes256Sha256RsaPss *cc = (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120449 UA_StatusCode ret = UA_Openssl_RSA_Oaep_Sha2_Decrypt(data, privateKey: cc->policyContext->localPrivateKey);
120450 return ret;
120451}
120452
120453static size_t
120454UA_Asym_Aes256Sha256RsaPss_getRemoteSignatureSize(const void *channelContext) {
120455 if(channelContext == NULL)
120456 return UA_STATUSCODE_BADINTERNALERROR;
120457
120458 const Channel_Context_Aes256Sha256RsaPss *cc = (const Channel_Context_Aes256Sha256RsaPss *)channelContext;
120459 UA_Int32 keyLen = 0;
120460 UA_Openssl_RSA_Public_GetKeyLength(publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
120461 return (size_t)keyLen;
120462}
120463
120464static size_t
120465UA_AsySig_Aes256Sha256RsaPss_getLocalSignatureSize(const void *channelContext) {
120466 if(channelContext == NULL)
120467 return UA_STATUSCODE_BADINTERNALERROR;
120468
120469 const Channel_Context_Aes256Sha256RsaPss *cc = (const Channel_Context_Aes256Sha256RsaPss *)channelContext;
120470 Policy_Context_Aes256Sha256RsaPss *pc = cc->policyContext;
120471 UA_Int32 keyLen = 0;
120472 UA_Openssl_RSA_Private_GetKeyLength(privateKey: pc->localPrivateKey, keyLen: &keyLen);
120473 return (size_t)keyLen;
120474}
120475
120476static size_t
120477UA_AsymEn_Aes256Sha256RsaPss_getRemotePlainTextBlockSize(const void *channelContext) {
120478 if(channelContext == NULL)
120479 return UA_STATUSCODE_BADINTERNALERROR;
120480
120481 const Channel_Context_Aes256Sha256RsaPss *cc =
120482 (const Channel_Context_Aes256Sha256RsaPss *)channelContext;
120483 UA_Int32 keyLen = 0;
120484 UA_Openssl_RSA_Public_GetKeyLength(publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
120485 return (size_t)keyLen - UA_SECURITYPOLICY_AES256SHA256RSAPSS_RSAPADDING_LEN;
120486}
120487
120488static size_t
120489UA_AsymEn_Aes256Sha256RsaPss_getRemoteBlockSize(const void *channelContext) {
120490 if(channelContext == NULL)
120491 return UA_STATUSCODE_BADINTERNALERROR;
120492
120493 const Channel_Context_Aes256Sha256RsaPss *cc =
120494 (const Channel_Context_Aes256Sha256RsaPss *)channelContext;
120495 UA_Int32 keyLen = 0;
120496 UA_Openssl_RSA_Public_GetKeyLength(publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
120497 return (size_t)keyLen;
120498}
120499
120500static size_t
120501UA_AsymEn_Aes256Sha256RsaPss_getRemoteKeyLength(const void *channelContext) {
120502 if(channelContext == NULL)
120503 return UA_STATUSCODE_BADINTERNALERROR;
120504
120505 const Channel_Context_Aes256Sha256RsaPss *cc =
120506 (const Channel_Context_Aes256Sha256RsaPss *)channelContext;
120507 UA_Int32 keyLen = 0;
120508 UA_Openssl_RSA_Public_GetKeyLength(publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
120509 return (size_t)keyLen * 8;
120510}
120511
120512static UA_StatusCode
120513UA_Sym_Aes256Sha256RsaPss_generateNonce(void *policyContext,
120514 UA_ByteString *out) {
120515 UA_Int32 rc = RAND_bytes(buf: out->data, num: (int)out->length);
120516 if(rc != 1) {
120517 return UA_STATUSCODE_BADUNEXPECTEDERROR;
120518 }
120519 return UA_STATUSCODE_GOOD;
120520}
120521
120522static size_t
120523UA_SymEn_Aes256Sha256RsaPss_getLocalKeyLength(const void *channelContext) {
120524 /* 32 bytes 256 bits */
120525 return UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_ENCRYPTION_KEY_LENGTH;
120526}
120527
120528static size_t
120529UA_SymSig_Aes256Sha256RsaPss_getLocalKeyLength(const void *channelContext) {
120530 /* 32 bytes 256 bits */
120531 return UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_SIGNING_KEY_LENGTH;
120532}
120533
120534static UA_StatusCode
120535UA_Sym_Aes256Sha256RsaPss_generateKey(void *policyContext,
120536 const UA_ByteString *secret,
120537 const UA_ByteString *seed, UA_ByteString *out) {
120538 return UA_Openssl_Random_Key_PSHA256_Derive(secret, seed, out);
120539}
120540
120541static UA_StatusCode
120542UA_CertSig_Aes256Sha256RsaPss_Verify(void *channelContext, const UA_ByteString *message,
120543 const UA_ByteString *signature) {
120544 if(message == NULL || signature == NULL || channelContext == NULL) {
120545 return UA_STATUSCODE_BADINTERNALERROR;
120546 }
120547
120548 Channel_Context_Aes256Sha256RsaPss *cc =
120549 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120550 UA_StatusCode retval = UA_OpenSSL_RSA_PKCS1_V15_SHA256_Verify(
120551 msg: message, publicKeyX509: cc->remoteCertificateX509, signature);
120552
120553 return retval;
120554}
120555
120556static UA_StatusCode
120557UA_CertSig_Aes256Sha256RsaPss_sign(void *channelContext, const UA_ByteString *message,
120558 UA_ByteString *signature) {
120559 if(channelContext == NULL || message == NULL ||
120560 signature == NULL)
120561 return UA_STATUSCODE_BADINTERNALERROR;
120562 Channel_Context_Aes256Sha256RsaPss *cc = (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120563 Policy_Context_Aes256Sha256RsaPss *pc = cc->policyContext;
120564 return UA_Openssl_RSA_PKCS1_V15_SHA256_Sign(message, privateKey: pc->localPrivateKey, outSignature: signature);
120565}
120566
120567static size_t
120568UA_CertSig_Aes256Sha256RsaPss_getRemoteSignatureSize(const void *channelContext) {
120569 if(channelContext == NULL)
120570 return UA_STATUSCODE_BADINTERNALERROR;
120571
120572 const Channel_Context_Aes256Sha256RsaPss *cc = (const Channel_Context_Aes256Sha256RsaPss *)channelContext;
120573 UA_Int32 keyLen = 0;
120574 UA_Openssl_RSA_Public_GetKeyLength(publicKeyX509: cc->remoteCertificateX509, keyLen: &keyLen);
120575 return (size_t)keyLen;
120576}
120577
120578static size_t
120579UA_CertSig_Aes256Sha256RsaPss_getLocalSignatureSize(const void *channelContext) {
120580 if(channelContext == NULL)
120581 return UA_STATUSCODE_BADINTERNALERROR;
120582
120583 const Channel_Context_Aes256Sha256RsaPss *cc = (const Channel_Context_Aes256Sha256RsaPss *)channelContext;
120584 Policy_Context_Aes256Sha256RsaPss *pc = cc->policyContext;
120585 UA_Int32 keyLen = 0;
120586 UA_Openssl_RSA_Private_GetKeyLength(privateKey: pc->localPrivateKey, keyLen: &keyLen);
120587 return (size_t)keyLen;
120588}
120589
120590static UA_StatusCode
120591UA_ChannelModule_Aes256Sha256RsaPss_setLocalSymSigningKey(void *channelContext,
120592 const UA_ByteString *key) {
120593 if(key == NULL || channelContext == NULL)
120594 return UA_STATUSCODE_BADINTERNALERROR;
120595 Channel_Context_Aes256Sha256RsaPss *cc =
120596 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120597 UA_ByteString_clear(p: &cc->localSymSigningKey);
120598 return UA_ByteString_copy(src: key, dst: &cc->localSymSigningKey);
120599}
120600
120601static UA_StatusCode
120602UA_ChannelM_Aes256Sha256RsaPss_setLocalSymEncryptingKey(void *channelContext,
120603 const UA_ByteString *key) {
120604 if(key == NULL || channelContext == NULL)
120605 return UA_STATUSCODE_BADINTERNALERROR;
120606 Channel_Context_Aes256Sha256RsaPss *cc =
120607 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120608 UA_ByteString_clear(p: &cc->localSymEncryptingKey);
120609 return UA_ByteString_copy(src: key, dst: &cc->localSymEncryptingKey);
120610}
120611
120612static UA_StatusCode
120613UA_ChannelM_Aes256Sha256RsaPss_setLocalSymIv(void *channelContext,
120614 const UA_ByteString *iv) {
120615 if(iv == NULL || channelContext == NULL)
120616 return UA_STATUSCODE_BADINTERNALERROR;
120617 Channel_Context_Aes256Sha256RsaPss *cc =
120618 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120619 UA_ByteString_clear(p: &cc->localSymIv);
120620 return UA_ByteString_copy(src: iv, dst: &cc->localSymIv);
120621}
120622
120623static size_t
120624UA_SymEn_Aes256Sha256RsaPss_getRemoteKeyLength(const void *channelContext) {
120625 /* 32 bytes 256 bits */
120626 return UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_ENCRYPTION_KEY_LENGTH;
120627}
120628
120629static size_t
120630UA_SymEn_Aes256Sha256RsaPss_getBlockSize(const void *channelContext) {
120631 return UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_ENCRYPTION_BLOCK_SIZE;
120632}
120633
120634static size_t
120635UA_SymSig_Aes256Sha256RsaPss_getRemoteKeyLength(const void *channelContext) {
120636 /* 32 bytes 256 bits */
120637 return UA_SECURITYPOLICY_AES256SHA256RSAPSS_SYM_SIGNING_KEY_LENGTH;
120638}
120639
120640static UA_StatusCode
120641UA_ChannelM_Aes256Sha256RsaPss_setRemoteSymSigningKey(void *channelContext,
120642 const UA_ByteString *key) {
120643 if(key == NULL || channelContext == NULL)
120644 return UA_STATUSCODE_BADINTERNALERROR;
120645 Channel_Context_Aes256Sha256RsaPss *cc =
120646 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120647 UA_ByteString_clear(p: &cc->remoteSymSigningKey);
120648 return UA_ByteString_copy(src: key, dst: &cc->remoteSymSigningKey);
120649}
120650
120651static UA_StatusCode
120652UA_ChannelM_Aes256Sha256RsaPss_setRemoteSymEncryptingKey(void *channelContext,
120653 const UA_ByteString *key) {
120654 if(key == NULL || channelContext == NULL)
120655 return UA_STATUSCODE_BADINTERNALERROR;
120656 Channel_Context_Aes256Sha256RsaPss *cc =
120657 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120658 UA_ByteString_clear(p: &cc->remoteSymEncryptingKey);
120659 return UA_ByteString_copy(src: key, dst: &cc->remoteSymEncryptingKey);
120660}
120661
120662static UA_StatusCode
120663UA_ChannelM_Aes256Sha256RsaPss_setRemoteSymIv(void *channelContext,
120664 const UA_ByteString *key) {
120665 if(key == NULL || channelContext == NULL)
120666 return UA_STATUSCODE_BADINTERNALERROR;
120667 Channel_Context_Aes256Sha256RsaPss *cc =
120668 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120669 UA_ByteString_clear(p: &cc->remoteSymIv);
120670 return UA_ByteString_copy(src: key, dst: &cc->remoteSymIv);
120671}
120672
120673static UA_StatusCode
120674UA_AsySig_Aes256Sha256RsaPss_sign(void *channelContext, const UA_ByteString *message,
120675 UA_ByteString *signature) {
120676 if(channelContext == NULL || message == NULL ||
120677 signature == NULL)
120678 return UA_STATUSCODE_BADINTERNALERROR;
120679 Channel_Context_Aes256Sha256RsaPss *cc =
120680 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120681 Policy_Context_Aes256Sha256RsaPss *pc = cc->policyContext;
120682 return UA_Openssl_RSA_PSS_SHA256_Sign(message, privateKey: pc->localPrivateKey, outSignature: signature);
120683}
120684
120685static UA_StatusCode
120686UA_AsymEn_Aes256Sha256RsaPss_encrypt(void *channelContext, UA_ByteString *data) {
120687 if(channelContext == NULL || data == NULL)
120688 return UA_STATUSCODE_BADINTERNALERROR;
120689 Channel_Context_Aes256Sha256RsaPss *cc =
120690 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120691 return UA_Openssl_RSA_OAEP_SHA2_Encrypt(
120692 data, UA_SECURITYPOLICY_AES256SHA256RSAPSS_RSAPADDING_LEN,
120693 publicX509: cc->remoteCertificateX509);
120694}
120695
120696static size_t
120697UA_SymSig_Aes256Sha256RsaPss_getRemoteSignatureSize(const void *channelContext) {
120698 return UA_SHA256_LENGTH;
120699}
120700
120701static UA_StatusCode
120702UA_SymSig_Aes256Sha256RsaPss_verify(void *channelContext, const UA_ByteString *message,
120703 const UA_ByteString *signature) {
120704 if(channelContext == NULL || message == NULL ||
120705 signature == NULL)
120706 return UA_STATUSCODE_BADINTERNALERROR;
120707
120708 Channel_Context_Aes256Sha256RsaPss *cc =
120709 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120710 return UA_OpenSSL_HMAC_SHA256_Verify(message, key: &cc->remoteSymSigningKey, signature);
120711}
120712
120713static UA_StatusCode
120714UA_SymSig_Aes256Sha256RsaPss_sign(void *channelContext, const UA_ByteString *message,
120715 UA_ByteString *signature) {
120716 if(channelContext == NULL || message == NULL ||
120717 signature == NULL)
120718 return UA_STATUSCODE_BADINTERNALERROR;
120719
120720 Channel_Context_Aes256Sha256RsaPss *cc =
120721 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120722 return UA_OpenSSL_HMAC_SHA256_Sign(message, key: &cc->localSymSigningKey, signature);
120723}
120724
120725static size_t
120726UA_SymSig_Aes256Sha256RsaPss_getLocalSignatureSize(const void *channelContext) {
120727 return UA_SHA256_LENGTH;
120728}
120729
120730static UA_StatusCode
120731UA_SymEn_Aes256Sha256RsaPss_decrypt(void *channelContext, UA_ByteString *data) {
120732 if(channelContext == NULL || data == NULL)
120733 return UA_STATUSCODE_BADINTERNALERROR;
120734 Channel_Context_Aes256Sha256RsaPss *cc =
120735 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120736 return UA_OpenSSL_AES_256_CBC_Decrypt(iv: &cc->remoteSymIv, key: &cc->remoteSymEncryptingKey,
120737 data);
120738}
120739
120740static UA_StatusCode
120741UA_SymEn_Aes256Sha256RsaPss_encrypt(void *channelContext, UA_ByteString *data) {
120742 if(channelContext == NULL || data == NULL)
120743 return UA_STATUSCODE_BADINTERNALERROR;
120744
120745 Channel_Context_Aes256Sha256RsaPss *cc =
120746 (Channel_Context_Aes256Sha256RsaPss *)channelContext;
120747 return UA_OpenSSL_AES_256_CBC_Encrypt(iv: &cc->localSymIv, key: &cc->localSymEncryptingKey,
120748 data);
120749}
120750
120751static UA_StatusCode
120752UA_ChannelM_Aes256Sha256RsaPss_compareCertificate(const void *channelContext,
120753 const UA_ByteString *certificate) {
120754 if(channelContext == NULL || certificate == NULL)
120755 return UA_STATUSCODE_BADINTERNALERROR;
120756
120757 const Channel_Context_Aes256Sha256RsaPss *cc =
120758 (const Channel_Context_Aes256Sha256RsaPss *)channelContext;
120759 return UA_OpenSSL_X509_compare(cert: certificate, bcert: cc->remoteCertificateX509);
120760}
120761
120762static size_t
120763UA_AsymEn_Aes256Sha256RsaPss_getLocalKeyLength(const void *channelContext) {
120764 if(channelContext == NULL)
120765 return UA_STATUSCODE_BADINTERNALERROR;
120766
120767 const Channel_Context_Aes256Sha256RsaPss *cc =
120768 (const Channel_Context_Aes256Sha256RsaPss *)channelContext;
120769 Policy_Context_Aes256Sha256RsaPss *pc = cc->policyContext;
120770 UA_Int32 keyLen = 0;
120771 UA_Openssl_RSA_Private_GetKeyLength(privateKey: pc->localPrivateKey, keyLen: &keyLen);
120772 return (size_t)keyLen * 8;
120773}
120774
120775/* the main entry of Aes256Sha256RsaPss */
120776
120777UA_StatusCode
120778UA_SecurityPolicy_Aes256Sha256RsaPss(UA_SecurityPolicy *policy,
120779 const UA_ByteString localCertificate,
120780 const UA_ByteString localPrivateKey,
120781 const UA_Logger *logger) {
120782
120783 UA_SecurityPolicyAsymmetricModule *const asymmetricModule = &policy->asymmetricModule;
120784 UA_SecurityPolicySymmetricModule *const symmetricModule = &policy->symmetricModule;
120785 UA_SecurityPolicyChannelModule *const channelModule = &policy->channelModule;
120786 UA_StatusCode retval;
120787
120788 UA_LOG_INFO(logger, category: UA_LOGCATEGORY_SECURITYPOLICY,
120789 msg: "The Aes256Sha256RsaPss security policy with openssl is added.");
120790
120791 UA_Openssl_Init();
120792 memset(s: policy, c: 0, n: sizeof(UA_SecurityPolicy));
120793 policy->logger = logger;
120794 policy->policyUri =
120795 UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#Aes256_Sha256_RsaPss\0");
120796
120797 /* set ChannelModule context */
120798
120799 channelModule->newContext = UA_ChannelModule_Aes256Sha256RsaPss_New_Context;
120800 channelModule->deleteContext = UA_ChannelModule_Aes256Sha256RsaPss_Delete_Context;
120801 channelModule->setLocalSymSigningKey =
120802 UA_ChannelModule_Aes256Sha256RsaPss_setLocalSymSigningKey;
120803 channelModule->setLocalSymEncryptingKey =
120804 UA_ChannelM_Aes256Sha256RsaPss_setLocalSymEncryptingKey;
120805 channelModule->setLocalSymIv = UA_ChannelM_Aes256Sha256RsaPss_setLocalSymIv;
120806 channelModule->setRemoteSymSigningKey =
120807 UA_ChannelM_Aes256Sha256RsaPss_setRemoteSymSigningKey;
120808 channelModule->setRemoteSymEncryptingKey =
120809 UA_ChannelM_Aes256Sha256RsaPss_setRemoteSymEncryptingKey;
120810 channelModule->setRemoteSymIv = UA_ChannelM_Aes256Sha256RsaPss_setRemoteSymIv;
120811 channelModule->compareCertificate =
120812 UA_ChannelM_Aes256Sha256RsaPss_compareCertificate;
120813
120814 /* Load and convert to DER if necessary */
120815 retval =
120816 UA_OpenSSL_LoadLocalCertificate(certificate: &localCertificate, target: &policy->localCertificate);
120817 if(retval != UA_STATUSCODE_GOOD)
120818 return retval;
120819
120820 /* AsymmetricModule - signature algorithm */
120821
120822 UA_SecurityPolicySignatureAlgorithm *asySigAlgorithm =
120823 &asymmetricModule->cryptoModule.signatureAlgorithm;
120824 asySigAlgorithm->uri =
120825 UA_STRING(chars: "http://opcfoundation.org/UA/security/rsa-pss-sha2-256\0");
120826 asySigAlgorithm->verify = UA_AsySig_Aes256Sha256RsaPss_Verify;
120827 asySigAlgorithm->getRemoteSignatureSize =
120828 UA_Asym_Aes256Sha256RsaPss_getRemoteSignatureSize;
120829 asySigAlgorithm->getLocalSignatureSize =
120830 UA_AsySig_Aes256Sha256RsaPss_getLocalSignatureSize;
120831 asySigAlgorithm->sign = UA_AsySig_Aes256Sha256RsaPss_sign;
120832 asySigAlgorithm->getLocalKeyLength = NULL;
120833 asySigAlgorithm->getRemoteKeyLength = NULL;
120834
120835 /* AsymmetricModule encryption algorithm */
120836
120837 UA_SecurityPolicyEncryptionAlgorithm *asymEncryAlg =
120838 &asymmetricModule->cryptoModule.encryptionAlgorithm;
120839 asymEncryAlg->uri = UA_STRING(chars: "http://opcfoundation.org/UA/security/rsa-oaep-sha2-256\0");
120840 asymEncryAlg->decrypt = UA_Asym_Aes256Sha256RsaPss_Decrypt;
120841 asymEncryAlg->getRemotePlainTextBlockSize =
120842 UA_AsymEn_Aes256Sha256RsaPss_getRemotePlainTextBlockSize;
120843 asymEncryAlg->getRemoteBlockSize = UA_AsymEn_Aes256Sha256RsaPss_getRemoteBlockSize;
120844 asymEncryAlg->getRemoteKeyLength = UA_AsymEn_Aes256Sha256RsaPss_getRemoteKeyLength;
120845 asymEncryAlg->encrypt = UA_AsymEn_Aes256Sha256RsaPss_encrypt;
120846 asymEncryAlg->getLocalKeyLength = UA_AsymEn_Aes256Sha256RsaPss_getLocalKeyLength;
120847
120848 /* asymmetricModule */
120849
120850 asymmetricModule->compareCertificateThumbprint =
120851 UA_compareCertificateThumbprint_Aes256Sha256RsaPss;
120852 asymmetricModule->makeCertificateThumbprint =
120853 UA_makeCertificateThumbprint_Aes256Sha256RsaPss;
120854
120855 /* SymmetricModule */
120856
120857 symmetricModule->secureChannelNonceLength = 32;
120858 symmetricModule->generateNonce = UA_Sym_Aes256Sha256RsaPss_generateNonce;
120859 symmetricModule->generateKey = UA_Sym_Aes256Sha256RsaPss_generateKey;
120860
120861 /* Symmetric encryption Algorithm */
120862
120863 UA_SecurityPolicyEncryptionAlgorithm *symEncryptionAlgorithm =
120864 &symmetricModule->cryptoModule.encryptionAlgorithm;
120865 symEncryptionAlgorithm->uri =
120866 UA_STRING(chars: "http://www.w3.org/2001/04/xmlenc#aes256-cbc\0");
120867 symEncryptionAlgorithm->getLocalKeyLength = UA_SymEn_Aes256Sha256RsaPss_getLocalKeyLength;
120868 symEncryptionAlgorithm->getRemoteKeyLength = UA_SymEn_Aes256Sha256RsaPss_getRemoteKeyLength;
120869 symEncryptionAlgorithm->getRemoteBlockSize = UA_SymEn_Aes256Sha256RsaPss_getBlockSize;
120870 symEncryptionAlgorithm->getRemotePlainTextBlockSize = UA_SymEn_Aes256Sha256RsaPss_getBlockSize;
120871 symEncryptionAlgorithm->decrypt = UA_SymEn_Aes256Sha256RsaPss_decrypt;
120872 symEncryptionAlgorithm->encrypt = UA_SymEn_Aes256Sha256RsaPss_encrypt;
120873
120874 /* Symmetric signature Algorithm */
120875
120876 UA_SecurityPolicySignatureAlgorithm *symSignatureAlgorithm =
120877 &symmetricModule->cryptoModule.signatureAlgorithm;
120878 symSignatureAlgorithm->uri = UA_STRING(chars: "http://www.w3.org/2000/09/xmldsig#hmac-sha2-256\0");
120879 symSignatureAlgorithm->getLocalKeyLength = UA_SymSig_Aes256Sha256RsaPss_getLocalKeyLength;
120880 symSignatureAlgorithm->getRemoteKeyLength = UA_SymSig_Aes256Sha256RsaPss_getRemoteKeyLength;
120881 symSignatureAlgorithm->getRemoteSignatureSize = UA_SymSig_Aes256Sha256RsaPss_getRemoteSignatureSize;
120882 symSignatureAlgorithm->verify = UA_SymSig_Aes256Sha256RsaPss_verify;
120883 symSignatureAlgorithm->sign = UA_SymSig_Aes256Sha256RsaPss_sign;
120884 symSignatureAlgorithm->getLocalSignatureSize = UA_SymSig_Aes256Sha256RsaPss_getLocalSignatureSize;
120885
120886 retval = UA_Policy_Aes256Sha256RsaPss_New_Context(securityPolicy: policy, localPrivateKey, logger);
120887 if(retval != UA_STATUSCODE_GOOD) {
120888 UA_ByteString_clear(p: &policy->localCertificate);
120889 return retval;
120890 }
120891 policy->updateCertificateAndPrivateKey = updateCertificateAndPrivateKey_sp_aes128sha256rsapss;
120892 policy->clear = UA_Policy_Aes256Sha256RsaPss_Clear_Context;
120893
120894 /* Certificate Signing Algorithm */
120895 policy->certificateSigningAlgorithm.uri =
120896 UA_STRING(chars: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\0");
120897 policy->certificateSigningAlgorithm.verify =
120898 (UA_StatusCode (*)(void *, const UA_ByteString *, const UA_ByteString *))UA_CertSig_Aes256Sha256RsaPss_Verify;
120899 policy->certificateSigningAlgorithm.sign =
120900 (UA_StatusCode (*)(void *, const UA_ByteString *, UA_ByteString *))UA_CertSig_Aes256Sha256RsaPss_sign;
120901 policy->certificateSigningAlgorithm.getLocalSignatureSize =
120902 (size_t (*)(const void *))UA_CertSig_Aes256Sha256RsaPss_getLocalSignatureSize;
120903 policy->certificateSigningAlgorithm.getRemoteSignatureSize =
120904 (size_t (*)(const void *))UA_CertSig_Aes256Sha256RsaPss_getRemoteSignatureSize;
120905 policy->certificateSigningAlgorithm.getLocalKeyLength = NULL; // TODO: Write function
120906 policy->certificateSigningAlgorithm.getRemoteKeyLength = NULL; // TODO: Write function
120907
120908 return UA_STATUSCODE_GOOD;
120909}
120910
120911#endif
120912
120913/**** amalgamated original file "/plugins/crypto/openssl/ua_openssl_create_certificate.c" ****/
120914
120915/* This Source Code Form is subject to the terms of the Mozilla Public
120916 * License, v. 2.0. If a copy of the MPL was not distributed with this
120917 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
120918 *
120919 * Copyright 2021 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati)
120920 * Copyright 2022 (c) Wind River Systems, Inc.
120921 *
120922 */
120923
120924
120925
120926#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL)
120927
120928
120929#include <openssl/pem.h>
120930#include <openssl/x509v3.h>
120931#include <openssl/err.h>
120932
120933/**
120934 * Join an array of UA_String to a single NULL-Terminated UA_String
120935 * separated by character sep
120936 */
120937static UA_StatusCode
120938join_string_with_sep(const UA_String *strings, size_t stringsSize,
120939 char sep, UA_String *out) {
120940 if(!out)
120941 return UA_STATUSCODE_BADINVALIDARGUMENT;
120942
120943 UA_String_clear(p: out);
120944 size_t totalSize = stringsSize;
120945 for(size_t iStr = 0; iStr < stringsSize; ++iStr) {
120946 totalSize += strings[iStr].length;
120947 }
120948
120949 UA_ByteString_allocBuffer(bs: out, length: totalSize);
120950 if(!out->data) {
120951 return UA_STATUSCODE_BADOUTOFMEMORY;
120952 }
120953
120954 size_t pos = 0;
120955 for(size_t iStr = 0; iStr < stringsSize; ++iStr) {
120956 memcpy(dest: &out->data[pos], src: strings[iStr].data, n: strings[iStr].length);
120957 pos += strings[iStr].length;
120958 out->data[pos] = (UA_Byte) sep;
120959 ++pos;
120960 }
120961 out->data[out->length-1] = 0;
120962
120963 return UA_STATUSCODE_GOOD;
120964}
120965
120966/**
120967 * Search for a character in a string (like strchr).
120968 * \todo Handle UTF-8
120969 *
120970 * \return index of the character or -1 on case of an error.
120971 */
120972
120973static UA_Int32
120974UA_String_chr(const UA_String *pUaStr, char needl) {
120975 UA_Byte byteNeedl = (UA_Byte)needl;
120976 for(size_t i = 0; (size_t)i < pUaStr->length; ++i) {
120977 if(pUaStr->data[i] == byteNeedl) {
120978 return (UA_Int32) i;
120979 }
120980 }
120981 return -1;
120982}
120983
120984/* char *value cannot be const due to openssl 1.0 compatibility */
120985static UA_StatusCode
120986add_x509V3ext(const UA_Logger *logger, X509 *x509, int nid, char *value) {
120987 X509_EXTENSION *ex;
120988 X509V3_CTX ctx;
120989 X509V3_set_ctx_nodb(&ctx);
120990 X509V3_set_ctx(ctx: &ctx, issuer: x509, subject: x509, NULL, NULL, flags: 0);
120991 ex = X509V3_EXT_conf_nid(NULL, ctx: &ctx, ext_nid: nid, value);
120992 if(!ex)
120993 {
120994#if UA_LOGLEVEL <= 300
120995 const char * file = NULL;
120996 int line = 0;
120997 const char * data = NULL;
120998 int flags = 0;
120999 get_error_line_data(&file, &line, &data, &flags);
121000 UA_LOG_INFO(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121001 msg: "Internal SSL error file: %s:%d data: %s", file, line, data);
121002#endif
121003 return UA_STATUSCODE_BADINTERNALERROR;
121004 }
121005 X509_add_ext(x: x509, ex, loc: -1);
121006 X509_EXTENSION_free(a: ex);
121007 return UA_STATUSCODE_GOOD;
121008}
121009
121010#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
121011
121012/* generate the RSA key */
121013
121014static EVP_PKEY * UA_RSA_Generate_Key (size_t keySizeBits){
121015 return EVP_RSA_gen(keySizeBits);
121016}
121017
121018#endif
121019
121020UA_StatusCode
121021UA_CreateCertificate(const UA_Logger *logger, const UA_String *subject,
121022 size_t subjectSize, const UA_String *subjectAltName,
121023 size_t subjectAltNameSize, UA_CertificateFormat certFormat,
121024 UA_KeyValueMap *params, UA_ByteString *outPrivateKey,
121025 UA_ByteString *outCertificate) {
121026 if(!outPrivateKey || !outCertificate || !logger || !subjectAltName || !subject ||
121027 subjectAltNameSize == 0 || subjectSize == 0 ||
121028 (certFormat != UA_CERTIFICATEFORMAT_DER && certFormat != UA_CERTIFICATEFORMAT_PEM))
121029 return UA_STATUSCODE_BADINVALIDARGUMENT;
121030
121031 /* Use the maximum size */
121032 UA_UInt16 keySizeBits = 4096;
121033 /* Default to 1 year */
121034 UA_UInt16 expiresInDays = 365;
121035
121036 if(params) {
121037 const UA_UInt16 *keySizeBitsValue = (const UA_UInt16 *)UA_KeyValueMap_getScalar(
121038 map: params, key: UA_QUALIFIEDNAME(nsIndex: 0, chars: "key-size-bits"), type: &UA_TYPES[UA_TYPES_UINT16]);
121039 if(keySizeBitsValue)
121040 keySizeBits = *keySizeBitsValue;
121041
121042 const UA_UInt16 *expiresInDaysValue = (const UA_UInt16 *)UA_KeyValueMap_getScalar(
121043 map: params, key: UA_QUALIFIEDNAME(nsIndex: 0, chars: "expires-in-days"), type: &UA_TYPES[UA_TYPES_UINT16]);
121044 if(expiresInDaysValue)
121045 expiresInDays = *expiresInDaysValue;
121046 }
121047
121048 UA_ByteString_init(p: outPrivateKey);
121049 UA_ByteString_init(p: outCertificate);
121050
121051 UA_String fullAltSubj = UA_STRING_NULL;
121052 UA_Int32 serial = 1;
121053
121054 /** \TODO: Seed Random generator
121055 * See: (https://www.openssl.org/docs/man1.1.0/man3/RAND_add.html) */
121056 BIO *memCert = NULL;
121057 BIO *memPKey = NULL;
121058
121059 UA_StatusCode errRet = UA_STATUSCODE_GOOD;
121060
121061 X509 *x509 = X509_new();
121062
121063#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
121064 EVP_PKEY *pkey = UA_RSA_Generate_Key(keySizeBits);
121065 if((pkey == NULL) || (x509 == NULL)) {
121066 errRet = UA_STATUSCODE_BADOUTOFMEMORY;
121067 goto cleanup;
121068 }
121069#else
121070 BIGNUM *exponent = BN_new();
121071 EVP_PKEY *pkey = EVP_PKEY_new();
121072 RSA *rsa = RSA_new();
121073 if(!pkey || !x509 || !exponent || !rsa) {
121074 errRet = UA_STATUSCODE_BADOUTOFMEMORY;
121075 goto cleanup;
121076 }
121077
121078 UA_LOG_INFO(logger, UA_LOGCATEGORY_SECURECHANNEL,
121079 "Create Certificate: Generating RSA key. This may take a while.");
121080
121081 if(BN_set_word(exponent, RSA_F4) != 1) {
121082 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
121083 "Create Certificate: Setting RSA exponent failed.");
121084 errRet = UA_STATUSCODE_BADINTERNALERROR;
121085 goto cleanup;
121086 }
121087
121088 if(RSA_generate_key_ex(rsa, (int) keySizeBits, exponent, NULL) != 1) {
121089 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
121090 "Create Certificate: Generating RSA key failed.");
121091 errRet = UA_STATUSCODE_BADINTERNALERROR;
121092 goto cleanup;
121093 }
121094
121095 if(EVP_PKEY_assign_RSA(pkey, rsa) != 1) {
121096 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SECURECHANNEL,
121097 "Create Certificate: Assign RSA key failed.");
121098 errRet = UA_STATUSCODE_BADINTERNALERROR;
121099 goto cleanup;
121100 }
121101 /* rsa will be freed by pkey */
121102 rsa = NULL;
121103
121104#endif /* end of OPENSSL_VERSION_NUMBER >= 0x30000000L */
121105
121106 /* x509v3 has version 2
121107 * (https://www.openssl.org/docs/man1.1.0/man3/X509_set_version.html) */
121108 if(X509_set_version(x: x509, version: 2) != 1) {
121109 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121110 msg: "Create Certificate: Setting version failed.");
121111 errRet = UA_STATUSCODE_BADINTERNALERROR;
121112 goto cleanup;
121113 }
121114
121115 if(ASN1_INTEGER_set(a: X509_get_serialNumber(x: x509), v: serial) != 1) {
121116 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121117 msg: "Create Certificate: Setting serial number failed.");
121118 /* Only memory errors are possible */
121119 errRet = UA_STATUSCODE_BADOUTOFMEMORY;
121120 goto cleanup;
121121 }
121122
121123 if(X509_gmtime_adj(X509_get_notBefore(x: x509), adj: 0) == NULL) {
121124 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121125 msg: "Create Certificate: Setting 'not before' failed.");
121126 errRet = UA_STATUSCODE_BADINTERNALERROR;
121127 goto cleanup;
121128 }
121129
121130 if(X509_gmtime_adj(X509_get_notAfter(x: x509), adj: (UA_Int64)60 * 60 * 24 * expiresInDays) ==
121131 NULL) {
121132 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121133 msg: "Create Certificate: Setting 'not before' failed.");
121134 errRet = UA_STATUSCODE_BADINTERNALERROR;
121135 goto cleanup;
121136 }
121137
121138 if(X509_set_pubkey(x: x509, pkey) != 1) {
121139 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121140 msg: "Create Certificate: Setting publik key failed.");
121141 errRet = UA_STATUSCODE_BADINTERNALERROR;
121142 goto cleanup;
121143 }
121144
121145 X509_NAME *name = X509_get_subject_name(a: x509);
121146 if(name == NULL) {
121147 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121148 msg: "Create Certificate: Getting name failed.");
121149 errRet = UA_STATUSCODE_BADINTERNALERROR;
121150 goto cleanup;
121151 }
121152
121153 for(UA_UInt32 iSubject = 0; iSubject < subjectSize; ++iSubject) {
121154 UA_Int32 sep = UA_String_chr(pUaStr: &subject[iSubject], needl: '=');
121155 char field[16];
121156 if(sep == -1 || sep == 0 ||
121157 ((size_t) sep == (subject[iSubject].length - 1)) || sep >= 15) {
121158 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121159 msg: "Create Certificate: Subject must contain one '=' with "
121160 "content before and after.");
121161 errRet = UA_STATUSCODE_BADINTERNALERROR;
121162 goto cleanup;
121163 }
121164 memcpy(dest: field, src: subject[iSubject].data, n: (size_t) sep);
121165 field[sep] = 0;
121166 UA_Byte* pData = &subject[iSubject].data[sep + 1];
121167 if(X509_NAME_add_entry_by_txt(
121168 name, field, MBSTRING_ASC,
121169 bytes: (const unsigned char *)pData,
121170 len: (int) subject[iSubject].length - (int) sep - 1, loc: -1, set: 0) != 1) {
121171 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121172 msg: "Create Certificate: Setting subject failed.");
121173 errRet = UA_STATUSCODE_BADINTERNALERROR;
121174 goto cleanup;
121175 }
121176 }
121177 /* Self signed, so issuer == subject */
121178 if(X509_set_issuer_name(x: x509, name) != 1) {
121179 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121180 msg: "Create Certificate: Setting name failed.");
121181 errRet = UA_STATUSCODE_BADINTERNALERROR;
121182 goto cleanup;
121183 }
121184
121185 errRet = add_x509V3ext(logger, x509, NID_basic_constraints, value: "CA:FALSE");
121186 if(errRet != UA_STATUSCODE_GOOD) {
121187 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121188 msg: "Create Certificate: Setting 'Basic Constraints' failed.");
121189 goto cleanup;
121190 }
121191
121192 /* See https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.3 for
121193 * possible values */
121194 errRet = add_x509V3ext(logger, x509, NID_key_usage,
121195 value: "digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyCertSign");
121196 if(errRet != UA_STATUSCODE_GOOD) {
121197 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121198 msg: "Create Certificate: Setting 'Key Usage' failed.");
121199 goto cleanup;
121200 }
121201
121202 errRet = add_x509V3ext(logger, x509, NID_ext_key_usage, value: "serverAuth,clientAuth");
121203 if(errRet != UA_STATUSCODE_GOOD) {
121204 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121205 msg: "Create Certificate: Setting 'Extended Key Usage' failed.");
121206 goto cleanup;
121207 }
121208
121209 errRet = add_x509V3ext(logger, x509, NID_subject_key_identifier, value: "hash");
121210 if(errRet != UA_STATUSCODE_GOOD) {
121211 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121212 msg: "Create Certificate: Setting 'Subject Key Identifier' failed.");
121213 goto cleanup;
121214 }
121215
121216 errRet = join_string_with_sep(strings: subjectAltName, stringsSize: subjectAltNameSize, sep: ',', out: &fullAltSubj);
121217 if(errRet != UA_STATUSCODE_GOOD) {
121218 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121219 msg: "Create Certificate: Joining altSubject failed.");
121220 goto cleanup;
121221 }
121222
121223 errRet = add_x509V3ext(logger, x509, NID_subject_alt_name, value: (char*) fullAltSubj.data);
121224 if(errRet != UA_STATUSCODE_GOOD) {
121225 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121226 msg: "Create Certificate: Setting 'Subject Alternative Name' failed.");
121227 goto cleanup;
121228 }
121229
121230 if(X509_sign(x: x509, pkey, md: EVP_sha256()) == 0) {
121231 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121232 msg: "Create Certificate: Signing failed.");
121233 errRet = UA_STATUSCODE_BADINTERNALERROR;
121234 goto cleanup;
121235 }
121236
121237 switch(certFormat) {
121238 case UA_CERTIFICATEFORMAT_DER: {
121239 unsigned char *p;
121240 /* Private Key */
121241 /* get length */
121242 outPrivateKey->length = (size_t)i2d_PrivateKey(a: pkey, NULL);
121243 if((int)outPrivateKey->length <= 0) {
121244 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121245 msg: "Create Certificate: Create private DER key failed.");
121246 errRet = UA_STATUSCODE_BADINTERNALERROR;
121247 goto cleanup;
121248 }
121249 /* allocate buffer */
121250 UA_ByteString_allocBuffer(bs: outPrivateKey, length: outPrivateKey->length);
121251 memset(s: outPrivateKey->data, c: 0, n: outPrivateKey->length);
121252 p = outPrivateKey->data;
121253 i2d_PrivateKey(a: pkey, pp: &p);
121254
121255 /* Certificate */
121256 /* get length */
121257 outCertificate->length = (size_t)i2d_X509(a: x509, NULL);
121258 if((int)outCertificate->length <= 0) {
121259 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121260 msg: "Create Certificate: Create DER-certificate failed.");
121261 errRet = UA_STATUSCODE_BADINTERNALERROR;
121262 goto cleanup;
121263 }
121264 /* allocate buffer */
121265 UA_ByteString_allocBuffer(bs: outCertificate, length: outCertificate->length);
121266 memset(s: outCertificate->data, c: 0, n: outCertificate->length);
121267 p = outCertificate->data;
121268 i2d_X509(a: x509, out: &p);
121269 break;
121270 }
121271 case UA_CERTIFICATEFORMAT_PEM: {
121272 /* Private Key */
121273 memPKey = BIO_new(type: BIO_s_mem());
121274 if(!memPKey) {
121275 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121276 msg: "Create Certificate: Allocate Membuffer for PKey failed.");
121277 errRet = UA_STATUSCODE_BADOUTOFMEMORY;
121278 goto cleanup;
121279 }
121280
121281 if(PEM_write_bio_PrivateKey(out: memPKey, x: pkey, NULL, NULL, klen: 0, cb: 0, NULL) != 1) {
121282 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121283 msg: "Create Certificate: Generate PEM-PrivateKey failed.");
121284 errRet = UA_STATUSCODE_BADINTERNALERROR;
121285 goto cleanup;
121286 }
121287
121288 UA_ByteString tmpPem = UA_BYTESTRING_NULL;
121289 tmpPem.length = (size_t) BIO_get_mem_data(memPKey, &tmpPem.data);
121290 errRet = UA_ByteString_copy(src: &tmpPem, dst: outPrivateKey);
121291 if(errRet != UA_STATUSCODE_GOOD) {
121292 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121293 msg: "Create Certificate: Copy PEM PKey failed.");
121294 goto cleanup;
121295 }
121296
121297 /* Certificate */
121298 memCert = BIO_new(type: BIO_s_mem());
121299 if(!memCert) {
121300 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121301 msg: "Create Certificate: Allocate Membuffer for Cert failed.");
121302 errRet = UA_STATUSCODE_BADOUTOFMEMORY;
121303 goto cleanup;
121304 }
121305
121306 if(PEM_write_bio_X509(out: memCert, x: x509) != 1) {
121307 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121308 msg: "Create Certificate: Generate PEM-Certifcate failed.");
121309 errRet = UA_STATUSCODE_BADINTERNALERROR;
121310 goto cleanup;
121311 }
121312
121313 tmpPem.length = (size_t) BIO_get_mem_data(memCert, &tmpPem.data);
121314 errRet = UA_ByteString_copy(src: &tmpPem, dst: outCertificate);
121315 if(errRet != UA_STATUSCODE_GOOD) {
121316 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SECURECHANNEL,
121317 msg: "Create Certificate: Copy PEM Certificate failed.");
121318 goto cleanup;
121319 }
121320 break;
121321 }
121322 }
121323
121324cleanup:
121325 UA_String_clear(p: &fullAltSubj);
121326#if (OPENSSL_VERSION_NUMBER < 0x30000000L)
121327 RSA_free(rsa);
121328 BN_free(exponent);
121329#endif
121330 X509_free(a: x509);
121331 EVP_PKEY_free(pkey);
121332 BIO_free(a: memCert);
121333 BIO_free(a: memPKey);
121334 return errRet;
121335}
121336
121337#endif
121338
121339/**** amalgamated original file "/plugins/crypto/openssl/ua_pki_openssl.c" ****/
121340
121341/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
121342 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
121343 *
121344 * Copyright 2020 (c) Wind River Systems, Inc.
121345 * Copyright 2020 (c) basysKom GmbH
121346
121347 */
121348
121349
121350
121351#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL)
121352#include <openssl/x509.h>
121353#include <openssl/x509_vfy.h>
121354#include <openssl/x509v3.h>
121355#include <openssl/pem.h>
121356
121357
121358#include <limits.h>
121359
121360/* Find binary substring. Taken and adjusted from
121361 * http://tungchingkai.blogspot.com/2011/07/binary-strstr.html */
121362
121363static const unsigned char *
121364bstrchr(const unsigned char *s, const unsigned char ch, size_t l) {
121365 /* find first occurrence of c in char s[] for length l*/
121366 for(; l > 0; ++s, --l) {
121367 if(*s == ch)
121368 return s;
121369 }
121370 return NULL;
121371}
121372
121373static const unsigned char *
121374UA_Bstrstr(const unsigned char *s1, size_t l1, const unsigned char *s2, size_t l2) {
121375 /* find first occurrence of s2[] in s1[] for length l1*/
121376 const unsigned char *ss1 = s1;
121377 const unsigned char *ss2 = s2;
121378 /* handle special case */
121379 if(l1 == 0)
121380 return (NULL);
121381 if(l2 == 0)
121382 return s1;
121383
121384 /* match prefix */
121385 for (; (s1 = bstrchr(s: s1, ch: *s2, l: (uintptr_t)ss1-(uintptr_t)s1+(uintptr_t)l1)) != NULL &&
121386 (uintptr_t)ss1-(uintptr_t)s1+(uintptr_t)l1 != 0; ++s1) {
121387
121388 /* match rest of prefix */
121389 const unsigned char *sc1, *sc2;
121390 for (sc1 = s1, sc2 = s2; ;)
121391 if (++sc2 >= ss2+l2)
121392 return s1;
121393 else if (*++sc1 != *sc2)
121394 break;
121395 }
121396 return NULL;
121397}
121398
121399typedef struct {
121400 /*
121401 * If the folders are defined, we use them to reload the certificates during
121402 * runtime
121403 */
121404
121405 UA_String trustListFolder;
121406 UA_String issuerListFolder;
121407 UA_String revocationListFolder;
121408 /* Used with mbedTLS and UA_ENABLE_CERT_REJECTED_DIR option */
121409 UA_String rejectedListFolder;
121410
121411 STACK_OF(X509) * skIssue;
121412 STACK_OF(X509) * skTrusted;
121413 STACK_OF(X509_CRL) * skCrls; /* Revocation list*/
121414
121415 UA_CertificateVerification *cv;
121416} CertContext;
121417
121418static UA_StatusCode
121419UA_CertContext_sk_Init (CertContext * context) {
121420 context->skTrusted = sk_X509_new_null();
121421 context->skIssue = sk_X509_new_null();
121422 context->skCrls = sk_X509_CRL_new_null();
121423 if (context->skTrusted == NULL || context->skIssue == NULL ||
121424 context->skCrls == NULL) {
121425 return UA_STATUSCODE_BADOUTOFMEMORY;
121426 }
121427 return UA_STATUSCODE_GOOD;
121428}
121429
121430static void
121431UA_CertContext_sk_free (CertContext * context) {
121432 sk_X509_pop_free (context->skTrusted, X509_free);
121433 sk_X509_pop_free (context->skIssue, X509_free);
121434 sk_X509_CRL_pop_free (context->skCrls, X509_CRL_free);
121435}
121436
121437static UA_StatusCode
121438UA_CertContext_Init (CertContext * context, UA_CertificateVerification *cv) {
121439 (void) memset (s: context, c: 0, n: sizeof (CertContext));
121440 UA_ByteString_init (p: &context->trustListFolder);
121441 UA_ByteString_init (p: &context->issuerListFolder);
121442 UA_ByteString_init (p: &context->revocationListFolder);
121443 UA_ByteString_init (p: &context->rejectedListFolder);
121444
121445 context->cv = cv;
121446
121447 return UA_CertContext_sk_Init (context);
121448}
121449
121450static void
121451UA_CertificateVerification_clear (UA_CertificateVerification * cv) {
121452 if (cv == NULL) {
121453 return;
121454 }
121455 CertContext * context = (CertContext *) cv->context;
121456 if (context == NULL) {
121457 return;
121458 }
121459 UA_ByteString_clear (p: &context->trustListFolder);
121460 UA_ByteString_clear (p: &context->issuerListFolder);
121461 UA_ByteString_clear (p: &context->revocationListFolder);
121462 UA_ByteString_clear (p: &context->rejectedListFolder);
121463
121464 UA_CertContext_sk_free (context);
121465 context->cv = NULL;
121466 UA_free (ptr: context);
121467
121468 memset(s: cv, c: 0, n: sizeof(UA_CertificateVerification));
121469}
121470
121471static UA_StatusCode
121472UA_skTrusted_Cert2X509 (const UA_ByteString * certificateTrustList,
121473 size_t certificateTrustListSize,
121474 CertContext * ctx) {
121475 size_t i;
121476
121477 for (i = 0; i < certificateTrustListSize; i++) {
121478 X509 * x509 = UA_OpenSSL_LoadCertificate(certificate: &certificateTrustList[i]);
121479
121480 if (x509 == NULL) {
121481 return UA_STATUSCODE_BADINTERNALERROR;
121482 }
121483 sk_X509_push (ctx->skTrusted, x509);
121484 }
121485
121486 return UA_STATUSCODE_GOOD;
121487}
121488
121489static UA_StatusCode
121490UA_skIssuer_Cert2X509 (const UA_ByteString * certificateIssuerList,
121491 size_t certificateIssuerListSize,
121492 CertContext * ctx) {
121493 size_t i;
121494
121495 for (i = 0; i < certificateIssuerListSize; i++) {
121496 X509 * x509 = UA_OpenSSL_LoadCertificate(certificate: &certificateIssuerList[i]);
121497
121498 if (x509 == NULL) {
121499 return UA_STATUSCODE_BADINTERNALERROR;
121500 }
121501 sk_X509_push (ctx->skIssue, x509);
121502 }
121503
121504 return UA_STATUSCODE_GOOD;
121505}
121506
121507static UA_StatusCode
121508UA_skCrls_Cert2X509 (const UA_ByteString * certificateRevocationList,
121509 size_t certificateRevocationListSize,
121510 CertContext * ctx) {
121511 size_t i;
121512 const unsigned char * pData;
121513
121514 for (i = 0; i < certificateRevocationListSize; i++) {
121515 pData = certificateRevocationList[i].data;
121516 X509_CRL * crl = NULL;
121517
121518 if (certificateRevocationList[i].length > 1 && pData[0] == 0x30 && pData[1] == 0x82) { // Magic number for DER encoded files
121519 crl = d2i_X509_CRL (NULL, in: &pData, len: (long) certificateRevocationList[i].length);
121520 } else {
121521 BIO* bio = NULL;
121522 bio = BIO_new_mem_buf(buf: (void *) certificateRevocationList[i].data,
121523 len: (int) certificateRevocationList[i].length);
121524 crl = PEM_read_bio_X509_CRL(out: bio, NULL, NULL, NULL);
121525 BIO_free(a: bio);
121526 }
121527
121528 if (crl == NULL) {
121529 return UA_STATUSCODE_BADINTERNALERROR;
121530 }
121531 sk_X509_CRL_push (ctx->skCrls, crl);
121532 }
121533
121534 return UA_STATUSCODE_GOOD;
121535}
121536
121537#ifdef __linux__
121538#include <dirent.h>
121539
121540static int UA_Certificate_Filter_der_pem (const struct dirent * entry) {
121541 /* ignore hidden files */
121542 if (entry->d_name[0] == '.') return 0;
121543
121544 /* check file extension */
121545 const char *pszFind = strrchr(s: entry->d_name, c: '.');
121546 if (pszFind == 0)
121547 return 0;
121548 pszFind++;
121549 if (strcmp (s1: pszFind, s2: "der") == 0 || strcmp (s1: pszFind, s2: "pem") == 0)
121550 return 1;
121551
121552 return 0;
121553}
121554
121555static int UA_Certificate_Filter_crl (const struct dirent * entry) {
121556
121557 /* ignore hidden files */
121558 if (entry->d_name[0] == '.') return 0;
121559
121560 /* check file extension */
121561 const char *pszFind = strrchr(s: entry->d_name, c: '.');
121562 if (pszFind == 0)
121563 return 0;
121564 pszFind++;
121565 if (strcmp (s1: pszFind, s2: "crl") == 0)
121566 return 1;
121567
121568 return 0;
121569}
121570
121571static UA_StatusCode
121572UA_BuildFullPath (const char * path,
121573 const char * fileName,
121574 size_t fullPathBufferLength,
121575 char * fullPath) {
121576 size_t pathLen = strlen (s: path);
121577 size_t fileNameLen = strlen (s: fileName);
121578 if ((pathLen + fileNameLen + 2) > fullPathBufferLength) {
121579 return UA_STATUSCODE_BADINVALIDARGUMENT;
121580 }
121581 strcpy (dest: fullPath, src: path);
121582 strcat (dest: fullPath, src: "/");
121583 strcat (dest: fullPath, src: fileName);
121584
121585 return UA_STATUSCODE_GOOD;
121586}
121587
121588static UA_StatusCode
121589UA_loadCertFromFile (const char * fileName,
121590 UA_ByteString * cert) {
121591
121592 FILE * fp = fopen(filename: fileName, modes: "rb");
121593
121594 if (fp == NULL)
121595 return UA_STATUSCODE_BADINTERNALERROR;
121596
121597 fseek(stream: fp, off: 0, SEEK_END);
121598 cert->length = (size_t) ftell(stream: fp);
121599 if (UA_ByteString_allocBuffer (bs: cert, length: cert->length) != UA_STATUSCODE_GOOD) {
121600 fclose (stream: fp);
121601 return UA_STATUSCODE_BADOUTOFMEMORY;
121602 }
121603 fseek(stream: fp, off: 0, SEEK_SET);
121604 size_t readLen = fread (ptr: cert->data, size: 1, n: cert->length, stream: fp);
121605 if (readLen != cert->length) {
121606 UA_ByteString_clear (p: cert);
121607 cert->length = 0;
121608 fclose (stream: fp);
121609 return UA_STATUSCODE_BADINTERNALERROR;
121610 }
121611 fclose (stream: fp);
121612
121613 return UA_STATUSCODE_GOOD;
121614}
121615
121616static UA_StatusCode
121617UA_ReloadCertFromFolder (CertContext * ctx) {
121618 UA_StatusCode ret;
121619 struct dirent ** dirlist = NULL;
121620 int i;
121621 int numCertificates;
121622 char certFile[PATH_MAX];
121623 UA_ByteString strCert;
121624 char folderPath[PATH_MAX];
121625
121626 UA_ByteString_init (p: &strCert);
121627
121628 if (ctx->trustListFolder.length > 0) {
121629 UA_LOG_INFO(logger: ctx->cv->logging, category: UA_LOGCATEGORY_SERVER, msg: "Reloading the trust-list");
121630
121631 sk_X509_pop_free (ctx->skTrusted, X509_free);
121632 ctx->skTrusted = sk_X509_new_null();
121633 if (ctx->skTrusted == NULL) {
121634 return UA_STATUSCODE_BADOUTOFMEMORY;
121635 }
121636
121637 (void) memcpy (dest: folderPath, src: ctx->trustListFolder.data,
121638 n: ctx->trustListFolder.length);
121639 folderPath[ctx->trustListFolder.length] = 0;
121640 numCertificates = scandir(dir: folderPath, namelist: &dirlist,
121641 selector: UA_Certificate_Filter_der_pem,
121642 cmp: alphasort);
121643 for (i = 0; i < numCertificates; i++) {
121644 if (UA_BuildFullPath (path: folderPath, fileName: dirlist[i]->d_name,
121645 PATH_MAX, fullPath: certFile) != UA_STATUSCODE_GOOD) {
121646 continue;
121647 }
121648 ret = UA_loadCertFromFile (fileName: certFile, cert: &strCert);
121649 if (ret != UA_STATUSCODE_GOOD) {
121650 UA_LOG_INFO(logger: ctx->cv->logging, category: UA_LOGCATEGORY_SERVER,
121651 msg: "Failed to load the certificate file %s", certFile);
121652 continue; /* continue or return ? */
121653 }
121654 if (UA_skTrusted_Cert2X509 (certificateTrustList: &strCert, certificateTrustListSize: 1, ctx) != UA_STATUSCODE_GOOD) {
121655 UA_LOG_INFO (logger: ctx->cv->logging, category: UA_LOGCATEGORY_SERVER,
121656 msg: "Failed to decode the certificate file %s", certFile);
121657 UA_ByteString_clear (p: &strCert);
121658 continue; /* continue or return ? */
121659 }
121660 UA_ByteString_clear (p: &strCert);
121661 }
121662 for (i = 0; i < numCertificates; i++) {
121663 free(ptr: dirlist[i]);
121664 }
121665 free(ptr: dirlist);
121666 }
121667
121668 if (ctx->issuerListFolder.length > 0) {
121669 UA_LOG_INFO(logger: ctx->cv->logging, category: UA_LOGCATEGORY_SERVER, msg: "Reloading the issuer-list");
121670
121671 sk_X509_pop_free (ctx->skIssue, X509_free);
121672 ctx->skIssue = sk_X509_new_null();
121673 if (ctx->skIssue == NULL) {
121674 return UA_STATUSCODE_BADOUTOFMEMORY;
121675 }
121676
121677 memcpy (dest: folderPath, src: ctx->issuerListFolder.data, n: ctx->issuerListFolder.length);
121678 folderPath[ctx->issuerListFolder.length] = 0;
121679 numCertificates = scandir(dir: folderPath, namelist: &dirlist,
121680 selector: UA_Certificate_Filter_der_pem,
121681 cmp: alphasort);
121682 for (i = 0; i < numCertificates; i++) {
121683 if (UA_BuildFullPath (path: folderPath, fileName: dirlist[i]->d_name,
121684 PATH_MAX, fullPath: certFile) != UA_STATUSCODE_GOOD) {
121685 continue;
121686 }
121687 ret = UA_loadCertFromFile (fileName: certFile, cert: &strCert);
121688 if (ret != UA_STATUSCODE_GOOD) {
121689 UA_LOG_INFO (logger: ctx->cv->logging, category: UA_LOGCATEGORY_SERVER,
121690 msg: "Failed to load the certificate file %s", certFile);
121691 continue; /* continue or return ? */
121692 }
121693 if (UA_skIssuer_Cert2X509 (certificateIssuerList: &strCert, certificateIssuerListSize: 1, ctx) != UA_STATUSCODE_GOOD) {
121694 UA_LOG_INFO (logger: ctx->cv->logging, category: UA_LOGCATEGORY_SERVER,
121695 msg: "Failed to decode the certificate file %s", certFile);
121696 UA_ByteString_clear (p: &strCert);
121697 continue; /* continue or return ? */
121698 }
121699 UA_ByteString_clear (p: &strCert);
121700 }
121701 for (i = 0; i < numCertificates; i++) {
121702 free(ptr: dirlist[i]);
121703 }
121704 free(ptr: dirlist);
121705 }
121706
121707 if (ctx->revocationListFolder.length > 0) {
121708 UA_LOG_INFO(logger: ctx->cv->logging, category: UA_LOGCATEGORY_SERVER, msg: "Reloading the revocation-list");
121709
121710 sk_X509_CRL_pop_free (ctx->skCrls, X509_CRL_free);
121711 ctx->skCrls = sk_X509_CRL_new_null();
121712 if (ctx->skCrls == NULL) {
121713 return UA_STATUSCODE_BADOUTOFMEMORY;
121714 }
121715
121716 memcpy (dest: folderPath, src: ctx->revocationListFolder.data, n: ctx->revocationListFolder.length);
121717 folderPath[ctx->revocationListFolder.length] = 0;
121718 numCertificates = scandir(dir: folderPath, namelist: &dirlist,
121719 selector: UA_Certificate_Filter_crl,
121720 cmp: alphasort);
121721 for (i = 0; i < numCertificates; i++) {
121722 if (UA_BuildFullPath (path: folderPath, fileName: dirlist[i]->d_name,
121723 PATH_MAX, fullPath: certFile) != UA_STATUSCODE_GOOD) {
121724 continue;
121725 }
121726 ret = UA_loadCertFromFile (fileName: certFile, cert: &strCert);
121727 if (ret != UA_STATUSCODE_GOOD) {
121728 UA_LOG_INFO (logger: ctx->cv->logging, category: UA_LOGCATEGORY_SERVER,
121729 msg: "Failed to load the revocation file %s", certFile);
121730 continue; /* continue or return ? */
121731 }
121732 if (UA_skCrls_Cert2X509 (certificateRevocationList: &strCert, certificateRevocationListSize: 1, ctx) != UA_STATUSCODE_GOOD) {
121733 UA_LOG_INFO (logger: ctx->cv->logging, category: UA_LOGCATEGORY_SERVER,
121734 msg: "Failed to decode the revocation file %s", certFile);
121735 UA_ByteString_clear (p: &strCert);
121736 continue; /* continue or return ? */
121737 }
121738 UA_ByteString_clear (p: &strCert);
121739 }
121740 for (i = 0; i < numCertificates; i++) {
121741 free(ptr: dirlist[i]);
121742 }
121743 free(ptr: dirlist);
121744 }
121745
121746 ret = UA_STATUSCODE_GOOD;
121747 return ret;
121748}
121749
121750#endif /* end of __linux__ */
121751
121752static const unsigned char openssl_PEM_PRE[28] = "-----BEGIN CERTIFICATE-----";
121753
121754/* Extract the leaf certificate from a bytestring that may contain an entire chain */
121755static X509 *
121756openSSLLoadLeafCertificate(UA_ByteString cert, size_t *offset) {
121757 if(cert.length <= *offset)
121758 return NULL;
121759 cert.length -= *offset;
121760 cert.data += *offset;
121761
121762 /* Detect DER encoding. Extract the encoding length and cut. */
121763 if(cert.length >= 4 && cert.data[0] == 0x30 && cert.data[1] == 0x82) {
121764 /* The certificate length is encoded after the magic bytes */
121765 size_t certLen = 4; /* Magic numbers + length bytes */
121766 certLen += (size_t)(((uint16_t)cert.data[2]) << 8);
121767 certLen += cert.data[3];
121768 if(certLen > cert.length)
121769 return NULL;
121770 cert.length = certLen;
121771 *offset += certLen;
121772 const UA_Byte *dataPtr = cert.data;
121773 return d2i_X509(NULL, in: &dataPtr, len: (long)cert.length);
121774 }
121775
121776 /* Assume PEM encoding. Detect multiple certificates and cut. */
121777 if(cert.length > 27 * 4) {
121778 const unsigned char *match =
121779 UA_Bstrstr(s1: openssl_PEM_PRE, l1: 27, s2: &cert.data[27*2], l2: cert.length - (27*2));
121780 if(match)
121781 cert.length = (uintptr_t)(match - cert.data);
121782 }
121783 *offset += cert.length;
121784
121785 BIO *bio = BIO_new_mem_buf(buf: (void *) cert.data, len: (int)cert.length);
121786 X509 *result = PEM_read_bio_X509(out: bio, NULL, NULL, NULL);
121787 BIO_free(a: bio);
121788 return result;
121789}
121790
121791/* The bytestring might contain an entire certificate chain. The first
121792 * stack-element is the leaf certificate itself. The remaining ones are
121793 * potential issuer certificates. */
121794static STACK_OF(X509) *
121795openSSLLoadCertificateStack(const UA_ByteString cert) {
121796 size_t offset = 0;
121797 X509 *x509 = NULL;
121798 STACK_OF(X509) *result = sk_X509_new_null();
121799 if(!result)
121800 return NULL;
121801 while((x509 = openSSLLoadLeafCertificate(cert, offset: &offset))) {
121802 sk_X509_push(result, x509);
121803 }
121804 return result;
121805}
121806
121807/* Return the first matching issuer candidate AFTER prev */
121808static X509 *
121809openSSLFindNextIssuer(CertContext *ctx, STACK_OF(X509) *stack, X509 *x509, X509 *prev) {
121810 /* First check issuers from the stack - provided in the same bytestring as
121811 * the certificate. This can also return x509 itself. */
121812 X509_NAME *in = X509_get_issuer_name(a: x509);
121813 do {
121814 int size = sk_X509_num(stack);
121815 for(int i = 0; i < size; i++) {
121816 X509 *candidate = sk_X509_value(stack, i);
121817 if(prev) {
121818 if(prev == candidate)
121819 prev = NULL; /* This was the last issuer we tried to verify */
121820 continue;
121821 }
121822 /* This checks subject/issuer name and the key usage of the issuer.
121823 * It does not verify the validity period and if the issuer key was
121824 * used for the signature. We check that afterwards. */
121825 if(X509_NAME_cmp(a: in, b: X509_get_subject_name(a: candidate)) == 0)
121826 return candidate;
121827 }
121828 /* Switch from the stack that came with the cert to the issuer list and
121829 * then to the trust list. */
121830 if(stack == ctx->skTrusted)
121831 stack = NULL;
121832 else if(stack == ctx->skIssue)
121833 stack = ctx->skTrusted;
121834 else
121835 stack = ctx->skIssue;
121836 } while(stack);
121837 return NULL;
121838}
121839
121840/* Is the certificate a CA? */
121841static UA_Boolean
121842openSSLCheckCA(X509 *cert) {
121843 uint32_t flags = X509_get_extension_flags(x: cert);
121844 /* The basic constraints must be set with the CA flag true */
121845 if(!(flags & EXFLAG_CA))
121846 return false;
121847
121848 /* The Key Usage extension must be set */
121849 if(!(flags & EXFLAG_KUSAGE))
121850 return false;
121851
121852 /* The Key Usage must include cert signing and CRL issuing */
121853 uint32_t usage = X509_get_key_usage(x: cert);
121854 if(!(usage & KU_KEY_CERT_SIGN) || !(usage & KU_CRL_SIGN))
121855 return false;
121856
121857 return true;
121858}
121859
121860static UA_StatusCode
121861openSSLCheckRevoked(CertContext *ctx, X509 *cert) {
121862 const ASN1_INTEGER *sn = X509_get0_serialNumber(x: cert);
121863 const X509_NAME *in = X509_get_issuer_name(a: cert);
121864 int size = sk_X509_CRL_num(ctx->skCrls);
121865
121866 if(size == 0) {
121867 UA_LOG_WARNING(logger: ctx->cv->logging, category: UA_LOGCATEGORY_SECURITYPOLICY,
121868 msg: "Zero revocation lists have been loaded. "
121869 "This seems intentional - omitting the check.");
121870 return UA_STATUSCODE_GOOD;
121871 }
121872
121873 /* Loop over the crl and match the Issuer Name */
121874 UA_StatusCode res = UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN;
121875 for(int i = 0; i < size; i++) {
121876 /* The crl contains a list of serial numbers from the same issuer */
121877 X509_CRL *crl = sk_X509_CRL_value(ctx->skCrls, i);
121878 if(X509_NAME_cmp(a: in, b: X509_CRL_get_issuer(crl)) != 0)
121879 continue;
121880 STACK_OF(X509_REVOKED) *rs = X509_CRL_get_REVOKED(crl);
121881 int rsize = sk_X509_REVOKED_num(rs);
121882 for(int j = 0; j < rsize; j++) {
121883 X509_REVOKED *r = sk_X509_REVOKED_value(rs, j);
121884 if(ASN1_INTEGER_cmp(x: sn, y: X509_REVOKED_get0_serialNumber(x: r)) == 0)
121885 return UA_STATUSCODE_BADCERTIFICATEREVOKED;
121886 }
121887 res = UA_STATUSCODE_GOOD; /* There was at least one crl that did not revoke (so far) */
121888 }
121889 return res;
121890}
121891
121892#define UA_OPENSSL_MAX_CHAIN_LENGTH 10
121893
121894static UA_StatusCode
121895openSSL_verifyChain(CertContext *ctx, STACK_OF(X509) *stack, X509 **old_issuers,
121896 X509 *cert, int depth) {
121897 /* Maxiumum chain length */
121898 if(depth == UA_OPENSSL_MAX_CHAIN_LENGTH)
121899 return UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE;
121900
121901 /* Verification Step: Validity Period */
121902 ASN1_TIME *notBefore = X509_get_notBefore(x: cert);
121903 ASN1_TIME *notAfter = X509_get_notAfter(x: cert);
121904 if(X509_cmp_current_time(s: notBefore) != -1 || X509_cmp_current_time(s: notAfter) != 1)
121905 return (depth == 0) ? UA_STATUSCODE_BADCERTIFICATETIMEINVALID :
121906 UA_STATUSCODE_BADCERTIFICATEISSUERTIMEINVALID;
121907
121908 /* Return the most specific error code. BADCERTIFICATECHAININCOMPLETE is
121909 * returned only if all possible chains are incomplete. */
121910 X509 *issuer = NULL;
121911 UA_StatusCode ret = UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE;
121912 while(ret != UA_STATUSCODE_GOOD) {
121913 /* Find the issuer. We jump back here to find a different path if a
121914 * subsequent check fails. */
121915 issuer = openSSLFindNextIssuer(ctx, stack, x509: cert, prev: issuer);
121916 if(!issuer)
121917 break;
121918
121919 /* Verification Step: Certificate Usage
121920 * Can the issuer act as CA? Omit for self-signed leaf certificates. */
121921 if((depth > 0 || issuer != cert) && !openSSLCheckCA(cert: issuer)) {
121922 ret = UA_STATUSCODE_BADCERTIFICATEISSUERUSENOTALLOWED;
121923 continue;
121924 }
121925
121926 /* Verification Step: Signature */
121927 int opensslRet = X509_verify(a: cert, r: X509_get0_pubkey(x: issuer));
121928 if(opensslRet == -1) {
121929 return UA_STATUSCODE_BADCERTIFICATEINVALID; /* Ill-formed signature */
121930 } else if(opensslRet == 0) {
121931 ret = UA_STATUSCODE_BADCERTIFICATEINVALID; /* Wrong issuer, try again */
121932 continue;
121933 }
121934
121935 /* The certificate is self-signed. We have arrived at the top of the
121936 * chain. We check whether the certificate is trusted below. This is the
121937 * only place where we return UA_STATUSCODE_BADCERTIFICATEUNTRUSTED.
121938 * This signals that the chain is complete (but can be still
121939 * untrusted).
121940 *
121941 * Break here as we have reached the end of the chain. Omit the
121942 * Revocation Check for self-signed certificates. */
121943 if(cert == issuer || X509_cmp(a: cert, b: issuer) == 0) {
121944 ret = UA_STATUSCODE_BADCERTIFICATEUNTRUSTED;
121945 break;
121946 }
121947
121948 /* Verification Step: Revocation Check */
121949 ret = openSSLCheckRevoked(ctx, cert);
121950 if(depth > 0) {
121951 if(ret == UA_STATUSCODE_BADCERTIFICATEREVOKED)
121952 ret = UA_STATUSCODE_BADCERTIFICATEISSUERREVOKED;
121953 if(ret == UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN)
121954 ret = UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN;
121955 }
121956 if(ret != UA_STATUSCODE_GOOD)
121957 continue;
121958
121959 /* Detect (endless) loops of issuers. The last one can be skipped by the
121960 * check for self-signed just before. */
121961 for(int i = 0; i < depth; i++) {
121962 if(old_issuers[i] == issuer)
121963 return UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE;
121964 }
121965 old_issuers[depth] = issuer;
121966
121967 /* We have found the issuer certificate used for the signature. Recurse
121968 * to the next certificate in the chain (verify the current issuer). */
121969 ret = openSSL_verifyChain(ctx, stack, old_issuers, cert: issuer, depth: depth + 1);
121970 }
121971
121972 /* Is the certificate in the trust list? If yes, then we are done. */
121973 if(ret == UA_STATUSCODE_BADCERTIFICATEUNTRUSTED) {
121974 for(int i = 0; i < sk_X509_num(ctx->skTrusted); i++) {
121975 if(X509_cmp(a: cert, sk_X509_value(ctx->skTrusted, i)) == 0)
121976 return UA_STATUSCODE_GOOD;
121977 }
121978 }
121979
121980 return ret;
121981}
121982
121983/* This follows Part 6, 6.1.3 Determining if a Certificate is trusted.
121984 * It defines a sequence of steps for certificate verification. */
121985static UA_StatusCode
121986UA_CertificateVerification_Verify(const UA_CertificateVerification *cv,
121987 const UA_ByteString *certificate) {
121988 if(!cv || !certificate)
121989 return UA_STATUSCODE_BADINTERNALERROR;
121990
121991 UA_StatusCode ret = UA_STATUSCODE_GOOD;
121992 CertContext *ctx = (CertContext *)cv->context;
121993 X509 *old_issuers[UA_OPENSSL_MAX_CHAIN_LENGTH];
121994
121995#ifdef __linux__
121996 ret = UA_ReloadCertFromFolder(ctx);
121997 if(ret != UA_STATUSCODE_GOOD)
121998 return ret;
121999#endif
122000
122001 /* Verification Step: Certificate Structure */
122002 STACK_OF(X509) *stack = openSSLLoadCertificateStack(cert: *certificate);
122003 if(!stack || sk_X509_num(stack) < 1) {
122004 ret = UA_STATUSCODE_BADCERTIFICATEINVALID;
122005 goto errout;
122006 }
122007
122008 /* Verification Step: Certificate Usage
122009 * Check whether the certificate is a User certificate or a CA certificate.
122010 * Refer the test case CTT/Security/Security Certificate Validation/029.js
122011 * for more details. */
122012 X509 *leaf = sk_X509_value(stack, 0);
122013 if(openSSLCheckCA(cert: leaf)) {
122014 ret = UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED;
122015 goto errout;
122016 }
122017
122018 /* These steps are performed outside of this method.
122019 * Because we need the server or client context.
122020 * - Security Policy
122021 * - Host Name
122022 * - URI */
122023
122024 /* Verification Step: Build Certificate Chain
122025 * We perform the checks for each certificate inside. */
122026 ret = openSSL_verifyChain(ctx, stack, old_issuers, cert: leaf, depth: 0);
122027
122028 errout:
122029 if(stack)
122030 sk_X509_pop_free(stack, X509_free);
122031
122032#ifdef UA_ENABLE_CERT_REJECTED_DIR
122033 if(ret != UA_STATUSCODE_GOOD &&
122034 ctx->rejectedListFolder.length > 0) {
122035 char rejectedFileName[256] = {0};
122036 UA_ByteString thumbprint;
122037 UA_ByteString_allocBuffer(&thumbprint, UA_SHA1_LENGTH);
122038 if(UA_Openssl_X509_GetCertificateThumbprint(certificate, &thumbprint, true) == UA_STATUSCODE_GOOD) {
122039 static const char hex2char[] = "0123456789ABCDEF";
122040 for(size_t pos = 0, namePos = 0; pos < thumbprint.length; pos++) {
122041 rejectedFileName[namePos++] = hex2char[(thumbprint.data[pos] & 0xf0) >> 4];
122042 rejectedFileName[namePos++] = hex2char[thumbprint.data[pos] & 0x0f];
122043 }
122044 strcat(rejectedFileName, ".der");
122045 } else {
122046 UA_UInt64 dt = (UA_UInt64) UA_DateTime_now();
122047 sprintf(rejectedFileName, "cert_%" PRIu64 ".der", dt);
122048 }
122049 UA_ByteString_clear(&thumbprint);
122050 char *rejectedFullFileName = (char *)
122051 calloc(ctx->rejectedListFolder.length + 1 /* '/' */ + strlen(rejectedFileName) + 1, sizeof(char));
122052 if(!rejectedFullFileName)
122053 return ret;
122054 memcpy(rejectedFullFileName, ctx->rejectedListFolder.data, ctx->rejectedListFolder.length);
122055 rejectedFullFileName[ctx->rejectedListFolder.length] = '/';
122056 memcpy(&rejectedFullFileName[ctx->rejectedListFolder.length + 1], rejectedFileName, strlen(rejectedFileName));
122057 FILE * fp_rejectedFile = fopen(rejectedFullFileName, "wb");
122058 if(fp_rejectedFile) {
122059 fwrite(certificate->data, sizeof(certificate->data[0]), certificate->length, fp_rejectedFile);
122060 fclose(fp_rejectedFile);
122061 }
122062 free(rejectedFullFileName);
122063 }
122064#endif
122065
122066 return ret;
122067}
122068
122069static UA_StatusCode
122070UA_CertificateVerification_VerifyApplicationURI (const UA_CertificateVerification *cv,
122071 const UA_ByteString * certificate,
122072 const UA_String * applicationURI) {
122073 const unsigned char * pData;
122074 X509 * certificateX509;
122075 UA_String subjectURI = UA_STRING_NULL;
122076 GENERAL_NAMES * pNames;
122077 int i;
122078 UA_StatusCode ret;
122079 CertContext * ctx;
122080
122081 if (cv == NULL) {
122082 return UA_STATUSCODE_BADINTERNALERROR;
122083 }
122084 ctx = (CertContext *)cv->context;
122085 if (ctx == NULL) {
122086 return UA_STATUSCODE_BADINTERNALERROR;
122087 }
122088
122089 pData = certificate->data;
122090 if (pData == NULL) {
122091 UA_LOG_ERROR(logger: cv->logging, category: UA_LOGCATEGORY_USERLAND, msg: "Error Empty Certificate");
122092 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
122093 }
122094
122095 certificateX509 = UA_OpenSSL_LoadCertificate(certificate);
122096 if (certificateX509 == NULL) {
122097 UA_LOG_ERROR(logger: cv->logging, category: UA_LOGCATEGORY_USERLAND, msg: "Error loading X509 Certificate");
122098 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
122099 }
122100
122101 pNames = (GENERAL_NAMES *) X509_get_ext_d2i(x: certificateX509, NID_subject_alt_name,
122102 NULL, NULL);
122103 if (pNames == NULL) {
122104 X509_free (a: certificateX509);
122105 UA_LOG_ERROR(logger: cv->logging, category: UA_LOGCATEGORY_USERLAND, msg: "Error processing X509 Certificate");
122106 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
122107 }
122108
122109 UA_String_init(p: &subjectURI);
122110
122111 for (i = 0; i < sk_GENERAL_NAME_num (pNames); i++) {
122112 GENERAL_NAME * value = sk_GENERAL_NAME_value (pNames, i);
122113 if (value->type == GEN_URI) {
122114 subjectURI.length = (size_t) (value->d.ia5->length);
122115 subjectURI.data = (UA_Byte *) UA_malloc (size: subjectURI.length);
122116 if (subjectURI.data == NULL) {
122117 UA_LOG_ERROR(logger: cv->logging, category: UA_LOGCATEGORY_USERLAND, msg: "Error Empty subjectURI");
122118 X509_free (a: certificateX509);
122119 sk_GENERAL_NAME_pop_free(pNames, GENERAL_NAME_free);
122120 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
122121 }
122122 (void) memcpy (dest: subjectURI.data, src: value->d.ia5->data, n: subjectURI.length);
122123 break;
122124 }
122125
122126 }
122127
122128 ret = UA_STATUSCODE_GOOD;
122129 if (UA_Bstrstr (s1: subjectURI.data, l1: subjectURI.length,
122130 s2: applicationURI->data, l2: applicationURI->length) == NULL) {
122131 UA_LOG_ERROR(logger: cv->logging, category: UA_LOGCATEGORY_USERLAND, msg: "Empty comparing subjectURI and applicationURI");
122132 ret = UA_STATUSCODE_BADCERTIFICATEURIINVALID;
122133 }
122134
122135 X509_free (a: certificateX509);
122136 sk_GENERAL_NAME_pop_free(pNames, GENERAL_NAME_free);
122137 UA_String_clear (p: &subjectURI);
122138 return ret;
122139}
122140
122141#ifdef UA_ENABLE_ENCRYPTION_OPENSSL
122142static UA_StatusCode
122143UA_GetCertificate_ExpirationDate(UA_DateTime *expiryDateTime,
122144 UA_ByteString *certificate) {
122145 const unsigned char *pData = certificate->data;
122146 X509 * x509 = d2i_X509 (NULL, in: &pData, len: (long)certificate->length);
122147 if (x509 == NULL) {
122148 return UA_STATUSCODE_BADINTERNALERROR;
122149 }
122150
122151 /* Get the certificate Expiry date */
122152 ASN1_TIME *not_after = X509_get_notAfter(x: x509);
122153
122154 struct tm dtTime;
122155 ASN1_TIME_to_tm(s: not_after, tm: &dtTime);
122156 X509_free(a: x509);
122157
122158 struct musl_tm dateTime;
122159 memset(s: &dateTime, c: 0, n: sizeof(struct musl_tm));
122160 dateTime.tm_year = dtTime.tm_year;
122161 dateTime.tm_mon = dtTime.tm_mon;
122162 dateTime.tm_mday = dtTime.tm_mday;
122163 dateTime.tm_hour = dtTime.tm_hour;
122164 dateTime.tm_min = dtTime.tm_min;
122165 dateTime.tm_sec = dtTime.tm_sec;
122166
122167 long long sec_epoch = musl_tm_to_secs(tm: &dateTime);
122168 *expiryDateTime = UA_DATETIME_UNIX_EPOCH;
122169 *expiryDateTime += sec_epoch * UA_DATETIME_SEC;
122170 return UA_STATUSCODE_GOOD;
122171}
122172#endif
122173
122174static UA_StatusCode
122175UA_GetCertificate_SubjectName(UA_String *subjectName,
122176 UA_ByteString *certificate) {
122177 const unsigned char *pData = certificate->data;
122178 X509 *x509 = d2i_X509 (NULL, in: &pData, len: (long)certificate->length);
122179 if(!x509)
122180 return UA_STATUSCODE_BADINTERNALERROR;
122181 X509_NAME *sn = X509_get_subject_name(a: x509);
122182 char buf[1024];
122183 *subjectName = UA_STRING_ALLOC(X509_NAME_oneline(sn, buf, 1024));
122184 X509_free(a: x509);
122185 return UA_STATUSCODE_GOOD;
122186}
122187
122188/* main entry */
122189
122190UA_StatusCode
122191UA_CertificateVerification_Trustlist(UA_CertificateVerification * cv,
122192 const UA_ByteString * certificateTrustList,
122193 size_t certificateTrustListSize,
122194 const UA_ByteString * certificateIssuerList,
122195 size_t certificateIssuerListSize,
122196 const UA_ByteString * certificateRevocationList,
122197 size_t certificateRevocationListSize) {
122198 UA_StatusCode ret;
122199
122200 if (cv == NULL) {
122201 return UA_STATUSCODE_BADINTERNALERROR;
122202 }
122203 if (cv->logging == NULL) {
122204 return UA_STATUSCODE_BADINTERNALERROR;
122205 }
122206
122207 /* Clear if the plugin is already initialized */
122208 if(cv->clear)
122209 cv->clear(cv);
122210
122211 CertContext * context = (CertContext *) UA_malloc (size: sizeof (CertContext));
122212 if (context == NULL) {
122213 return UA_STATUSCODE_BADOUTOFMEMORY;
122214 }
122215
122216 cv->verifyApplicationURI = UA_CertificateVerification_VerifyApplicationURI;
122217 cv->clear = UA_CertificateVerification_clear;
122218 cv->context = context;
122219 cv->verifyCertificate = UA_CertificateVerification_Verify;
122220#ifdef UA_ENABLE_ENCRYPTION_OPENSSL
122221 cv->getExpirationDate = UA_GetCertificate_ExpirationDate;
122222#endif
122223 cv->getSubjectName = UA_GetCertificate_SubjectName;
122224
122225 ret = UA_CertContext_Init (context, cv);
122226 if (ret != UA_STATUSCODE_GOOD) {
122227 return ret;
122228 }
122229
122230 if (certificateTrustListSize > 0) {
122231 if (UA_skTrusted_Cert2X509 (certificateTrustList, certificateTrustListSize,
122232 ctx: context) != UA_STATUSCODE_GOOD) {
122233 ret = UA_STATUSCODE_BADINTERNALERROR;
122234 goto errout;
122235 }
122236 }
122237
122238 if (certificateIssuerListSize > 0) {
122239 if (UA_skIssuer_Cert2X509 (certificateIssuerList, certificateIssuerListSize,
122240 ctx: context) != UA_STATUSCODE_GOOD) {
122241 ret = UA_STATUSCODE_BADINTERNALERROR;
122242 goto errout;
122243 }
122244 }
122245
122246 if (certificateRevocationListSize > 0) {
122247 if (UA_skCrls_Cert2X509 (certificateRevocationList, certificateRevocationListSize,
122248 ctx: context) != UA_STATUSCODE_GOOD) {
122249 ret = UA_STATUSCODE_BADINTERNALERROR;
122250 goto errout;
122251 }
122252 }
122253
122254 return UA_STATUSCODE_GOOD;
122255
122256errout:
122257 UA_CertificateVerification_clear (cv);
122258 return ret;
122259}
122260
122261#ifdef __linux__ /* Linux only so far */
122262UA_StatusCode
122263UA_CertificateVerification_CertFolders(UA_CertificateVerification *cv,
122264 const char *trustListFolder,
122265 const char *issuerListFolder,
122266 const char *revocationListFolder
122267#ifdef UA_ENABLE_CERT_REJECTED_DIR
122268 , const char *rejectedListFolder
122269#endif
122270 ) {
122271 UA_StatusCode ret;
122272 if (cv == NULL) {
122273 return UA_STATUSCODE_BADINTERNALERROR;
122274 }
122275 if (cv->logging == NULL) {
122276 return UA_STATUSCODE_BADINTERNALERROR;
122277 }
122278
122279 /* Clear if the plugin is already initialized */
122280 if(cv->clear)
122281 cv->clear(cv);
122282
122283 CertContext * context = (CertContext *) UA_malloc (size: sizeof (CertContext));
122284 if (context == NULL) {
122285 return UA_STATUSCODE_BADOUTOFMEMORY;
122286 }
122287
122288 cv->verifyApplicationURI = UA_CertificateVerification_VerifyApplicationURI;
122289 cv->clear = UA_CertificateVerification_clear;
122290 cv->context = context;
122291 cv->verifyCertificate = UA_CertificateVerification_Verify;
122292
122293 ret = UA_CertContext_Init (context, cv);
122294 if (ret != UA_STATUSCODE_GOOD) {
122295 return ret;
122296 }
122297
122298 /* Only set the folder paths. They will be reloaded during runtime. */
122299
122300 context->trustListFolder = UA_STRING_ALLOC(trustListFolder);
122301 context->issuerListFolder = UA_STRING_ALLOC(issuerListFolder);
122302 context->revocationListFolder = UA_STRING_ALLOC(revocationListFolder);
122303#ifdef UA_ENABLE_CERT_REJECTED_DIR
122304 context->rejectedListFolder = UA_STRING_ALLOC(rejectedListFolder);
122305#endif
122306
122307 return UA_STATUSCODE_GOOD;
122308}
122309#endif
122310
122311static int
122312privateKeyPasswordCallback(char *buf, int size, int rwflag, void *userdata) {
122313 (void) rwflag;
122314 UA_ByteString *pw = (UA_ByteString*)userdata;
122315 if(pw->length <= (size_t)size)
122316 memcpy(dest: buf, src: pw->data, n: pw->length);
122317 return (int)pw->length;
122318}
122319
122320UA_StatusCode
122321UA_PKI_decryptPrivateKey(const UA_ByteString privateKey,
122322 const UA_ByteString password,
122323 UA_ByteString *outDerKey) {
122324 if(!outDerKey)
122325 return UA_STATUSCODE_BADINTERNALERROR;
122326
122327 if (privateKey.length == 0) {
122328 *outDerKey = UA_BYTESTRING_NULL;
122329 return UA_STATUSCODE_BADINVALIDARGUMENT;
122330 }
122331
122332 /* Already in DER format -> return verbatim */
122333 if(privateKey.length > 1 && privateKey.data[0] == 0x30 && privateKey.data[1] == 0x82)
122334 return UA_ByteString_copy(src: &privateKey, dst: outDerKey);
122335
122336 /* Decrypt */
122337 BIO *bio = BIO_new_mem_buf(buf: (void*)privateKey.data, len: (int)privateKey.length);
122338 EVP_PKEY *pkey = PEM_read_bio_PrivateKey(out: bio, NULL,
122339 cb: privateKeyPasswordCallback,
122340 u: (void*)(uintptr_t)&password);
122341 BIO_free(a: bio);
122342 if(!pkey)
122343 return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
122344
122345 /* Write DER encoded, allocates the new memory */
122346 unsigned char *data = NULL;
122347 const int numBytes = i2d_PrivateKey(a: pkey, pp: &data);
122348 EVP_PKEY_free(pkey);
122349 if(!data)
122350 return UA_STATUSCODE_BADOUTOFMEMORY;
122351
122352 /* Copy to the data to outDerKey
122353 * Passing the data pointer directly causes a heap corruption on Windows
122354 * when outDerKey is cleared.
122355 */
122356 UA_ByteString temp = UA_BYTESTRING_NULL;
122357 temp.data = data;
122358 temp.length = (size_t)numBytes;
122359 const UA_StatusCode success = UA_ByteString_copy(src: &temp, dst: outDerKey);
122360 /* OPENSSL_clear_free() is not supported by the LibreSSL version in the CI */
122361 OPENSSL_cleanse(ptr: data, len: numBytes);
122362 OPENSSL_free(data);
122363 return success;
122364}
122365
122366#endif /* end of defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL) */
122367
122368/**** amalgamated original file "/plugins/crypto/ua_pki_none.c" ****/
122369
122370/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
122371 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
122372 *
122373 * Copyright 2020 (c) Julius Pfrommer, Fraunhofer IOSB
122374 */
122375
122376
122377static UA_StatusCode
122378verifyCertificateAllowAll(const UA_CertificateVerification *cv,
122379 const UA_ByteString *certificate) {
122380 UA_LOG_WARNING(logger: cv->logging, category: UA_LOGCATEGORY_USERLAND,
122381 msg: "No certificate store configured. Accepting the certificate.");
122382 return UA_STATUSCODE_GOOD;
122383}
122384
122385static UA_StatusCode
122386verifyApplicationURIAllowAll(const UA_CertificateVerification *cv,
122387 const UA_ByteString *certificate,
122388 const UA_String *applicationURI) {
122389 return UA_STATUSCODE_GOOD;
122390}
122391
122392static void
122393clearVerifyAllowAll(UA_CertificateVerification *cv) {
122394
122395}
122396
122397void UA_CertificateVerification_AcceptAll(UA_CertificateVerification *cv) {
122398 /* Clear the structure, as it may have already been initialized. */
122399 if(cv->clear)
122400 cv->clear(cv);
122401 cv->verifyCertificate = verifyCertificateAllowAll;
122402 cv->verifyApplicationURI = verifyApplicationURIAllowAll;
122403 cv->clear = clearVerifyAllowAll;
122404}
122405
122406/**** amalgamated original file "/plugins/crypto/ua_securitypolicy_none.c" ****/
122407
122408/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
122409 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
122410 *
122411 * Copyright 2017-2018 (c) Mark Giraud, Fraunhofer IOSB
122412 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
122413 */
122414
122415
122416#ifdef UA_ENABLE_ENCRYPTION_MBEDTLS
122417#endif
122418
122419#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL)
122420#endif
122421
122422static UA_StatusCode
122423verify_none(void *channelContext,
122424 const UA_ByteString *message,
122425 const UA_ByteString *signature) {
122426 return UA_STATUSCODE_GOOD;
122427}
122428
122429static UA_StatusCode
122430sign_none(void *channelContext, const UA_ByteString *message,
122431 UA_ByteString *signature) {
122432 return UA_STATUSCODE_GOOD;
122433}
122434
122435static size_t
122436length_none(const void *channelContext) {
122437 return 0;
122438}
122439
122440static UA_StatusCode
122441encrypt_none(void *channelContext, UA_ByteString *data) {
122442 return UA_STATUSCODE_GOOD;
122443}
122444
122445static UA_StatusCode
122446decrypt_none(void *channelContext, UA_ByteString *data) {
122447 return UA_STATUSCODE_GOOD;
122448}
122449
122450static UA_StatusCode
122451makeThumbprint_none(const UA_SecurityPolicy *securityPolicy,
122452 const UA_ByteString *certificate,
122453 UA_ByteString *thumbprint) {
122454 return UA_STATUSCODE_GOOD;
122455}
122456
122457static UA_StatusCode
122458compareThumbprint_none(const UA_SecurityPolicy *securityPolicy,
122459 const UA_ByteString *certificateThumbprint) {
122460 return UA_STATUSCODE_GOOD;
122461}
122462
122463static UA_StatusCode
122464generateKey_none(void *policyContext, const UA_ByteString *secret,
122465 const UA_ByteString *seed, UA_ByteString *out) {
122466 return UA_STATUSCODE_GOOD;
122467}
122468
122469/* Use the non-cryptographic RNG to set the nonce */
122470static UA_StatusCode
122471generateNonce_none(void *policyContext, UA_ByteString *out) {
122472 if(out == NULL)
122473 return UA_STATUSCODE_BADINTERNALERROR;
122474
122475 if(out->length == 0)
122476 return UA_STATUSCODE_GOOD;
122477
122478 /* Fill blocks of four byte */
122479 size_t i = 0;
122480 while(i + 3 < out->length) {
122481 UA_UInt32 randNumber = UA_UInt32_random();
122482 memcpy(dest: &out->data[i], src: &randNumber, n: 4);
122483 i = i+4;
122484 }
122485
122486 /* Fill the remaining byte */
122487 UA_UInt32 randNumber = UA_UInt32_random();
122488 memcpy(dest: &out->data[i], src: &randNumber, n: out->length % 4);
122489
122490 return UA_STATUSCODE_GOOD;
122491}
122492
122493static UA_StatusCode
122494newContext_none(const UA_SecurityPolicy *securityPolicy,
122495 const UA_ByteString *remoteCertificate,
122496 void **channelContext) {
122497 return UA_STATUSCODE_GOOD;
122498}
122499
122500static void
122501deleteContext_none(void *channelContext) {
122502}
122503
122504static UA_StatusCode
122505setContextValue_none(void *channelContext,
122506 const UA_ByteString *key) {
122507 return UA_STATUSCODE_GOOD;
122508}
122509
122510static UA_StatusCode
122511compareCertificate_none(const void *channelContext,
122512 const UA_ByteString *certificate) {
122513 return UA_STATUSCODE_GOOD;
122514}
122515
122516static UA_StatusCode
122517updateCertificateAndPrivateKey_none(UA_SecurityPolicy *policy,
122518 const UA_ByteString newCertificate,
122519 const UA_ByteString newPrivateKey) {
122520 UA_ByteString_clear(p: &policy->localCertificate);
122521 UA_ByteString_copy(src: &newCertificate, dst: &policy->localCertificate);
122522 return UA_STATUSCODE_GOOD;
122523}
122524
122525
122526static void
122527policy_clear_none(UA_SecurityPolicy *policy) {
122528 UA_ByteString_clear(p: &policy->localCertificate);
122529}
122530
122531UA_StatusCode
122532UA_SecurityPolicy_None(UA_SecurityPolicy *policy, const UA_ByteString localCertificate,
122533 const UA_Logger *logger) {
122534 policy->policyContext = (void *)(uintptr_t)logger;
122535 policy->policyUri = UA_STRING(chars: "http://opcfoundation.org/UA/SecurityPolicy#None");
122536 policy->logger = logger;
122537
122538#ifdef UA_ENABLE_ENCRYPTION_MBEDTLS
122539 UA_mbedTLS_LoadLocalCertificate(&localCertificate, &policy->localCertificate);
122540#elif defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL)
122541 UA_OpenSSL_LoadLocalCertificate(certificate: &localCertificate, target: &policy->localCertificate);
122542#else
122543 UA_ByteString_copy(&localCertificate, &policy->localCertificate);
122544#endif
122545
122546 policy->symmetricModule.generateKey = generateKey_none;
122547 policy->symmetricModule.generateNonce = generateNonce_none;
122548
122549 UA_SecurityPolicySignatureAlgorithm *sym_signatureAlgorithm =
122550 &policy->symmetricModule.cryptoModule.signatureAlgorithm;
122551 sym_signatureAlgorithm->uri = UA_STRING_NULL;
122552 sym_signatureAlgorithm->verify = verify_none;
122553 sym_signatureAlgorithm->sign = sign_none;
122554 sym_signatureAlgorithm->getLocalSignatureSize = length_none;
122555 sym_signatureAlgorithm->getRemoteSignatureSize = length_none;
122556 sym_signatureAlgorithm->getLocalKeyLength = length_none;
122557 sym_signatureAlgorithm->getRemoteKeyLength = length_none;
122558
122559 UA_SecurityPolicyEncryptionAlgorithm *sym_encryptionAlgorithm =
122560 &policy->symmetricModule.cryptoModule.encryptionAlgorithm;
122561 sym_encryptionAlgorithm->uri = UA_STRING_NULL;
122562 sym_encryptionAlgorithm->encrypt = encrypt_none;
122563 sym_encryptionAlgorithm->decrypt = decrypt_none;
122564 sym_encryptionAlgorithm->getLocalKeyLength = length_none;
122565 sym_encryptionAlgorithm->getRemoteKeyLength = length_none;
122566 sym_encryptionAlgorithm->getRemoteBlockSize = length_none;
122567 sym_encryptionAlgorithm->getRemotePlainTextBlockSize = length_none;
122568 policy->symmetricModule.secureChannelNonceLength = 0;
122569
122570 policy->asymmetricModule.makeCertificateThumbprint = makeThumbprint_none;
122571 policy->asymmetricModule.compareCertificateThumbprint = compareThumbprint_none;
122572
122573 // This only works for none since symmetric and asymmetric crypto modules do the same i.e. nothing
122574 policy->asymmetricModule.cryptoModule = policy->symmetricModule.cryptoModule;
122575
122576 // Use the same signing algorithm as for asymmetric signing
122577 policy->certificateSigningAlgorithm = policy->asymmetricModule.cryptoModule.signatureAlgorithm;
122578
122579 policy->channelModule.newContext = newContext_none;
122580 policy->channelModule.deleteContext = deleteContext_none;
122581 policy->channelModule.setLocalSymEncryptingKey = setContextValue_none;
122582 policy->channelModule.setLocalSymSigningKey = setContextValue_none;
122583 policy->channelModule.setLocalSymIv = setContextValue_none;
122584 policy->channelModule.setRemoteSymEncryptingKey = setContextValue_none;
122585 policy->channelModule.setRemoteSymSigningKey = setContextValue_none;
122586 policy->channelModule.setRemoteSymIv = setContextValue_none;
122587 policy->channelModule.compareCertificate = compareCertificate_none;
122588 policy->updateCertificateAndPrivateKey = updateCertificateAndPrivateKey_none;
122589 policy->clear = policy_clear_none;
122590
122591 return UA_STATUSCODE_GOOD;
122592}
122593
122594/**** amalgamated original file "/arch/common/ua_timer.h" ****/
122595
122596/* This Source Code Form is subject to the terms of the Mozilla Public
122597 * License, v. 2.0. If a copy of the MPL was not distributed with this
122598 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
122599 *
122600 * Copyright 2017, 2018, 2021 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
122601 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
122602 */
122603
122604
122605
122606_UA_BEGIN_DECLS
122607
122608/* The timer is protected by its own mutex. The mutex is released before calling
122609 * into the callbacks. So the timer can be modified from the callbacks it is
122610 * executing. Also, the timer mutex can never lead to locking. Because the timer
122611 * mutex will be left without acquiring another mutex.
122612 *
122613 * Obviously, the timer must not be deleted from within one of its
122614 * callbacks. */
122615
122616/* Callback where the application is either a client or a server */
122617typedef void (*UA_ApplicationCallback)(void *application, void *data);
122618
122619typedef struct UA_TimerEntry {
122620 ZIP_ENTRY(UA_TimerEntry) treeEntry;
122621 UA_TimerPolicy timerPolicy; /* Timer policy to handle cycle misses */
122622 UA_DateTime nextTime; /* The next time when the callback is to be
122623 * executed */
122624 UA_UInt64 interval; /* Interval in 100ns resolution. If the
122625 * interval is zero, the callback is not
122626 * repeated and removed after execution. */
122627 UA_ApplicationCallback callback; /* This is also a sentinel value. If the
122628 * callback is NULL, then the entry is
122629 * marked for deletion. */
122630 void *application;
122631 void *data;
122632
122633 ZIP_ENTRY(UA_TimerEntry) idTreeEntry;
122634 UA_UInt64 id; /* Id of the entry */
122635} UA_TimerEntry;
122636
122637typedef ZIP_HEAD(UA_TimerTree, UA_TimerEntry) UA_TimerTree;
122638typedef ZIP_HEAD(UA_TimerIdTree, UA_TimerEntry) UA_TimerIdTree;
122639
122640typedef struct {
122641 UA_TimerTree tree; /* The root of the time-sorted tree */
122642 UA_TimerIdTree idTree; /* The root of the id-sorted tree */
122643 UA_UInt64 idCounter; /* Generate unique identifiers. Identifiers are
122644 * always above zero. */
122645#if UA_MULTITHREADING >= 100
122646 UA_Lock timerMutex;
122647#endif
122648
122649 UA_TimerTree processTree; /* When the timer is processed, all entries that
122650 * need processing now are moved to processTree.
122651 * Then we iterate over that tree. */
122652} UA_Timer;
122653
122654void
122655UA_Timer_init(UA_Timer *t);
122656
122657UA_DateTime
122658UA_Timer_nextRepeatedTime(UA_Timer *t);
122659
122660UA_StatusCode
122661UA_Timer_addTimedCallback(UA_Timer *t, UA_ApplicationCallback callback,
122662 void *application, void *data, UA_DateTime date,
122663 UA_UInt64 *callbackId);
122664
122665UA_StatusCode
122666UA_Timer_addRepeatedCallback(UA_Timer *t, UA_ApplicationCallback callback,
122667 void *application, void *data, UA_Double interval_ms,
122668 UA_DateTime *baseTime, UA_TimerPolicy timerPolicy,
122669 UA_UInt64 *callbackId);
122670
122671UA_StatusCode
122672UA_Timer_changeRepeatedCallback(UA_Timer *t, UA_UInt64 callbackId,
122673 UA_Double interval_ms, UA_DateTime *baseTime,
122674 UA_TimerPolicy timerPolicy);
122675
122676void
122677UA_Timer_removeCallback(UA_Timer *t, UA_UInt64 callbackId);
122678
122679UA_DateTime
122680UA_Timer_process(UA_Timer *t, UA_DateTime nowMonotonic);
122681
122682void
122683UA_Timer_clear(UA_Timer *t);
122684
122685_UA_END_DECLS
122686
122687
122688/**** amalgamated original file "/arch/eventloop_common.h" ****/
122689
122690/* This Source Code Form is subject to the terms of the Mozilla Public
122691 * License, v. 2.0. If a copy of the MPL was not distributed with this
122692 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
122693 *
122694 * Copyright 2021 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
122695 * Copyright 2021 (c) Fraunhofer IOSB (Author: Jan Hermes)
122696 */
122697
122698
122699
122700/* Utility definitions to be used in EventLoop implementations.
122701 * Not part of the public API. */
122702
122703_UA_BEGIN_DECLS
122704
122705/* Typing restrictions for key-value parameters */
122706typedef struct {
122707 UA_QualifiedName name;
122708 const UA_DataType *type;
122709 UA_Boolean required;
122710 UA_Boolean scalar;
122711 UA_Boolean array;
122712} UA_KeyValueRestriction;
122713
122714UA_StatusCode
122715UA_KeyValueRestriction_validate(const UA_Logger *logger,
122716 const char *logprefix,
122717 const UA_KeyValueRestriction *restrictions,
122718 size_t restrictionsSiz,
122719 const UA_KeyValueMap *map);
122720
122721_UA_END_DECLS
122722
122723
122724/**** amalgamated original file "/arch/eventloop_posix.h" ****/
122725
122726/* This Source Code Form is subject to the terms of the Mozilla Public
122727 * License, v. 2.0. If a copy of the MPL was not distributed with this
122728 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
122729 *
122730 * Copyright 2021 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
122731 * Copyright 2021 (c) Fraunhofer IOSB (Author: Jan Hermes)
122732 */
122733
122734
122735
122736#if defined(UA_ARCHITECTURE_POSIX) || defined(UA_ARCHITECTURE_WIN32)
122737
122738/* Include architecture-specific definitions */
122739#if defined(UA_ARCHITECTURE_WIN32)
122740#elif defined(UA_ARCHITECTURE_POSIX)
122741#endif
122742
122743
122744#if !defined(__QNX__)
122745#endif
122746
122747/* epoll_pwait returns bogus data with the tc compiler */
122748#if defined(__linux__) && !defined(__TINYC__)
122749# define UA_HAVE_EPOLL
122750# include <sys/epoll.h>
122751#endif
122752
122753#define UA_MAXBACKLOG 100
122754#define UA_MAXHOSTNAME_LENGTH 256
122755#define UA_MAXPORTSTR_LENGTH 6
122756
122757#ifndef MSG_NOSIGNAL
122758#define MSG_NOSIGNAL 0
122759#endif
122760
122761#ifndef MSG_DONTWAIT
122762#define MSG_DONTWAIT 0
122763#endif
122764
122765_UA_BEGIN_DECLS
122766
122767/* POSIX events are based on sockets / file descriptors. The EventSources can
122768 * register their fd in the EventLoop so that they are considered by the
122769 * EventLoop dropping into "poll" to wait for events. */
122770
122771/* TODO: Move the macro-forest from /arch/<arch>/ua_architecture.h */
122772
122773#define UA_FD UA_SOCKET
122774#define UA_INVALID_FD UA_INVALID_SOCKET
122775
122776struct UA_RegisteredFD;
122777typedef struct UA_RegisteredFD UA_RegisteredFD;
122778
122779/* Bitmask to be used for the UA_FDCallback event argument */
122780#define UA_FDEVENT_IN 1
122781#define UA_FDEVENT_OUT 2
122782#define UA_FDEVENT_ERR 4
122783
122784typedef void (*UA_FDCallback)(UA_EventSource *es, UA_RegisteredFD *rfd, short event);
122785
122786struct UA_RegisteredFD {
122787 UA_DelayedCallback dc; /* Used for async closing. Must be the first member
122788 * because the rfd is freed by the delayed callback
122789 * mechanism. */
122790
122791 ZIP_ENTRY(UA_RegisteredFD) zipPointers; /* Register FD in the EventSource */
122792 UA_FD fd;
122793 short listenEvents; /* UA_FDEVENT_IN | UA_FDEVENT_OUT*/
122794
122795 UA_EventSource *es; /* Backpointer to the EventSource */
122796 UA_FDCallback eventSourceCB;
122797};
122798
122799enum ZIP_CMP cmpFD(const UA_FD *a, const UA_FD *b);
122800typedef ZIP_HEAD(UA_FDTree, UA_RegisteredFD) UA_FDTree;
122801ZIP_FUNCTIONS(UA_FDTree, UA_RegisteredFD, zipPointers, UA_FD, fd, cmpFD)
122802
122803/* All ConnectionManager in the POSIX EventLoop can be cast to
122804 * UA_ConnectionManagerPOSIX. They carry a sorted tree of their open
122805 * sockets/file-descriptors. */
122806typedef struct {
122807 UA_ConnectionManager cm;
122808
122809 /* Reused receive buffer. The size is configured via
122810 * the recv-bufsize parameter.*/
122811 UA_ByteString rxBuffer;
122812
122813 /* Sorted tree of the FDs */
122814 size_t fdsSize;
122815 UA_FDTree fds;
122816} UA_POSIXConnectionManager;
122817
122818typedef struct {
122819 UA_EventLoop eventLoop;
122820
122821 /* Timer */
122822 UA_Timer timer;
122823
122824 /* Linked List of Delayed Callbacks */
122825 UA_DelayedCallback *delayedCallbacks;
122826
122827 /* Flag determining whether the eventloop is currently within the
122828 * "run" method */
122829 UA_Boolean executing;
122830
122831#if defined(UA_HAVE_EPOLL)
122832 UA_FD epollfd;
122833#else
122834 UA_RegisteredFD **fds;
122835 size_t fdsSize;
122836#endif
122837
122838#if UA_MULTITHREADING >= 100
122839 UA_Lock elMutex;
122840#endif
122841} UA_EventLoopPOSIX;
122842
122843/*
122844 * The following functions differ between epoll and normal select
122845 */
122846
122847/* Register to start receiving events */
122848UA_StatusCode
122849UA_EventLoopPOSIX_registerFD(UA_EventLoopPOSIX *el, UA_RegisteredFD *rfd);
122850
122851/* Modify the events that the fd listens on */
122852UA_StatusCode
122853UA_EventLoopPOSIX_modifyFD(UA_EventLoopPOSIX *el, UA_RegisteredFD *rfd);
122854
122855/* Deregister but do not close the fd. No further events are received. */
122856void
122857UA_EventLoopPOSIX_deregisterFD(UA_EventLoopPOSIX *el, UA_RegisteredFD *rfd);
122858
122859UA_StatusCode
122860UA_EventLoopPOSIX_pollFDs(UA_EventLoopPOSIX *el, UA_DateTime listenTimeout);
122861
122862/* Helper functions between EventSources */
122863
122864UA_StatusCode
122865UA_EventLoopPOSIX_allocateRXBuffer(UA_POSIXConnectionManager *pcm);
122866
122867UA_StatusCode
122868UA_EventLoopPOSIX_allocNetworkBuffer(UA_ConnectionManager *cm,
122869 uintptr_t connectionId,
122870 UA_ByteString *buf,
122871 size_t bufSize);
122872
122873void
122874UA_EventLoopPOSIX_freeNetworkBuffer(UA_ConnectionManager *cm,
122875 uintptr_t connectionId,
122876 UA_ByteString *buf);
122877
122878/*
122879 * Helper functions to be used across protocols
122880 */
122881
122882/* Set the socket non-blocking. If the listen-socket is nonblocking, incoming
122883 * connections inherit this state. */
122884UA_StatusCode
122885UA_EventLoopPOSIX_setNonBlocking(UA_FD sockfd);
122886
122887/* Don't have the socket create interrupt signals */
122888UA_StatusCode
122889UA_EventLoopPOSIX_setNoSigPipe(UA_FD sockfd);
122890
122891/* Enables sharing of the same listening address on different sockets */
122892UA_StatusCode
122893UA_EventLoopPOSIX_setReusable(UA_FD sockfd);
122894
122895_UA_END_DECLS
122896
122897#endif /* defined(UA_ARCHITECTURE_POSIX) || defined(UA_ARCHITECTURE_WIN32) */
122898
122899
122900/**** amalgamated original file "/arch/posix/ua_clock.c" ****/
122901
122902/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
122903 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
122904 *
122905 * Copyright 2016-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
122906 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
122907 * Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA
122908 */
122909
122910
122911#ifdef UA_ARCHITECTURE_POSIX
122912
122913#include <time.h>
122914#include <sys/time.h>
122915
122916#if defined(__APPLE__) || defined(__MACH__)
122917# include <mach/clock.h>
122918# include <mach/mach.h>
122919#endif
122920
122921UA_DateTime UA_DateTime_now(void) {
122922 struct timeval tv;
122923 gettimeofday(tv: &tv, NULL);
122924 return (tv.tv_sec * UA_DATETIME_SEC) + (tv.tv_usec * UA_DATETIME_USEC) + UA_DATETIME_UNIX_EPOCH;
122925}
122926
122927/* Credit to https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c */
122928UA_Int64 UA_DateTime_localTimeUtcOffset(void) {
122929 time_t gmt, rawtime = time(NULL);
122930 struct tm *ptm;
122931 struct tm gbuf;
122932 ptm = gmtime_r(timer: &rawtime, tp: &gbuf);
122933 // Request that mktime() looksup dst in timezone database
122934 ptm->tm_isdst = -1;
122935 gmt = mktime(tp: ptm);
122936 return (UA_Int64) (difftime(time1: rawtime, time0: gmt) * UA_DATETIME_SEC);
122937}
122938
122939UA_DateTime UA_DateTime_nowMonotonic(void) {
122940#if defined(__APPLE__) || defined(__MACH__)
122941 /* OS X does not have clock_gettime, use clock_get_time */
122942 clock_serv_t cclock;
122943 mach_timespec_t mts;
122944 host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
122945 clock_get_time(cclock, &mts);
122946 mach_port_deallocate(mach_task_self(), cclock);
122947 return (mts.tv_sec * UA_DATETIME_SEC) + (mts.tv_nsec / 100);
122948#elif !defined(CLOCK_MONOTONIC_RAW)
122949 struct timespec ts;
122950 clock_gettime(CLOCK_MONOTONIC, &ts);
122951 return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100);
122952#else
122953 struct timespec ts;
122954 clock_gettime(CLOCK_MONOTONIC_RAW, tp: &ts);
122955 return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100);
122956#endif
122957}
122958
122959#endif /* UA_ARCHITECTURE_POSIX */
122960
122961/**** amalgamated original file "/arch/win32/ua_clock.c" ****/
122962
122963/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
122964 * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
122965 *
122966 * Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB
122967 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
122968 * Copyright 2017 (c) Thomas Stalder
122969 */
122970
122971
122972#ifdef UA_ARCHITECTURE_WIN32
122973
122974#include <time.h>
122975/* Backup definition of SLIST_ENTRY on mingw winnt.h */
122976# ifdef SLIST_ENTRY
122977# pragma push_macro("SLIST_ENTRY")
122978# undef SLIST_ENTRY
122979# define POP_SLIST_ENTRY
122980# endif
122981# include <windows.h>
122982/* restore definition */
122983# ifdef POP_SLIST_ENTRY
122984# undef SLIST_ENTRY
122985# undef POP_SLIST_ENTRY
122986# pragma pop_macro("SLIST_ENTRY")
122987# endif
122988
122989UA_DateTime UA_DateTime_now(void) {
122990 /* Windows filetime has the same definition as UA_DateTime */
122991 FILETIME ft;
122992 SYSTEMTIME st;
122993 GetSystemTime(&st);
122994 SystemTimeToFileTime(&st, &ft);
122995 ULARGE_INTEGER ul;
122996 ul.LowPart = ft.dwLowDateTime;
122997 ul.HighPart = ft.dwHighDateTime;
122998 return (UA_DateTime)ul.QuadPart;
122999}
123000
123001/* Credit to https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c */
123002UA_Int64 UA_DateTime_localTimeUtcOffset(void) {
123003 time_t gmt, rawtime = time(NULL);
123004
123005 struct tm ptm;
123006#ifdef __CODEGEARC__
123007 gmtime_s(&rawtime, &ptm);
123008#else
123009 gmtime_s(&ptm, &rawtime);
123010#endif
123011 // Request that mktime() looksup dst in timezone database
123012 ptm.tm_isdst = -1;
123013 gmt = mktime(&ptm);
123014
123015 return (UA_Int64) (difftime(rawtime, gmt) * UA_DATETIME_SEC);
123016}
123017
123018UA_DateTime UA_DateTime_nowMonotonic(void) {
123019 LARGE_INTEGER freq, ticks;
123020 QueryPerformanceFrequency(&freq);
123021 QueryPerformanceCounter(&ticks);
123022 UA_Double ticks2dt = UA_DATETIME_SEC / (UA_Double)freq.QuadPart;
123023 return (UA_DateTime)(ticks.QuadPart * ticks2dt);
123024}
123025
123026#endif /* UA_ARCHITECTURE_WIN32 */
123027
123028/**** amalgamated original file "/arch/common/ua_timer.c" ****/
123029
123030/* This Source Code Form is subject to the terms of the Mozilla Public
123031 * License, v. 2.0. If a copy of the MPL was not distributed with this
123032 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
123033 *
123034 * Copyright 2017, 2018, 2021 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
123035 * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
123036 */
123037
123038
123039static enum ZIP_CMP
123040cmpDateTime(const UA_DateTime *a, const UA_DateTime *b) {
123041 if(*a == *b)
123042 return ZIP_CMP_EQ;
123043 return (*a < *b) ? ZIP_CMP_LESS : ZIP_CMP_MORE;
123044}
123045
123046static enum ZIP_CMP
123047cmpId(const UA_UInt64 *a, const UA_UInt64 *b) {
123048 if(*a == *b)
123049 return ZIP_CMP_EQ;
123050 return (*a < *b) ? ZIP_CMP_LESS : ZIP_CMP_MORE;
123051}
123052
123053ZIP_FUNCTIONS(UA_TimerTree, UA_TimerEntry, treeEntry, UA_DateTime, nextTime, cmpDateTime)
123054ZIP_FUNCTIONS(UA_TimerIdTree, UA_TimerEntry, idTreeEntry, UA_UInt64, id, cmpId)
123055
123056static UA_DateTime
123057calculateNextTime(UA_DateTime currentTime, UA_DateTime baseTime,
123058 UA_DateTime interval) {
123059 /* Take the difference between current and base time */
123060 UA_DateTime diffCurrentTimeBaseTime = currentTime - baseTime;
123061
123062 /* Take modulo of the diff time with the interval. This is the duration we
123063 * are already "into" the current interval. Subtract it from (current +
123064 * interval) to get the next execution time. */
123065 UA_DateTime cycleDelay = diffCurrentTimeBaseTime % interval;
123066
123067 /* Handle the special case where the baseTime is in the future */
123068 if(UA_UNLIKELY(cycleDelay < 0))
123069 cycleDelay += interval;
123070
123071 return currentTime + interval - cycleDelay;
123072}
123073
123074void
123075UA_Timer_init(UA_Timer *t) {
123076 memset(s: t, c: 0, n: sizeof(UA_Timer));
123077 UA_LOCK_INIT(&t->timerMutex);
123078}
123079
123080/* Global variables, only used behind the mutex */
123081static UA_DateTime earliest, latest, adjustedNextTime;
123082
123083static void *
123084findTimer2Batch(void *context, UA_TimerEntry *compare) {
123085 UA_TimerEntry *te = (UA_TimerEntry*)context;
123086
123087 /* NextTime deviation within interval? */
123088 if(compare->nextTime < earliest || compare->nextTime > latest)
123089 return NULL;
123090
123091 /* Check if one interval is a multiple of the other */
123092 if(te->interval < compare->interval && compare->interval % te->interval != 0)
123093 return NULL;
123094 if(te->interval > compare->interval && te->interval % compare->interval != 0)
123095 return NULL;
123096
123097 adjustedNextTime = compare->nextTime; /* Candidate found */
123098
123099 /* Abort when a perfect match is found */
123100 return (te->interval == compare->interval) ? te : NULL;
123101}
123102
123103static UA_StatusCode
123104addCallback(UA_Timer *t, UA_ApplicationCallback callback, void *application,
123105 void *data, UA_DateTime nextTime, UA_UInt64 interval,
123106 UA_TimerPolicy timerPolicy, UA_UInt64 *callbackId) {
123107 /* A callback method needs to be present */
123108 if(!callback)
123109 return UA_STATUSCODE_BADINTERNALERROR;
123110
123111 /* Allocate the repeated callback structure */
123112 UA_TimerEntry *te = (UA_TimerEntry*)UA_malloc(size: sizeof(UA_TimerEntry));
123113 if(!te)
123114 return UA_STATUSCODE_BADOUTOFMEMORY;
123115
123116 /* Set the repeated callback */
123117 te->interval = interval;
123118 te->id = ++t->idCounter;
123119 te->callback = callback;
123120 te->application = application;
123121 te->data = data;
123122 te->nextTime = nextTime;
123123 te->timerPolicy = timerPolicy;
123124
123125 /* Adjust the nextTime to batch cyclic callbacks. Look in an interval around
123126 * the original nextTime. Deviate from the original nextTime by at most 1/4
123127 * of the interval and at most by 1s. */
123128 if(timerPolicy == UA_TIMER_HANDLE_CYCLEMISS_WITH_CURRENTTIME && interval != 0) {
123129 UA_UInt64 deviate = te->interval / 4;
123130 if(deviate > UA_DATETIME_SEC)
123131 deviate = UA_DATETIME_SEC;
123132 earliest = te->nextTime - deviate;
123133 latest = te->nextTime + deviate;
123134 adjustedNextTime = te->nextTime;
123135 ZIP_ITER(UA_TimerIdTree, &t->idTree, findTimer2Batch, te);
123136 te->nextTime = adjustedNextTime;
123137 }
123138
123139 /* Set the output identifier */
123140 if(callbackId)
123141 *callbackId = te->id;
123142
123143 ZIP_INSERT(UA_TimerTree, &t->tree, te);
123144 ZIP_INSERT(UA_TimerIdTree, &t->idTree, te);
123145 return UA_STATUSCODE_GOOD;
123146}
123147
123148UA_StatusCode
123149UA_Timer_addTimedCallback(UA_Timer *t, UA_ApplicationCallback callback,
123150 void *application, void *data, UA_DateTime date,
123151 UA_UInt64 *callbackId) {
123152 UA_LOCK(&t->timerMutex);
123153 UA_StatusCode res = addCallback(t, callback, application, data, nextTime: date,
123154 interval: 0, timerPolicy: UA_TIMER_HANDLE_CYCLEMISS_WITH_CURRENTTIME,
123155 callbackId);
123156 UA_UNLOCK(&t->timerMutex);
123157 return res;
123158}
123159
123160/* Adding repeated callbacks: Add an entry with the "nextTime" timestamp in the
123161 * future. This will be picked up in the next iteration and inserted at the
123162 * correct place. So that the next execution takes place ät "nextTime". */
123163UA_StatusCode
123164UA_Timer_addRepeatedCallback(UA_Timer *t, UA_ApplicationCallback callback,
123165 void *application, void *data, UA_Double interval_ms,
123166 UA_DateTime *baseTime, UA_TimerPolicy timerPolicy,
123167 UA_UInt64 *callbackId) {
123168 /* The interval needs to be positive */
123169 if(interval_ms <= 0.0)
123170 return UA_STATUSCODE_BADINTERNALERROR;
123171 UA_UInt64 interval = (UA_UInt64)(interval_ms * UA_DATETIME_MSEC);
123172 if(interval == 0)
123173 return UA_STATUSCODE_BADINTERNALERROR;
123174
123175 /* Compute the first time for execution */
123176 UA_DateTime currentTime = UA_DateTime_nowMonotonic();
123177 UA_DateTime nextTime;
123178 if(baseTime == NULL) {
123179 /* Use "now" as the basetime */
123180 nextTime = currentTime + (UA_DateTime)interval;
123181 } else {
123182 nextTime = calculateNextTime(currentTime, baseTime: *baseTime, interval: (UA_DateTime)interval);
123183 }
123184
123185 UA_LOCK(&t->timerMutex);
123186 UA_StatusCode res = addCallback(t, callback, application, data, nextTime,
123187 interval, timerPolicy, callbackId);
123188 UA_UNLOCK(&t->timerMutex);
123189 return res;
123190}
123191
123192UA_StatusCode
123193UA_Timer_changeRepeatedCallback(UA_Timer *t, UA_UInt64 callbackId,
123194 UA_Double interval_ms, UA_DateTime *baseTime,
123195 UA_TimerPolicy timerPolicy) {
123196 /* The interval needs to be positive */
123197 if(interval_ms <= 0.0)
123198 return UA_STATUSCODE_BADINTERNALERROR;
123199 UA_UInt64 interval = (UA_UInt64)(interval_ms * UA_DATETIME_MSEC);
123200 if(interval == 0)
123201 return UA_STATUSCODE_BADINTERNALERROR;
123202
123203 UA_LOCK(&t->timerMutex);
123204
123205 /* Find according to the id */
123206 UA_TimerEntry *te = ZIP_FIND(UA_TimerIdTree, &t->idTree, &callbackId);
123207 if(!te) {
123208 UA_UNLOCK(&t->timerMutex);
123209 return UA_STATUSCODE_BADNOTFOUND;
123210 }
123211
123212 /* Try to remove from the time-sorted tree. If not found, then the entry is
123213 * in the processTree. If that is the case, leave it there and only adjust
123214 * the interval and nextTime (if the TimerPolicy uses a basetime). */
123215 UA_Boolean normalTree = (ZIP_REMOVE(UA_TimerTree, &t->tree, te) != NULL);
123216
123217 /* Compute the next time for execution. The logic is identical to the
123218 * creation of a new repeated callback. */
123219 UA_DateTime currentTime = UA_DateTime_nowMonotonic();
123220 if(baseTime == NULL) {
123221 /* Use "now" as the basetime */
123222 te->nextTime = currentTime + (UA_DateTime)interval;
123223 } else {
123224 te->nextTime = calculateNextTime(currentTime, baseTime: *baseTime, interval: (UA_DateTime)interval);
123225 }
123226
123227 /* Update the remaining parameters and re-insert */
123228 te->interval = interval;
123229 te->timerPolicy = timerPolicy;
123230
123231 if(normalTree)
123232 ZIP_INSERT(UA_TimerTree, &t->tree, te);
123233
123234 UA_UNLOCK(&t->timerMutex);
123235 return UA_STATUSCODE_GOOD;
123236}
123237
123238void
123239UA_Timer_removeCallback(UA_Timer *t, UA_UInt64 callbackId) {
123240 UA_LOCK(&t->timerMutex);
123241 UA_TimerEntry *te = ZIP_FIND(UA_TimerIdTree, &t->idTree, &callbackId);
123242 if(UA_LIKELY(te != NULL)) {
123243 if(t->processTree.root == NULL) {
123244 /* Remove/free the entry */
123245 ZIP_REMOVE(UA_TimerTree, &t->tree, te);
123246 ZIP_REMOVE(UA_TimerIdTree, &t->idTree, te);
123247 UA_free(ptr: te);
123248 } else {
123249 /* We are currently processing. Only mark the entry to be deleted.
123250 * Will be removed/freed the next time we reach it in the processing
123251 * callback. */
123252 te->callback = NULL;
123253 }
123254 }
123255 UA_UNLOCK(&t->timerMutex);
123256}
123257
123258struct TimerProcessContext {
123259 UA_Timer *t;
123260 UA_DateTime nowMonotonic;
123261};
123262
123263static void *
123264processEntryCallback(void *context, UA_TimerEntry *te) {
123265 struct TimerProcessContext *tpc = (struct TimerProcessContext*)context;
123266 UA_Timer *t = tpc->t;
123267
123268 /* Execute the callback. The memory is not freed during the callback.
123269 * Instead, whenever t->processTree != NULL, the entries are only marked for
123270 * deletion by setting elm->callback to NULL. */
123271 if(te->callback) {
123272 te->callback(te->application, te->data);
123273 }
123274
123275 /* Remove and free the entry if marked for deletion or a one-time timed
123276 * callback */
123277 if(!te->callback || te->interval == 0) {
123278 ZIP_REMOVE(UA_TimerIdTree, &t->idTree, te);
123279 UA_free(ptr: te);
123280 return NULL;
123281 }
123282
123283 /* Set the time for the next regular execution */
123284 te->nextTime += (UA_DateTime)te->interval;
123285
123286 /* Handle the case where the "window" was missed. E.g. due to congestion of
123287 * the application or if the clock was shifted.
123288 *
123289 * If the timer policy is "CurrentTime", then there is at least the
123290 * interval between executions. This is used for Monitoreditems, for
123291 * which the spec says: The sampling interval indicates the fastest rate
123292 * at which the Server should sample its underlying source for data
123293 * changes. (Part 4, 5.12.1.2) */
123294 if(te->nextTime < tpc->nowMonotonic) {
123295 if(te->timerPolicy == UA_TIMER_HANDLE_CYCLEMISS_WITH_BASETIME)
123296 te->nextTime = calculateNextTime(currentTime: tpc->nowMonotonic, baseTime: te->nextTime,
123297 interval: (UA_DateTime)te->interval);
123298 else
123299 te->nextTime = tpc->nowMonotonic + (UA_DateTime)te->interval;
123300 }
123301
123302 /* Insert back into the time-sorted tree */
123303 ZIP_INSERT(UA_TimerTree, &t->tree, te);
123304 return NULL;
123305}
123306
123307UA_DateTime
123308UA_Timer_process(UA_Timer *t, UA_DateTime nowMonotonic) {
123309 UA_LOCK(&t->timerMutex);
123310
123311 /* Not reentrant. Don't call _process from within _process. */
123312 if(!t->processTree.root) {
123313 /* Move all entries <= nowMonotonic to processTree */
123314 ZIP_UNZIP(UA_TimerTree, &t->tree, &nowMonotonic,
123315 &t->processTree, &t->tree);
123316
123317 /* Consistency check. The smallest not-processed entry isn't ready. */
123318 UA_assert(!ZIP_MIN(UA_TimerTree, &t->tree) ||
123319 ZIP_MIN(UA_TimerTree, &t->tree)->nextTime > nowMonotonic);
123320
123321 /* Iterate over the entries that need processing in-order. This also
123322 * moves them back to the regular time-ordered tree. */
123323 struct TimerProcessContext ctx;
123324 ctx.t = t;
123325 ctx.nowMonotonic = nowMonotonic;
123326 ZIP_ITER(UA_TimerTree, &t->processTree, processEntryCallback, &ctx);
123327
123328 /* Reset processTree. All entries are already moved to the normal tree. */
123329 t->processTree.root = NULL;
123330 }
123331
123332 /* Compute the timestamp of the earliest next callback */
123333 UA_TimerEntry *first = ZIP_MIN(UA_TimerTree, &t->tree);
123334 UA_DateTime next = (first) ? first->nextTime : UA_INT64_MAX;
123335 if(next < nowMonotonic)
123336 next = nowMonotonic;
123337
123338 UA_UNLOCK(&t->timerMutex);
123339 return next;
123340}
123341
123342UA_DateTime
123343UA_Timer_nextRepeatedTime(UA_Timer *t) {
123344 UA_LOCK(&t->timerMutex);
123345 UA_TimerEntry *first = ZIP_MIN(UA_TimerTree, &t->tree);
123346 UA_DateTime next = (first) ? first->nextTime : UA_INT64_MAX;
123347 UA_UNLOCK(&t->timerMutex);
123348 return next;
123349}
123350
123351static void *
123352freeEntryCallback(void *context, UA_TimerEntry *entry) {
123353 UA_free(ptr: entry);
123354 return NULL;
123355}
123356
123357void
123358UA_Timer_clear(UA_Timer *t) {
123359 UA_LOCK(&t->timerMutex);
123360
123361 ZIP_ITER(UA_TimerIdTree, &t->idTree, freeEntryCallback, NULL);
123362 t->tree.root = NULL;
123363 t->idTree.root = NULL;
123364 t->idCounter = 0;
123365
123366 UA_UNLOCK(&t->timerMutex);
123367
123368#if UA_MULTITHREADING >= 100
123369 UA_LOCK_DESTROY(&t->timerMutex);
123370#endif
123371}
123372
123373/**** amalgamated original file "/arch/eventloop_common.c" ****/
123374
123375/* This Source Code Form is subject to the terms of the Mozilla Public
123376 * License, v. 2.0. If a copy of the MPL was not distributed with this
123377 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
123378 *
123379 * Copyright 2022 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
123380 */
123381
123382
123383UA_StatusCode
123384UA_KeyValueRestriction_validate(const UA_Logger *logger, const char *logprefix,
123385 const UA_KeyValueRestriction *restrictions, size_t restrictionsSize,
123386 const UA_KeyValueMap *map) {
123387 for(size_t i = 0; i < restrictionsSize; i++) {
123388 const UA_KeyValueRestriction *r = &restrictions[i];
123389 const UA_Variant *val = UA_KeyValueMap_get(map, key: r->name);
123390
123391 /* Value not present but required? */
123392 if(!val) {
123393 if(r->required) {
123394 UA_LOG_WARNING(logger, category: UA_LOGCATEGORY_USERLAND,
123395 msg: "%s\t| Parameter %.*s required but not defined",
123396 logprefix, (int)r->name.name.length, (char*)r->name.name.data);
123397 return UA_STATUSCODE_BADINTERNALERROR;
123398 }
123399 continue;
123400 }
123401
123402 /* Type matches */
123403 if(val->type != r->type) {
123404 UA_LOG_WARNING(logger, category: UA_LOGCATEGORY_USERLAND,
123405 msg: "%s\t| Parameter %.*s has the wrong type",
123406 logprefix, (int)r->name.name.length, (char*)r->name.name.data);
123407 return UA_STATUSCODE_BADINTERNALERROR;
123408 }
123409
123410 /* Scalar / array is allowed */
123411 UA_Boolean scalar = UA_Variant_isScalar(v: val);
123412 if(scalar && !r->scalar) {
123413 UA_LOG_WARNING(logger, category: UA_LOGCATEGORY_USERLAND,
123414 msg: "%s\t| Parameter %.*s must not be scalar",
123415 logprefix, (int)r->name.name.length, (char*)r->name.name.data);
123416 return UA_STATUSCODE_BADINTERNALERROR;
123417 }
123418 if(!scalar && !r->array) {
123419 UA_LOG_WARNING(logger, category: UA_LOGCATEGORY_USERLAND,
123420 msg: "%s\t| Parameter %.*s must not be an array",
123421 logprefix, (int)r->name.name.length, (char*)r->name.name.data);
123422 return UA_STATUSCODE_BADCONNECTIONREJECTED;
123423 }
123424 }
123425
123426 return UA_STATUSCODE_GOOD;
123427}
123428
123429/**** amalgamated original file "/arch/eventloop_posix.c" ****/
123430
123431/* This Source Code Form is subject to the terms of the Mozilla Public
123432 * License, v. 2.0. If a copy of the MPL was not distributed with this
123433 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
123434 *
123435 * Copyright 2021 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
123436 * Copyright 2021 (c) Fraunhofer IOSB (Author: Jan Hermes)
123437 */
123438
123439
123440/*********/
123441/* Timer */
123442/*********/
123443
123444/* Process delayed callbacks immediately */
123445static UA_DateTime
123446UA_EventLoopPOSIX_nextCyclicTime(UA_EventLoop *public_el) {
123447 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)public_el;
123448 if(el->delayedCallbacks)
123449 el->eventLoop.dateTime_nowMonotonic(&el->eventLoop);
123450 return UA_Timer_nextRepeatedTime(t: &el->timer);
123451}
123452
123453static UA_StatusCode
123454UA_EventLoopPOSIX_addTimedCallback(UA_EventLoop *public_el,
123455 UA_Callback callback,
123456 void *application, void *data,
123457 UA_DateTime date,
123458 UA_UInt64 *callbackId) {
123459 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)public_el;
123460 return UA_Timer_addTimedCallback(t: &el->timer, callback, application,
123461 data, date, callbackId);
123462}
123463
123464static UA_StatusCode
123465UA_EventLoopPOSIX_addCyclicCallback(UA_EventLoop *public_el,
123466 UA_Callback cb,
123467 void *application, void *data,
123468 UA_Double interval_ms,
123469 UA_DateTime *baseTime,
123470 UA_TimerPolicy timerPolicy,
123471 UA_UInt64 *callbackId) {
123472 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)public_el;
123473 return UA_Timer_addRepeatedCallback(t: &el->timer, callback: cb, application,
123474 data, interval_ms, baseTime,
123475 timerPolicy, callbackId);
123476}
123477
123478static UA_StatusCode
123479UA_EventLoopPOSIX_modifyCyclicCallback(UA_EventLoop *public_el,
123480 UA_UInt64 callbackId,
123481 UA_Double interval_ms,
123482 UA_DateTime *baseTime,
123483 UA_TimerPolicy timerPolicy) {
123484 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)public_el;
123485 return UA_Timer_changeRepeatedCallback(t: &el->timer, callbackId,
123486 interval_ms, baseTime,
123487 timerPolicy);
123488}
123489
123490static void
123491UA_EventLoopPOSIX_removeCyclicCallback(UA_EventLoop *public_el,
123492 UA_UInt64 callbackId) {
123493 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)public_el;
123494 UA_Timer_removeCallback(t: &el->timer, callbackId);
123495}
123496
123497static void
123498UA_EventLoopPOSIX_addDelayedCallback(UA_EventLoop *public_el,
123499 UA_DelayedCallback *dc) {
123500 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)public_el;
123501 UA_LOCK(&el->elMutex);
123502 dc->next = el->delayedCallbacks;
123503 el->delayedCallbacks = dc;
123504 UA_UNLOCK(&el->elMutex);
123505}
123506
123507static void
123508UA_EventLoopPOSIX_removeDelayedCallback(UA_EventLoop *public_el,
123509 UA_DelayedCallback *dc) {
123510 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)public_el;
123511 UA_LOCK(&el->elMutex);
123512 UA_DelayedCallback **prev = &el->delayedCallbacks;
123513 while(*prev) {
123514 if(*prev == dc) {
123515 *prev = (*prev)->next;
123516 UA_UNLOCK(&el->elMutex);
123517 return;
123518 }
123519 prev = &(*prev)->next;
123520 }
123521 UA_UNLOCK(&el->elMutex);
123522}
123523
123524/* Process and then free registered delayed callbacks */
123525static void
123526processDelayed(UA_EventLoopPOSIX *el) {
123527 UA_LOG_TRACE(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
123528 msg: "Process delayed callbacks");
123529
123530 UA_LOCK_ASSERT(&el->elMutex, 1);
123531
123532 /* First empty the linked list in the el. So a delayed callback can add
123533 * (itself) to the list. New entries are then processed during the next
123534 * iteration. */
123535 UA_DelayedCallback *dc = el->delayedCallbacks, *next = NULL;
123536 el->delayedCallbacks = NULL;
123537
123538 for(; dc; dc = next) {
123539 next = dc->next;
123540 /* Delayed Callbacks might have no callback set. We don't return a
123541 * StatusCode during "add" and don't validate. So test here. */
123542 if(!dc->callback)
123543 continue;
123544 dc->callback(dc->application, dc->context);
123545 }
123546}
123547
123548/***********************/
123549/* EventLoop Lifecycle */
123550/***********************/
123551
123552static UA_StatusCode
123553UA_EventLoopPOSIX_start(UA_EventLoopPOSIX *el) {
123554 UA_LOCK(&el->elMutex);
123555
123556 if(el->eventLoop.state != UA_EVENTLOOPSTATE_FRESH &&
123557 el->eventLoop.state != UA_EVENTLOOPSTATE_STOPPED) {
123558 UA_UNLOCK(&el->elMutex);
123559 return UA_STATUSCODE_BADINTERNALERROR;
123560 }
123561
123562 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
123563 msg: "Starting the EventLoop");
123564
123565#ifdef UA_HAVE_EPOLL
123566 el->epollfd = epoll_create1(flags: 0);
123567 if(el->epollfd == -1) {
123568 UA_LOG_SOCKET_ERRNO_WRAP(
123569 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
123570 "Eventloop\t| Could not create the epoll socket (%s)",
123571 errno_str));
123572 UA_UNLOCK(&el->elMutex);
123573 return UA_STATUSCODE_BADINTERNALERROR;
123574 }
123575#endif
123576
123577 UA_StatusCode res = UA_STATUSCODE_GOOD;
123578 UA_EventSource *es = el->eventLoop.eventSources;
123579 while(es) {
123580 res |= es->start(es);
123581 es = es->next;
123582 }
123583
123584 /* Dirty-write the state that is const "from the outside" */
123585 *(UA_EventLoopState*)(uintptr_t)&el->eventLoop.state =
123586 UA_EVENTLOOPSTATE_STARTED;
123587
123588 UA_UNLOCK(&el->elMutex);
123589 return res;
123590}
123591
123592static void
123593checkClosed(UA_EventLoopPOSIX *el) {
123594 UA_LOCK_ASSERT(&el->elMutex, 1);
123595
123596 UA_EventSource *es = el->eventLoop.eventSources;
123597 while(es) {
123598 if(es->state != UA_EVENTSOURCESTATE_STOPPED)
123599 return;
123600 es = es->next;
123601 }
123602
123603 /* Not closed until all delayed callbacks are processed */
123604 if(el->delayedCallbacks != NULL)
123605 return;
123606
123607 /* Dirty-write the state that is const "from the outside" */
123608 *(UA_EventLoopState*)(uintptr_t)&el->eventLoop.state =
123609 UA_EVENTLOOPSTATE_STOPPED;
123610
123611 /* Close the epoll/IOCP socket once all EventSources have shut down */
123612#ifdef UA_HAVE_EPOLL
123613 close(fd: el->epollfd);
123614#endif
123615
123616 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
123617 msg: "The EventLoop has stopped");
123618}
123619
123620static void
123621UA_EventLoopPOSIX_stop(UA_EventLoopPOSIX *el) {
123622 UA_LOCK(&el->elMutex);
123623
123624 if(el->eventLoop.state != UA_EVENTLOOPSTATE_STARTED) {
123625 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
123626 msg: "The EventLoop is not running, cannot be stopped");
123627 UA_UNLOCK(&el->elMutex);
123628 return;
123629 }
123630
123631 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
123632 msg: "Stopping the EventLoop");
123633
123634 /* Set to STOPPING to prevent "normal use" */
123635 *(UA_EventLoopState*)(uintptr_t)&el->eventLoop.state =
123636 UA_EVENTLOOPSTATE_STOPPING;
123637
123638 /* Stop all event sources (asynchronous) */
123639 UA_EventSource *es = el->eventLoop.eventSources;
123640 for(; es; es = es->next) {
123641 if(es->state == UA_EVENTSOURCESTATE_STARTING ||
123642 es->state == UA_EVENTSOURCESTATE_STARTED) {
123643 es->stop(es);
123644 }
123645 }
123646
123647 /* Set to STOPPED if all EventSources are STOPPED */
123648 checkClosed(el);
123649
123650 UA_UNLOCK(&el->elMutex);
123651}
123652
123653static UA_StatusCode
123654UA_EventLoopPOSIX_run(UA_EventLoopPOSIX *el, UA_UInt32 timeout) {
123655 UA_LOCK(&el->elMutex);
123656
123657 if(el->executing) {
123658 UA_LOG_ERROR(logger: el->eventLoop.logger,
123659 category: UA_LOGCATEGORY_EVENTLOOP,
123660 msg: "Cannot run EventLoop from the run method itself");
123661 UA_UNLOCK(&el->elMutex);
123662 return UA_STATUSCODE_BADINTERNALERROR;
123663 }
123664
123665 el->executing = true;
123666
123667 if(el->eventLoop.state == UA_EVENTLOOPSTATE_FRESH ||
123668 el->eventLoop.state == UA_EVENTLOOPSTATE_STOPPED) {
123669 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
123670 msg: "Cannot iterate a stopped EventLoop");
123671 el->executing = false;
123672 UA_UNLOCK(&el->elMutex);
123673 return UA_STATUSCODE_BADINTERNALERROR;
123674 }
123675
123676 UA_LOG_TRACE(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
123677 msg: "Iterate the EventLoop");
123678
123679 /* Process cyclic callbacks */
123680 UA_DateTime dateBefore =
123681 el->eventLoop.dateTime_nowMonotonic(&el->eventLoop);
123682
123683 UA_DateTime dateNext = UA_Timer_process(t: &el->timer, nowMonotonic: dateBefore);
123684
123685 /* Process delayed callbacks here:
123686 * - Removes closed sockets already here instead of polling them again.
123687 * - The timeout for polling is selected to be ready in time for the next
123688 * cyclic callback. So we want to do little work between the timeout
123689 * running out and executing the due cyclic callbacks. */
123690 processDelayed(el);
123691
123692 /* A delayed callback could create another delayed callback (or re-add
123693 * itself). In that case we don't want to wait (indefinitely) for an event
123694 * to happen. Process queued events but don't sleep. Then process the
123695 * delayed callbacks in the next iteration. */
123696 if(el->delayedCallbacks != NULL)
123697 timeout = 0;
123698
123699 /* Compute the remaining time */
123700 UA_DateTime maxDate = dateBefore + (timeout * UA_DATETIME_MSEC);
123701 if(dateNext > maxDate)
123702 dateNext = maxDate;
123703 UA_DateTime listenTimeout =
123704 dateNext - el->eventLoop.dateTime_nowMonotonic(&el->eventLoop);
123705 if(listenTimeout < 0)
123706 listenTimeout = 0;
123707
123708 /* Listen on the active file-descriptors (sockets) from the
123709 * ConnectionManagers */
123710 UA_StatusCode rv = UA_EventLoopPOSIX_pollFDs(el, listenTimeout);
123711
123712 /* Check if the last EventSource was successfully stopped */
123713 if(el->eventLoop.state == UA_EVENTLOOPSTATE_STOPPING)
123714 checkClosed(el);
123715
123716 el->executing = false;
123717 UA_UNLOCK(&el->elMutex);
123718 return rv;
123719}
123720
123721/*****************************/
123722/* Registering Event Sources */
123723/*****************************/
123724
123725static UA_StatusCode
123726UA_EventLoopPOSIX_registerEventSource(UA_EventLoopPOSIX *el,
123727 UA_EventSource *es) {
123728 UA_LOCK(&el->elMutex);
123729
123730 /* Already registered? */
123731 if(es->state != UA_EVENTSOURCESTATE_FRESH) {
123732 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
123733 msg: "Cannot register the EventSource \"%.*s\": "
123734 "already registered",
123735 (int)es->name.length, (char*)es->name.data);
123736 UA_UNLOCK(&el->elMutex);
123737 return UA_STATUSCODE_BADINTERNALERROR;
123738 }
123739
123740 /* Add to linked list */
123741 es->next = el->eventLoop.eventSources;
123742 el->eventLoop.eventSources = es;
123743
123744 es->eventLoop = &el->eventLoop;
123745 es->state = UA_EVENTSOURCESTATE_STOPPED;
123746
123747 /* Start if the entire EventLoop is started */
123748 UA_StatusCode res = UA_STATUSCODE_GOOD;
123749 if(el->eventLoop.state == UA_EVENTLOOPSTATE_STARTED)
123750 res = es->start(es);
123751
123752 UA_UNLOCK(&el->elMutex);
123753 return res;
123754}
123755
123756static UA_StatusCode
123757UA_EventLoopPOSIX_deregisterEventSource(UA_EventLoopPOSIX *el,
123758 UA_EventSource *es) {
123759 UA_LOCK(&el->elMutex);
123760
123761 if(es->state != UA_EVENTSOURCESTATE_STOPPED) {
123762 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
123763 msg: "Cannot deregister the EventSource %.*s: "
123764 "Has to be stopped first",
123765 (int)es->name.length, es->name.data);
123766 UA_UNLOCK(&el->elMutex);
123767 return UA_STATUSCODE_BADINTERNALERROR;
123768 }
123769
123770 /* Remove from the linked list */
123771 UA_EventSource **s = &el->eventLoop.eventSources;
123772 while(*s) {
123773 if(*s == es) {
123774 *s = es->next;
123775 break;
123776 }
123777 s = &(*s)->next;
123778 }
123779
123780 /* Set the state to non-registered */
123781 es->state = UA_EVENTSOURCESTATE_FRESH;
123782
123783 UA_UNLOCK(&el->elMutex);
123784 return UA_STATUSCODE_GOOD;
123785}
123786
123787/***************/
123788/* Time Domain */
123789/***************/
123790
123791/* No special synchronization with an external source, just use the globally
123792 * defined functions. */
123793
123794static UA_DateTime
123795UA_EventLoopPOSIX_DateTime_now(UA_EventLoop *el) {
123796 return UA_DateTime_now();
123797}
123798
123799static UA_DateTime
123800UA_EventLoopPOSIX_DateTime_nowMonotonic(UA_EventLoop *el) {
123801 return UA_DateTime_nowMonotonic();
123802}
123803
123804static UA_Int64
123805UA_EventLoopPOSIX_DateTime_localTimeUtcOffset(UA_EventLoop *el) {
123806 return UA_DateTime_localTimeUtcOffset();
123807}
123808
123809/*************************/
123810/* Initialize and Delete */
123811/*************************/
123812
123813static UA_StatusCode
123814UA_EventLoopPOSIX_free(UA_EventLoopPOSIX *el) {
123815 UA_LOCK(&el->elMutex);
123816
123817 /* Check if the EventLoop can be deleted */
123818 if(el->eventLoop.state != UA_EVENTLOOPSTATE_STOPPED &&
123819 el->eventLoop.state != UA_EVENTLOOPSTATE_FRESH) {
123820 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
123821 msg: "Cannot delete a running EventLoop");
123822 UA_UNLOCK(&el->elMutex);
123823 return UA_STATUSCODE_BADINTERNALERROR;
123824 }
123825
123826 /* Deregister and delete all the EventSources */
123827 while(el->eventLoop.eventSources) {
123828 UA_EventSource *es = el->eventLoop.eventSources;
123829 UA_EventLoopPOSIX_deregisterEventSource(el, es);
123830 es->free(es);
123831 }
123832
123833 /* Remove the repeated timed callbacks */
123834 UA_Timer_clear(t: &el->timer);
123835
123836 /* Process remaining delayed callbacks */
123837 processDelayed(el);
123838
123839#ifdef UA_ARCHITECTURE_WIN32
123840 /* Stop the Windows networking subsystem */
123841 WSACleanup();
123842#endif
123843
123844 /* Clean up */
123845 UA_UNLOCK(&el->elMutex);
123846 UA_LOCK_DESTROY(&el->elMutex);
123847 UA_free(ptr: el);
123848 return UA_STATUSCODE_GOOD;
123849}
123850
123851static void
123852UA_EventLoopPOSIX_lock(UA_EventLoop *public_el) {
123853 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)public_el;
123854 UA_LOCK(&el->elMutex);
123855}
123856
123857static void
123858UA_EventLoopPOSIX_unlock(UA_EventLoop *public_el) {
123859 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)public_el;
123860 UA_UNLOCK(&el->elMutex);
123861}
123862
123863UA_EventLoop *
123864UA_EventLoop_new_POSIX(const UA_Logger *logger) {
123865 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)
123866 UA_calloc(nmemb: 1, size: sizeof(UA_EventLoopPOSIX));
123867 if(!el)
123868 return NULL;
123869
123870 UA_LOCK_INIT(&el->elMutex);
123871 UA_Timer_init(t: &el->timer);
123872
123873#ifdef UA_ARCHITECTURE_WIN32
123874 /* Start the WSA networking subsystem on Windows */
123875 WSADATA wsaData;
123876 WSAStartup(MAKEWORD(2, 2), &wsaData);
123877#endif
123878
123879 /* Set the public EventLoop content */
123880 el->eventLoop.logger = logger;
123881
123882 el->eventLoop.start = (UA_StatusCode (*)(UA_EventLoop*))UA_EventLoopPOSIX_start;
123883 el->eventLoop.stop = (void (*)(UA_EventLoop*))UA_EventLoopPOSIX_stop;
123884 el->eventLoop.run = (UA_StatusCode (*)(UA_EventLoop*, UA_UInt32))UA_EventLoopPOSIX_run;
123885 el->eventLoop.free = (UA_StatusCode (*)(UA_EventLoop*))UA_EventLoopPOSIX_free;
123886
123887 el->eventLoop.dateTime_now = UA_EventLoopPOSIX_DateTime_now;
123888 el->eventLoop.dateTime_nowMonotonic =
123889 UA_EventLoopPOSIX_DateTime_nowMonotonic;
123890 el->eventLoop.dateTime_localTimeUtcOffset =
123891 UA_EventLoopPOSIX_DateTime_localTimeUtcOffset;
123892
123893 el->eventLoop.nextCyclicTime = UA_EventLoopPOSIX_nextCyclicTime;
123894 el->eventLoop.addCyclicCallback = UA_EventLoopPOSIX_addCyclicCallback;
123895 el->eventLoop.modifyCyclicCallback = UA_EventLoopPOSIX_modifyCyclicCallback;
123896 el->eventLoop.removeCyclicCallback = UA_EventLoopPOSIX_removeCyclicCallback;
123897 el->eventLoop.addTimedCallback = UA_EventLoopPOSIX_addTimedCallback;
123898 el->eventLoop.addDelayedCallback = UA_EventLoopPOSIX_addDelayedCallback;
123899 el->eventLoop.removeDelayedCallback = UA_EventLoopPOSIX_removeDelayedCallback;
123900
123901 el->eventLoop.registerEventSource =
123902 (UA_StatusCode (*)(UA_EventLoop*, UA_EventSource*))
123903 UA_EventLoopPOSIX_registerEventSource;
123904 el->eventLoop.deregisterEventSource =
123905 (UA_StatusCode (*)(UA_EventLoop*, UA_EventSource*))
123906 UA_EventLoopPOSIX_deregisterEventSource;
123907
123908 el->eventLoop.lock = UA_EventLoopPOSIX_lock;
123909 el->eventLoop.unlock = UA_EventLoopPOSIX_unlock;
123910
123911 return &el->eventLoop;
123912}
123913
123914/* Reusable EventSource functionality */
123915
123916UA_StatusCode
123917UA_EventLoopPOSIX_allocNetworkBuffer(UA_ConnectionManager *cm,
123918 uintptr_t connectionId,
123919 UA_ByteString *buf,
123920 size_t bufSize) {
123921 return UA_ByteString_allocBuffer(bs: buf, length: bufSize);
123922}
123923
123924void
123925UA_EventLoopPOSIX_freeNetworkBuffer(UA_ConnectionManager *cm,
123926 uintptr_t connectionId,
123927 UA_ByteString *buf) {
123928 UA_ByteString_clear(p: buf);
123929}
123930
123931UA_StatusCode
123932UA_EventLoopPOSIX_allocateRXBuffer(UA_POSIXConnectionManager *pcm) {
123933 UA_UInt32 rxBufSize = 2u << 16; /* The default is 64kb */
123934 const UA_UInt32 *configRxBufSize = (const UA_UInt32 *)
123935 UA_KeyValueMap_getScalar(map: &pcm->cm.eventSource.params,
123936 key: UA_QUALIFIEDNAME(nsIndex: 0, chars: "recv-bufsize"),
123937 type: &UA_TYPES[UA_TYPES_UINT32]);
123938 if(configRxBufSize)
123939 rxBufSize = *configRxBufSize;
123940 if(pcm->rxBuffer.length != rxBufSize) {
123941 UA_ByteString_clear(p: &pcm->rxBuffer);
123942 return UA_ByteString_allocBuffer(bs: &pcm->rxBuffer, length: rxBufSize);
123943 }
123944 return UA_STATUSCODE_GOOD;
123945}
123946
123947/* Socket Handling */
123948
123949enum ZIP_CMP
123950cmpFD(const UA_FD *a, const UA_FD *b) {
123951 if(*a == *b)
123952 return ZIP_CMP_EQ;
123953 return (*a < *b) ? ZIP_CMP_LESS : ZIP_CMP_MORE;
123954}
123955
123956UA_StatusCode
123957UA_EventLoopPOSIX_setNonBlocking(UA_FD sockfd) {
123958#ifndef UA_ARCHITECTURE_WIN32
123959 int opts = fcntl(fd: sockfd, F_GETFL);
123960 if(opts < 0 || fcntl(fd: sockfd, F_SETFL, opts | O_NONBLOCK) < 0)
123961 return UA_STATUSCODE_BADINTERNALERROR;
123962#else
123963 u_long iMode = 1;
123964 if(ioctlsocket(sockfd, FIONBIO, &iMode) != NO_ERROR)
123965 return UA_STATUSCODE_BADINTERNALERROR;
123966#endif
123967 return UA_STATUSCODE_GOOD;
123968}
123969
123970UA_StatusCode
123971UA_EventLoopPOSIX_setNoSigPipe(UA_FD sockfd) {
123972#ifdef SO_NOSIGPIPE
123973 int val = 1;
123974 int res = UA_setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val));
123975 if(res < 0)
123976 return UA_STATUSCODE_BADINTERNALERROR;
123977#endif
123978 return UA_STATUSCODE_GOOD;
123979}
123980
123981UA_StatusCode
123982UA_EventLoopPOSIX_setReusable(UA_FD sockfd) {
123983 int enableReuseVal = 1;
123984#ifndef UA_ARCHITECTURE_WIN32
123985 int res = UA_setsockopt(fd: sockfd, SOL_SOCKET, SO_REUSEADDR,
123986 optval: (const char*)&enableReuseVal, optlen: sizeof(enableReuseVal));
123987 res |= UA_setsockopt(fd: sockfd, SOL_SOCKET, SO_REUSEPORT,
123988 optval: (const char*)&enableReuseVal, optlen: sizeof(enableReuseVal));
123989 return (res == 0) ? UA_STATUSCODE_GOOD : UA_STATUSCODE_BADINTERNALERROR;
123990#else
123991 int res = UA_setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
123992 (const char*)&enableReuseVal, sizeof(enableReuseVal));
123993 return (res == 0) ? UA_STATUSCODE_GOOD : UA_STATUSCODE_BADINTERNALERROR;
123994#endif
123995}
123996
123997/**** amalgamated original file "/arch/eventloop_posix_select.c" ****/
123998
123999/* This Source Code Form is subject to the terms of the Mozilla Public
124000 * License, v. 2.0. If a copy of the MPL was not distributed with this
124001 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
124002 *
124003 * Copyright 2021 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
124004 */
124005
124006
124007#if !defined(UA_HAVE_EPOLL)
124008
124009UA_StatusCode
124010UA_EventLoopPOSIX_registerFD(UA_EventLoopPOSIX *el, UA_RegisteredFD *rfd) {
124011 UA_LOCK_ASSERT(&el->elMutex, 1);
124012 UA_LOG_DEBUG(el->eventLoop.logger, UA_LOGCATEGORY_EVENTLOOP,
124013 "Registering fd: %u", (unsigned)rfd->fd);
124014
124015 /* Realloc */
124016 UA_RegisteredFD **fds_tmp = (UA_RegisteredFD**)
124017 UA_realloc(el->fds, sizeof(UA_RegisteredFD*) * (el->fdsSize + 1));
124018 if(!fds_tmp) {
124019 return UA_STATUSCODE_BADOUTOFMEMORY;
124020 }
124021 el->fds = fds_tmp;
124022
124023 /* Add to the last entry */
124024 el->fds[el->fdsSize] = rfd;
124025 el->fdsSize++;
124026 return UA_STATUSCODE_GOOD;
124027}
124028
124029UA_StatusCode
124030UA_EventLoopPOSIX_modifyFD(UA_EventLoopPOSIX *el, UA_RegisteredFD *rfd) {
124031 /* Do nothing, it is enough if the data was changed in the rfd */
124032 UA_LOCK_ASSERT(&el->elMutex, 1);
124033 return UA_STATUSCODE_GOOD;
124034}
124035
124036void
124037UA_EventLoopPOSIX_deregisterFD(UA_EventLoopPOSIX *el, UA_RegisteredFD *rfd) {
124038 UA_LOCK_ASSERT(&el->elMutex, 1);
124039 UA_LOG_DEBUG(el->eventLoop.logger, UA_LOGCATEGORY_EVENTLOOP,
124040 "Unregistering fd: %u", (unsigned)rfd->fd);
124041
124042 /* Find the entry */
124043 size_t i = 0;
124044 for(; i < el->fdsSize; i++) {
124045 if(el->fds[i] == rfd)
124046 break;
124047 }
124048
124049 /* Not found? */
124050 if(i == el->fdsSize)
124051 return;
124052
124053 if(el->fdsSize > 1) {
124054 /* Move the last entry in the ith slot and realloc. */
124055 el->fdsSize--;
124056 el->fds[i] = el->fds[el->fdsSize];
124057 UA_RegisteredFD **fds_tmp = (UA_RegisteredFD**)
124058 UA_realloc(el->fds, sizeof(UA_RegisteredFD*) * el->fdsSize);
124059 /* if realloc fails the fds are still in a correct state with
124060 * possibly lost memory, so failing silently here is ok */
124061 if(fds_tmp)
124062 el->fds = fds_tmp;
124063 } else {
124064 /* Remove the last entry */
124065 UA_free(el->fds);
124066 el->fds = NULL;
124067 el->fdsSize = 0;
124068 }
124069}
124070
124071static UA_FD
124072setFDSets(UA_EventLoopPOSIX *el, fd_set *readset, fd_set *writeset, fd_set *errset) {
124073 UA_LOCK_ASSERT(&el->elMutex, 1);
124074
124075 FD_ZERO(readset);
124076 FD_ZERO(writeset);
124077 FD_ZERO(errset);
124078 UA_FD highestfd = UA_INVALID_FD;
124079 for(size_t i = 0; i < el->fdsSize; i++) {
124080 UA_FD currentFD = el->fds[i]->fd;
124081
124082 /* Add to the fd_sets */
124083 if(el->fds[i]->listenEvents & UA_FDEVENT_IN)
124084 FD_SET(currentFD, readset);
124085 if(el->fds[i]->listenEvents & UA_FDEVENT_OUT)
124086 FD_SET(currentFD, writeset);
124087
124088 /* Always return errors */
124089 FD_SET(currentFD, errset);
124090
124091 /* Highest fd? */
124092 if(currentFD > highestfd || highestfd == UA_INVALID_FD)
124093 highestfd = currentFD;
124094 }
124095 return highestfd;
124096}
124097
124098UA_StatusCode
124099UA_EventLoopPOSIX_pollFDs(UA_EventLoopPOSIX *el, UA_DateTime listenTimeout) {
124100 UA_assert(listenTimeout >= 0);
124101 UA_LOCK_ASSERT(&el->elMutex, 1);
124102
124103 fd_set readset, writeset, errset;
124104 UA_FD highestfd = setFDSets(el, &readset, &writeset, &errset);
124105
124106 /* Nothing to do? */
124107 if(highestfd == UA_INVALID_FD) {
124108 UA_LOG_TRACE(el->eventLoop.logger, UA_LOGCATEGORY_EVENTLOOP,
124109 "No valid FDs for processing");
124110 return UA_STATUSCODE_GOOD;
124111 }
124112
124113 struct timeval tmptv = {
124114#ifndef UA_ARCHITECTURE_WIN32
124115 (time_t)(listenTimeout / UA_DATETIME_SEC),
124116 (suseconds_t)((listenTimeout % UA_DATETIME_SEC) / UA_DATETIME_USEC)
124117#else
124118 (long)(listenTimeout / UA_DATETIME_SEC),
124119 (long)((listenTimeout % UA_DATETIME_SEC) / UA_DATETIME_USEC)
124120#endif
124121 };
124122
124123 UA_UNLOCK(&el->elMutex);
124124 int selectStatus = UA_select(highestfd+1, &readset, &writeset, &errset, &tmptv);
124125 UA_LOCK(&el->elMutex);
124126 if(selectStatus < 0) {
124127 /* We will retry, only log the error */
124128 UA_LOG_SOCKET_ERRNO_WRAP(
124129 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_EVENTLOOP,
124130 "Error during select: %s", errno_str));
124131 return UA_STATUSCODE_GOOD;
124132 }
124133
124134 /* Loop over all registered FD to see if an event arrived. Yes, this is why
124135 * select is slow for many open sockets. */
124136 for(size_t i = 0; i < el->fdsSize; i++) {
124137 UA_RegisteredFD *rfd = el->fds[i];
124138
124139 /* The rfd is already registered for removal. Don't process incoming
124140 * events any longer. */
124141 if(rfd->dc.callback)
124142 continue;
124143
124144 /* Event signaled for the fd? */
124145 short event = 0;
124146 if(FD_ISSET(rfd->fd, &readset)) {
124147 event = UA_FDEVENT_IN;
124148 } else if(FD_ISSET(rfd->fd, &writeset)) {
124149 event = UA_FDEVENT_OUT;
124150 } else if(FD_ISSET(rfd->fd, &errset)) {
124151 event = UA_FDEVENT_ERR;
124152 } else {
124153 continue;
124154 }
124155
124156 UA_LOG_DEBUG(el->eventLoop.logger, UA_LOGCATEGORY_EVENTLOOP,
124157 "Processing event %u on fd %u", (unsigned)event,
124158 (unsigned)rfd->fd);
124159
124160 /* Call the EventSource callback */
124161 rfd->eventSourceCB(rfd->es, rfd, event);
124162
124163 /* The fd has removed itself */
124164 if(i == el->fdsSize || rfd != el->fds[i])
124165 i--;
124166 }
124167 return UA_STATUSCODE_GOOD;
124168}
124169
124170#endif /* !defined(UA_HAVE_EPOLL) */
124171
124172/**** amalgamated original file "/arch/eventloop_posix_epoll.c" ****/
124173
124174/* This Source Code Form is subject to the terms of the Mozilla Public
124175 * License, v. 2.0. If a copy of the MPL was not distributed with this
124176 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
124177 *
124178 * Copyright 2021 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
124179 */
124180
124181
124182#if defined(UA_HAVE_EPOLL)
124183
124184UA_StatusCode
124185UA_EventLoopPOSIX_registerFD(UA_EventLoopPOSIX *el, UA_RegisteredFD *rfd) {
124186 struct epoll_event event;
124187 memset(s: &event, c: 0, n: sizeof(struct epoll_event));
124188 event.data.ptr = rfd;
124189 event.events = 0;
124190 if(rfd->listenEvents & UA_FDEVENT_IN)
124191 event.events |= EPOLLIN;
124192 if(rfd->listenEvents & UA_FDEVENT_OUT)
124193 event.events |= EPOLLOUT;
124194
124195 int err = epoll_ctl(epfd: el->epollfd, EPOLL_CTL_ADD, fd: rfd->fd, event: &event);
124196 if(err != 0) {
124197 UA_LOG_SOCKET_ERRNO_WRAP(
124198 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
124199 "TCP %u\t| Could not register for epoll (%s)",
124200 rfd->fd, errno_str));
124201 return UA_STATUSCODE_BADINTERNALERROR;
124202 }
124203 return UA_STATUSCODE_GOOD;
124204}
124205
124206UA_StatusCode
124207UA_EventLoopPOSIX_modifyFD(UA_EventLoopPOSIX *el, UA_RegisteredFD *rfd) {
124208 struct epoll_event event;
124209 memset(s: &event, c: 0, n: sizeof(struct epoll_event));
124210 event.data.ptr = rfd;
124211 event.events = 0;
124212 if(rfd->listenEvents & UA_FDEVENT_IN)
124213 event.events |= EPOLLIN;
124214 if(rfd->listenEvents & UA_FDEVENT_OUT)
124215 event.events |= EPOLLOUT;
124216
124217 int err = epoll_ctl(epfd: el->epollfd, EPOLL_CTL_MOD, fd: rfd->fd, event: &event);
124218 if(err != 0) {
124219 UA_LOG_SOCKET_ERRNO_WRAP(
124220 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
124221 "TCP %u\t| Could not modify for epoll (%s)",
124222 rfd->fd, errno_str));
124223 return UA_STATUSCODE_BADINTERNALERROR;
124224 }
124225 return UA_STATUSCODE_GOOD;
124226}
124227
124228void
124229UA_EventLoopPOSIX_deregisterFD(UA_EventLoopPOSIX *el, UA_RegisteredFD *rfd) {
124230 int res = epoll_ctl(epfd: el->epollfd, EPOLL_CTL_DEL, fd: rfd->fd, NULL);
124231 if(res != 0) {
124232 UA_LOG_SOCKET_ERRNO_WRAP(
124233 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
124234 "TCP %u\t| Could not deregister from epoll (%s)",
124235 rfd->fd, errno_str));
124236 }
124237}
124238
124239UA_StatusCode
124240UA_EventLoopPOSIX_pollFDs(UA_EventLoopPOSIX *el, UA_DateTime listenTimeout) {
124241 UA_assert(listenTimeout >= 0);
124242
124243 /* If there is a positive timeout, wait at least one millisecond, the
124244 * minimum for blocking epoll_wait. This prevents a busy-loop, as the
124245 * open62541 library allows even smaller timeouts, which can result in a
124246 * zero timeout due to rounding to an integer here. */
124247 int timeout = (int)(listenTimeout / UA_DATETIME_MSEC);
124248 if(timeout == 0 && listenTimeout > 0)
124249 timeout = 1;
124250
124251 /* Poll the registered sockets */
124252 struct epoll_event epoll_events[64];
124253 UA_UNLOCK(&el->elMutex);
124254 int events = epoll_wait(epfd: el->epollfd, events: epoll_events, maxevents: 64, timeout: timeout);
124255 UA_LOCK(&el->elMutex);
124256
124257 /* TODO: Replace with pwait2 for higher-precision timeouts once this is
124258 * available in the standard library.
124259 *
124260 * struct timespec precisionTimeout = {
124261 * (long)(listenTimeout / UA_DATETIME_SEC),
124262 * (long)((listenTimeout % UA_DATETIME_SEC) * 100)
124263 * };
124264 * int events = epoll_pwait2(epollfd, epoll_events, 64,
124265 * precisionTimeout, NULL); */
124266
124267 /* Handle error conditions */
124268 if(events == -1) {
124269 if(errno == EINTR) {
124270 /* We will retry, only log the error */
124271 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
124272 msg: "Timeout during poll");
124273 return UA_STATUSCODE_GOOD;
124274 }
124275 UA_LOG_SOCKET_ERRNO_WRAP(
124276 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
124277 "TCP\t| Error %s, closing the server socket",
124278 errno_str));
124279 return UA_STATUSCODE_BADINTERNALERROR;
124280 }
124281
124282 /* Process all received events */
124283 for(int i = 0; i < events; i++) {
124284 UA_RegisteredFD *rfd = (UA_RegisteredFD*)epoll_events[i].data.ptr;
124285
124286 /* The rfd is already registered for removal. Don't process incoming
124287 * events any longer. */
124288 if(rfd->dc.callback)
124289 continue;
124290
124291 /* Get the event */
124292 short revent = 0;
124293 if((epoll_events[i].events & EPOLLIN) == EPOLLIN) {
124294 revent = UA_FDEVENT_IN;
124295 } else if((epoll_events[i].events & EPOLLOUT) == EPOLLOUT) {
124296 revent = UA_FDEVENT_OUT;
124297 } else {
124298 revent = UA_FDEVENT_ERR;
124299 }
124300
124301 /* Call the EventSource callback */
124302 rfd->eventSourceCB(rfd->es, rfd, revent);
124303 }
124304 return UA_STATUSCODE_GOOD;
124305}
124306
124307#endif /* defined(UA_HAVE_EPOLL) */
124308
124309/**** amalgamated original file "/arch/eventloop_posix_tcp.c" ****/
124310
124311/* This Source Code Form is subject to the terms of the Mozilla Public
124312 * License, v. 2.0. If a copy of the MPL was not distributed with this
124313 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
124314 *
124315 * Copyright 2021-2022 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
124316 * Copyright 2021 (c) Fraunhofer IOSB (Author: Jan Hermes)
124317 */
124318
124319
124320/* Configuration parameters */
124321#define TCP_PARAMETERSSIZE 6
124322#define TCP_PARAMINDEX_RECVBUF 0
124323#define TCP_PARAMINDEX_ADDR 1
124324#define TCP_PARAMINDEX_PORT 2
124325#define TCP_PARAMINDEX_LISTEN 3
124326#define TCP_PARAMINDEX_VALIDATE 4
124327#define TCP_PARAMINDEX_REUSE 5
124328
124329static UA_KeyValueRestriction TCPConfigParameters[TCP_PARAMETERSSIZE] = {
124330 {{0, UA_STRING_STATIC("recv-bufsize")}, &UA_TYPES[UA_TYPES_UINT32], false, true, false},
124331 {{0, UA_STRING_STATIC("address")}, &UA_TYPES[UA_TYPES_STRING], false, true, true},
124332 {{0, UA_STRING_STATIC("port")}, &UA_TYPES[UA_TYPES_UINT16], true, true, false},
124333 {{0, UA_STRING_STATIC("listen")}, &UA_TYPES[UA_TYPES_BOOLEAN], false, true, false},
124334 {{0, UA_STRING_STATIC("validate")}, &UA_TYPES[UA_TYPES_BOOLEAN], false, true, false},
124335 {{0, UA_STRING_STATIC("reuse")}, &UA_TYPES[UA_TYPES_BOOLEAN], false, true, false}
124336};
124337
124338typedef struct {
124339 UA_RegisteredFD rfd;
124340
124341 UA_ConnectionManager_connectionCallback applicationCB;
124342 void *application;
124343 void *context;
124344} TCP_FD;
124345
124346static void
124347TCP_shutdown(UA_ConnectionManager *cm, TCP_FD *conn);
124348
124349/* Do not merge packets on the socket (disable Nagle's algorithm) */
124350static UA_StatusCode
124351TCP_setNoNagle(UA_FD sockfd) {
124352 int val = 1;
124353 int res = UA_setsockopt(fd: sockfd, IPPROTO_TCP, TCP_NODELAY, optval: &val, optlen: sizeof(val));
124354 if(res < 0)
124355 return UA_STATUSCODE_BADINTERNALERROR;
124356 return UA_STATUSCODE_GOOD;
124357}
124358
124359/* Test if the ConnectionManager can be stopped */
124360static void
124361TCP_checkStopped(UA_POSIXConnectionManager *pcm) {
124362 UA_LOCK_ASSERT(&((UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop)->elMutex, 1);
124363
124364 if(pcm->fdsSize == 0 &&
124365 pcm->cm.eventSource.state == UA_EVENTSOURCESTATE_STOPPING) {
124366 UA_LOG_DEBUG(logger: pcm->cm.eventSource.eventLoop->logger, category: UA_LOGCATEGORY_NETWORK,
124367 msg: "TCP\t| All sockets closed, the EventLoop has stopped");
124368 pcm->cm.eventSource.state = UA_EVENTSOURCESTATE_STOPPED;
124369 }
124370}
124371
124372static void
124373TCP_delayedClose(void *application, void *context) {
124374 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)application;
124375 UA_ConnectionManager *cm = &pcm->cm;
124376 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
124377 TCP_FD *conn = (TCP_FD*)context;
124378
124379 UA_LOCK(&el->elMutex);
124380
124381 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
124382 msg: "TCP %u\t| Delayed closing of the connection",
124383 (unsigned)conn->rfd.fd);
124384
124385 /* Ensure reuse is possible right away. Port-stealing is no longer an issue
124386 * as the socket gets closed anyway. And we do not want to wait for the
124387 * timeout to open a new socket for the same address and port. */
124388 UA_EventLoopPOSIX_setReusable(sockfd: conn->rfd.fd);
124389
124390 /* Deregister from the EventLoop */
124391 UA_EventLoopPOSIX_deregisterFD(el, rfd: &conn->rfd);
124392
124393 /* Deregister internally */
124394 ZIP_REMOVE(UA_FDTree, &pcm->fds, &conn->rfd);
124395 UA_assert(pcm->fdsSize > 0);
124396 pcm->fdsSize--;
124397
124398 /* Signal closing to the application */
124399 conn->applicationCB(cm, (uintptr_t)conn->rfd.fd,
124400 conn->application, &conn->context,
124401 UA_CONNECTIONSTATE_CLOSING,
124402 &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL);
124403
124404 /* Close the socket */
124405 int ret = UA_close(fd: conn->rfd.fd);
124406 if(ret == 0) {
124407 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124408 msg: "TCP %u\t| Socket closed", (unsigned)conn->rfd.fd);
124409 } else {
124410 UA_LOG_SOCKET_ERRNO_WRAP(
124411 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
124412 "TCP %u\t| Could not close the socket (%s)",
124413 (unsigned)conn->rfd.fd, errno_str));
124414 }
124415
124416 UA_free(ptr: conn);
124417
124418 /* Check if this was the last connection for a closing ConnectionManager */
124419 TCP_checkStopped(pcm);
124420
124421 UA_UNLOCK(&el->elMutex);
124422}
124423
124424static int
124425getSockError(TCP_FD *conn) {
124426 int error = 0;
124427#ifndef UA_ARCHITECTURE_WIN32
124428 socklen_t errlen = sizeof(int);
124429 int err = getsockopt(fd: conn->rfd.fd, SOL_SOCKET, SO_ERROR, optval: &error, optlen: &errlen);
124430#else
124431 int errlen = (int)sizeof(int);
124432 int err = getsockopt((SOCKET)conn->rfd.fd, SOL_SOCKET, SO_ERROR,
124433 (char*)&error, &errlen);
124434#endif
124435 return (err == 0) ? error : err;
124436}
124437
124438/* Gets called when a connection socket opens, receives data or closes */
124439static void
124440TCP_connectionSocketCallback(UA_ConnectionManager *cm, TCP_FD *conn,
124441 short event) {
124442 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
124443 UA_LOCK_ASSERT(&el->elMutex, 1);
124444
124445 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124446 msg: "TCP %u\t| Activity on the socket",
124447 (unsigned)conn->rfd.fd);
124448
124449 /* Error. The connection has closed. */
124450 if(event == UA_FDEVENT_ERR) {
124451 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124452 msg: "TCP %u\t| The connection closes with error %i",
124453 (unsigned)conn->rfd.fd, getSockError(conn));
124454 TCP_shutdown(cm, conn);
124455 return;
124456 }
124457
124458 /* Write-Event, a new connection has opened. But some errors come as an
124459 * out-event. For example if the remote side could not be reached to
124460 * initiate the connection. So we check manually for error conditions on
124461 * the socket. */
124462 if(event == UA_FDEVENT_OUT) {
124463 int error = getSockError(conn);
124464 if(error != 0) {
124465 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124466 msg: "TCP %u\t| The connection closes with error %i",
124467 (unsigned)conn->rfd.fd, error);
124468 TCP_shutdown(cm, conn);
124469 return;
124470 }
124471
124472 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124473 msg: "TCP %u\t| Opening a new connection",
124474 (unsigned)conn->rfd.fd);
124475
124476 /* Now we are interested in read-events. */
124477 conn->rfd.listenEvents = UA_FDEVENT_IN;
124478 UA_EventLoopPOSIX_modifyFD(el, rfd: &conn->rfd);
124479
124480 /* A new socket has opened. Signal it to the application. */
124481 conn->applicationCB(cm, (uintptr_t)conn->rfd.fd,
124482 conn->application, &conn->context,
124483 UA_CONNECTIONSTATE_ESTABLISHED,
124484 &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL);
124485 return;
124486 }
124487
124488 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124489 msg: "TCP %u\t| Allocate receive buffer",
124490 (unsigned)conn->rfd.fd);
124491
124492 /* Use the already allocated receive-buffer */
124493 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
124494 UA_ByteString response = pcm->rxBuffer;
124495
124496 /* Receive */
124497#ifndef UA_ARCHITECTURE_WIN32
124498 ssize_t ret = UA_recv(fd: conn->rfd.fd, buf: (char*)response.data,
124499 n: response.length, MSG_DONTWAIT);
124500#else
124501 int ret = UA_recv(conn->rfd.fd, (char*)response.data,
124502 response.length, MSG_DONTWAIT);
124503#endif
124504
124505 /* Receive has failed */
124506 if(ret <= 0) {
124507 if(UA_ERRNO == UA_INTERRUPTED ||
124508 UA_ERRNO == UA_WOULDBLOCK ||
124509 UA_ERRNO == UA_AGAIN)
124510 return; /* Temporary error on an non-blocking socket */
124511
124512 /* Orderly shutdown of the socket */
124513 UA_LOG_SOCKET_ERRNO_WRAP(
124514 UA_LOG_DEBUG(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
124515 "TCP %u\t| recv signaled the socket was shutdown (%s)",
124516 (unsigned)conn->rfd.fd, errno_str));
124517 TCP_shutdown(cm, conn);
124518 return;
124519 }
124520
124521 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124522 msg: "TCP %u\t| Received message of size %u",
124523 (unsigned)conn->rfd.fd, (unsigned)ret);
124524
124525 /* Callback to the application layer */
124526 response.length = (size_t)ret; /* Set the length of the received buffer */
124527 conn->applicationCB(cm, (uintptr_t)conn->rfd.fd,
124528 conn->application, &conn->context,
124529 UA_CONNECTIONSTATE_ESTABLISHED,
124530 &UA_KEYVALUEMAP_NULL, response);
124531}
124532
124533/* Gets called when a new connection opens or if the listenSocket is closed */
124534static void
124535TCP_listenSocketCallback(UA_ConnectionManager *cm, TCP_FD *conn, short event) {
124536 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
124537 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
124538 UA_LOCK_ASSERT(&el->elMutex, 1);
124539
124540 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124541 msg: "TCP %u\t| Callback on server socket",
124542 (unsigned)conn->rfd.fd);
124543
124544 /* Try to accept a new connection */
124545 struct sockaddr_storage remote;
124546 socklen_t remote_size = sizeof(remote);
124547 UA_FD newsockfd = accept(fd: conn->rfd.fd, addr: (struct sockaddr*)&remote, addr_len: &remote_size);
124548 if(newsockfd == UA_INVALID_FD) {
124549 /* Temporary error -- retry */
124550 if(UA_ERRNO == UA_INTERRUPTED)
124551 return;
124552
124553 /* Close the listen socket */
124554 if(cm->eventSource.state != UA_EVENTSOURCESTATE_STOPPING) {
124555 UA_LOG_SOCKET_ERRNO_WRAP(
124556 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
124557 "TCP %u\t| Error %s, closing the server socket",
124558 (unsigned)conn->rfd.fd, errno_str));
124559 }
124560
124561 TCP_shutdown(cm, conn);
124562 return;
124563 }
124564
124565 /* Log the name of the remote host */
124566 char hoststr[UA_MAXHOSTNAME_LENGTH];
124567 int get_res = UA_getnameinfo((struct sockaddr *)&remote, sizeof(remote),
124568 hoststr, sizeof(hoststr),
124569 NULL, 0, NI_NUMERICHOST);
124570 if(get_res != 0) {
124571 UA_LOG_SOCKET_ERRNO_WRAP(
124572 UA_LOG_WARNING(cm->eventSource.eventLoop->logger, UA_LOGCATEGORY_NETWORK,
124573 "TCP %u\t| getnameinfo(...) could not resolve the "
124574 "hostname (%s)", (unsigned)conn->rfd.fd, errno_str));
124575 }
124576 UA_LOG_INFO(logger: cm->eventSource.eventLoop->logger, category: UA_LOGCATEGORY_NETWORK,
124577 msg: "TCP %u\t| Connection opened from \"%s\" via the server socket %u",
124578 (unsigned)newsockfd, hoststr, (unsigned)conn->rfd.fd);
124579
124580 /* Configure the new socket */
124581 UA_StatusCode res = UA_STATUSCODE_GOOD;
124582 /* res |= UA_EventLoopPOSIX_setNonBlocking(newsockfd); Inherited from the listen-socket */
124583 res |= UA_EventLoopPOSIX_setNoSigPipe(sockfd: newsockfd); /* Supress interrupts from the socket */
124584 res |= TCP_setNoNagle(sockfd: newsockfd); /* Disable Nagle's algorithm */
124585 if(res != UA_STATUSCODE_GOOD) {
124586 UA_LOG_SOCKET_ERRNO_WRAP(
124587 UA_LOG_WARNING(cm->eventSource.eventLoop->logger, UA_LOGCATEGORY_NETWORK,
124588 "TCP %u\t| Error seeting the TCP options (%s)",
124589 (unsigned)newsockfd, errno_str));
124590 /* Close the new socket */
124591 UA_close(fd: newsockfd);
124592 return;
124593 }
124594
124595 /* Allocate the UA_RegisteredFD */
124596 TCP_FD *newConn = (TCP_FD*)UA_calloc(nmemb: 1, size: sizeof(TCP_FD));
124597 if(!newConn) {
124598 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124599 msg: "TCP %u\t| Error allocating memory for the socket",
124600 (unsigned)newsockfd);
124601 UA_close(fd: newsockfd);
124602 return;
124603 }
124604
124605 newConn->rfd.fd = newsockfd;
124606 newConn->rfd.listenEvents = UA_FDEVENT_IN;
124607 newConn->rfd.es = &cm->eventSource;
124608 newConn->rfd.eventSourceCB = (UA_FDCallback)TCP_connectionSocketCallback;
124609 newConn->applicationCB = conn->applicationCB;
124610 newConn->application = conn->application;
124611 newConn->context = conn->context;
124612
124613 /* Register in the EventLoop. Signal to the user if registering failed. */
124614 res = UA_EventLoopPOSIX_registerFD(el, rfd: &newConn->rfd);
124615 if(res != UA_STATUSCODE_GOOD) {
124616 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124617 msg: "TCP %u\t| Error registering the socket",
124618 (unsigned)newsockfd);
124619 UA_free(ptr: newConn);
124620 UA_close(fd: newsockfd);
124621 return;
124622 }
124623
124624 /* Register internally in the EventSource */
124625 ZIP_INSERT(UA_FDTree, &pcm->fds, &newConn->rfd);
124626 pcm->fdsSize++;
124627
124628 /* Forward the remote hostname to the application */
124629 UA_KeyValuePair kvp;
124630 kvp.key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "remote-address");
124631 UA_String hostName = UA_STRING(chars: hoststr);
124632 UA_Variant_setScalar(v: &kvp.value, p: &hostName, type: &UA_TYPES[UA_TYPES_STRING]);
124633
124634 UA_KeyValueMap kvm;
124635 kvm.mapSize = 1;
124636 kvm.map = &kvp;
124637
124638 /* The socket has opened. Signal it to the application. */
124639 newConn->applicationCB(cm, (uintptr_t)newsockfd,
124640 newConn->application, &newConn->context,
124641 UA_CONNECTIONSTATE_ESTABLISHED,
124642 &kvm, UA_BYTESTRING_NULL);
124643}
124644
124645static UA_StatusCode
124646TCP_registerListenSocket(UA_POSIXConnectionManager *pcm, struct addrinfo *ai,
124647 const char *hostname, UA_UInt16 port,
124648 void *application, void *context,
124649 UA_ConnectionManager_connectionCallback connectionCallback,
124650 UA_Boolean validate, UA_Boolean reuseaddr) {
124651 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop;
124652 UA_LOCK_ASSERT(&el->elMutex, 1);
124653
124654 /* Translate INADDR_ANY to IPv4/IPv6 address */
124655 char addrstr[UA_MAXHOSTNAME_LENGTH];
124656 int get_res = UA_getnameinfo(ai->ai_addr, ai->ai_addrlen,
124657 addrstr, sizeof(addrstr), NULL, 0, 0);
124658 if(get_res != 0) {
124659 get_res = UA_getnameinfo(ai->ai_addr, ai->ai_addrlen,
124660 addrstr, sizeof(addrstr),
124661 NULL, 0, NI_NUMERICHOST);
124662 if(get_res != 0) {
124663 addrstr[0] = 0;
124664 UA_LOG_SOCKET_ERRNO_WRAP(
124665 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
124666 "TCP\t| getnameinfo(...) could not resolve the "
124667 "hostname (%s)", errno_str));
124668 }
124669 }
124670
124671 /* Create the server socket */
124672 UA_FD listenSocket = socket(domain: ai->ai_family, type: ai->ai_socktype, protocol: ai->ai_protocol);
124673 if(listenSocket == UA_INVALID_FD) {
124674 UA_LOG_SOCKET_ERRNO_WRAP(
124675 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
124676 "TCP %u\t| Error opening the listen socket for "
124677 "\"%s\" on port %u (%s)",
124678 (unsigned)listenSocket, addrstr, port, errno_str));
124679 return UA_STATUSCODE_BADINTERNALERROR;
124680 }
124681
124682 /* Some Linux distributions have net.ipv6.bindv6only not activated. So
124683 * sockets can double-bind to IPv4 and IPv6. This leads to problems. Use
124684 * AF_INET6 sockets only for IPv6. */
124685#if UA_IPV6
124686 int optval = 1;
124687 if(ai->ai_family == AF_INET6 &&
124688 UA_setsockopt(fd: listenSocket, IPPROTO_IPV6, IPV6_V6ONLY,
124689 optval: (const char*)&optval, optlen: sizeof(optval)) == -1) {
124690 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124691 msg: "TCP %u\t| Could not set an IPv6 socket to IPv6 only",
124692 (unsigned)listenSocket);
124693 UA_close(fd: listenSocket);
124694 return UA_STATUSCODE_BADINTERNALERROR;
124695 }
124696#endif
124697
124698 /* Allow rebinding to the IP/port combination. Eg. to restart the server. */
124699 if(reuseaddr &&
124700 UA_EventLoopPOSIX_setReusable(sockfd: listenSocket) != UA_STATUSCODE_GOOD) {
124701 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124702 msg: "TCP %u\t| Could not make the socket addr reusable",
124703 (unsigned)listenSocket);
124704 UA_close(fd: listenSocket);
124705 return UA_STATUSCODE_BADINTERNALERROR;
124706 }
124707
124708 /* Set the socket non-blocking */
124709 if(UA_EventLoopPOSIX_setNonBlocking(sockfd: listenSocket) != UA_STATUSCODE_GOOD) {
124710 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124711 msg: "TCP %u\t| Could not set the socket non-blocking",
124712 (unsigned)listenSocket);
124713 UA_close(fd: listenSocket);
124714 return UA_STATUSCODE_BADINTERNALERROR;
124715 }
124716
124717 /* Supress interrupts from the socket */
124718 if(UA_EventLoopPOSIX_setNoSigPipe(sockfd: listenSocket) != UA_STATUSCODE_GOOD) {
124719 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124720 msg: "TCP %u\t| Could not disable SIGPIPE",
124721 (unsigned)listenSocket);
124722 UA_close(fd: listenSocket);
124723 return UA_STATUSCODE_BADINTERNALERROR;
124724 }
124725
124726 /* Bind socket to address */
124727 int ret = bind(fd: listenSocket, addr: ai->ai_addr, len: (socklen_t)ai->ai_addrlen);
124728
124729 /* Get the port being used if dynamic porting was used */
124730 if(port == 0) {
124731 struct sockaddr_in sin;
124732 memset(s: &sin, c: 0, n: sizeof(sin));
124733 socklen_t len = sizeof(sin);
124734 getsockname(fd: listenSocket, addr: (struct sockaddr *)&sin, len: &len);
124735 port = ntohs(netshort: sin.sin_port);
124736 }
124737
124738 /* If the INADDR_ANY is used, use the local hostname */
124739 char hoststr[UA_MAXHOSTNAME_LENGTH];
124740 if(hostname) {
124741 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124742 msg: "TCP %u\t| Creating listen socket for \"%s\" on port %u",
124743 (unsigned)listenSocket, hostname, port);
124744 } else {
124745 gethostname(name: hoststr, UA_MAXHOSTNAME_LENGTH);
124746 hostname = hoststr;
124747 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124748 msg: "TCP %u\t| Creating listen socket for \"%s\" "
124749 "(with local hostname \"%s\") on port %u",
124750 (unsigned)listenSocket, addrstr, hostname, port);
124751 }
124752
124753 if(ret < 0) {
124754 UA_LOG_SOCKET_ERRNO_WRAP(
124755 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
124756 "TCP %u\t| Error binding the socket to the address %s (%s)",
124757 (unsigned)listenSocket, hostname, errno_str));
124758 UA_close(fd: listenSocket);
124759 return UA_STATUSCODE_BADINTERNALERROR;
124760 }
124761
124762 /* Only validate, don't actually start listening */
124763 if(validate) {
124764 UA_EventLoopPOSIX_setReusable(sockfd: listenSocket); /* Ensure reuse is possible */
124765 UA_close(fd: listenSocket);
124766 return UA_STATUSCODE_GOOD;
124767 }
124768
124769 /* Start listening */
124770 if(listen(fd: listenSocket, UA_MAXBACKLOG) < 0) {
124771 UA_LOG_SOCKET_ERRNO_WRAP(
124772 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
124773 "TCP %u\t| Error listening on the socket (%s)",
124774 (unsigned)listenSocket, errno_str));
124775 UA_EventLoopPOSIX_setReusable(sockfd: listenSocket); /* Ensure reuse is possible */
124776 UA_close(fd: listenSocket);
124777 return UA_STATUSCODE_BADINTERNALERROR;
124778 }
124779
124780 /* Allocate the connection */
124781 TCP_FD *newConn = (TCP_FD*)UA_calloc(nmemb: 1, size: sizeof(TCP_FD));
124782 if(!newConn) {
124783 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124784 msg: "TCP %u\t| Error allocating memory for the socket",
124785 (unsigned)listenSocket);
124786 UA_EventLoopPOSIX_setReusable(sockfd: listenSocket); /* Ensure reuse is possible */
124787 UA_close(fd: listenSocket);
124788 return UA_STATUSCODE_BADINTERNALERROR;
124789 }
124790
124791 newConn->rfd.fd = listenSocket;
124792 newConn->rfd.listenEvents = UA_FDEVENT_IN;
124793 newConn->rfd.es = &pcm->cm.eventSource;
124794 newConn->rfd.eventSourceCB = (UA_FDCallback)TCP_listenSocketCallback;
124795 newConn->applicationCB = connectionCallback;
124796 newConn->application = application;
124797 newConn->context = context;
124798
124799 /* Register in the EventLoop */
124800 UA_StatusCode res = UA_EventLoopPOSIX_registerFD(el, rfd: &newConn->rfd);
124801 if(res != UA_STATUSCODE_GOOD) {
124802 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124803 msg: "TCP %u\t| Error registering the socket",
124804 (unsigned)listenSocket);
124805 UA_free(ptr: newConn);
124806 UA_EventLoopPOSIX_setReusable(sockfd: listenSocket); /* Ensure reuse is possible */
124807 UA_close(fd: listenSocket);
124808 return res;
124809 }
124810
124811 /* Register internally */
124812 ZIP_INSERT(UA_FDTree, &pcm->fds, &newConn->rfd);
124813 pcm->fdsSize++;
124814
124815 /* Set up the callback parameters */
124816 UA_String listenAddress = UA_STRING(chars: (char*)(uintptr_t)hostname);
124817 UA_KeyValuePair params[2];
124818 params[0].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "listen-address");
124819 UA_Variant_setScalar(v: &params[0].value, p: &listenAddress, type: &UA_TYPES[UA_TYPES_STRING]);
124820 params[1].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "listen-port");
124821 UA_Variant_setScalar(v: &params[1].value, p: &port, type: &UA_TYPES[UA_TYPES_UINT16]);
124822 UA_KeyValueMap paramMap = {2, params};
124823
124824 /* Announce the listen-socket in the application */
124825 connectionCallback(&pcm->cm, (uintptr_t)listenSocket,
124826 application, &newConn->context,
124827 UA_CONNECTIONSTATE_ESTABLISHED,
124828 &paramMap, UA_BYTESTRING_NULL);
124829
124830 return UA_STATUSCODE_GOOD;
124831}
124832
124833static UA_StatusCode
124834TCP_registerListenSockets(UA_POSIXConnectionManager *pcm, const char *hostname,
124835 UA_UInt16 port, void *application, void *context,
124836 UA_ConnectionManager_connectionCallback connectionCallback,
124837 UA_Boolean validate, UA_Boolean reuseaddr) {
124838 UA_LOCK_ASSERT(&((UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop)->elMutex, 1);
124839
124840 /* Create a string for the port */
124841 char portstr[6];
124842 mp_snprintf(s: portstr, n: sizeof(portstr), format: "%d", port);
124843
124844 /* Get all the interface and IPv4/6 combinations for the configured hostname */
124845 struct addrinfo hints, *res;
124846 memset(s: &hints, c: 0, n: sizeof hints);
124847#if UA_IPV6
124848 hints.ai_family = AF_UNSPEC; /* Allow IPv4 and IPv6 */
124849#else
124850 hints.ai_family = AF_INET; /* IPv4 only */
124851#endif
124852 hints.ai_socktype = SOCK_STREAM;
124853 hints.ai_protocol = IPPROTO_TCP;
124854 hints.ai_flags = AI_PASSIVE;
124855
124856 int retcode = getaddrinfo(name: hostname, service: portstr, req: &hints, pai: &res);
124857 if(retcode != 0) {
124858#ifdef UA_ARCHITECTURE_WIN32
124859 UA_LOG_SOCKET_ERRNO_WRAP(
124860 UA_LOG_WARNING(pcm->cm.eventSource.eventLoop->logger, UA_LOGCATEGORY_NETWORK,
124861 "TCP\t| Lookup for \"%s\" on port %u failed (%s)",
124862 hostname, port, errno_str));
124863#else
124864 UA_LOG_WARNING(logger: pcm->cm.eventSource.eventLoop->logger, category: UA_LOGCATEGORY_NETWORK,
124865 msg: "TCP\t| Lookup for \"%s\" on port %u failed (%s)",
124866 hostname, port, gai_strerror(ecode: retcode));
124867#endif
124868 return UA_STATUSCODE_BADINTERNALERROR;
124869 }
124870
124871 /* Add listen sockets. Aggregate the results to see if at least one
124872 * listen-socket was established. */
124873 UA_StatusCode total_result = UA_INT32_MAX;
124874 struct addrinfo *ai = res;
124875 while(ai) {
124876 total_result &= TCP_registerListenSocket(pcm, ai, hostname, port, application, context,
124877 connectionCallback, validate, reuseaddr);
124878 ai = ai->ai_next;
124879 }
124880 freeaddrinfo(ai: res);
124881
124882 return total_result;
124883}
124884
124885/* Close the connection via a delayed callback */
124886static void
124887TCP_shutdown(UA_ConnectionManager *cm, TCP_FD *conn) {
124888 /* Already closing - nothing to do */
124889 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
124890 UA_LOCK_ASSERT(&el->elMutex, 1);
124891
124892 if(conn->rfd.dc.callback) {
124893 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124894 msg: "TCP %u\t| Cannot shutdown - already triggered",
124895 (unsigned)conn->rfd.fd);
124896 return;
124897 }
124898
124899 /* Shutdown the socket to cancel the current select/epoll */
124900 shutdown(fd: conn->rfd.fd, UA_SHUT_RDWR);
124901
124902 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124903 msg: "TCP %u\t| Shutdown triggered",
124904 (unsigned)conn->rfd.fd);
124905
124906 /* Add to the delayed callback list. Will be cleaned up in the next
124907 * iteration. */
124908 UA_DelayedCallback *dc = &conn->rfd.dc;
124909 dc->callback = TCP_delayedClose;
124910 dc->application = cm;
124911 dc->context = conn;
124912
124913 /* Don't use the "public" el->addDelayedCallback. It takes a lock. */
124914 dc->next = el->delayedCallbacks;
124915 el->delayedCallbacks = dc;
124916}
124917
124918static UA_StatusCode
124919TCP_shutdownConnection(UA_ConnectionManager *cm, uintptr_t connectionId) {
124920 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
124921 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX *)cm->eventSource.eventLoop;
124922 UA_LOCK(&el->elMutex);
124923
124924 UA_FD fd = (UA_FD)connectionId;
124925 TCP_FD *conn = (TCP_FD*)ZIP_FIND(UA_FDTree, &pcm->fds, &fd);
124926 if(!conn) {
124927 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
124928 msg: "TCP\t| Cannot close TCP connection %u - not found",
124929 (unsigned)connectionId);
124930 UA_UNLOCK(&el->elMutex);
124931 return UA_STATUSCODE_BADNOTFOUND;
124932 }
124933
124934 TCP_shutdown(cm, conn);
124935
124936 UA_UNLOCK(&el->elMutex);
124937 return UA_STATUSCODE_GOOD;
124938}
124939
124940static UA_StatusCode
124941TCP_sendWithConnection(UA_ConnectionManager *cm, uintptr_t connectionId,
124942 const UA_KeyValueMap *params, UA_ByteString *buf) {
124943 /* We may not have a lock. But we need not take it. As the connectionId is
124944 * the fd, no need to do a lookup and access internal data strucures. */
124945
124946 /* Prevent OS signals when sending to a closed socket */
124947 int flags = MSG_NOSIGNAL;
124948
124949 struct pollfd tmp_poll_fd;
124950 tmp_poll_fd.fd = (UA_FD)connectionId;
124951 tmp_poll_fd.events = UA_POLLOUT;
124952
124953 /* Send the full buffer. This may require several calls to send */
124954 size_t nWritten = 0;
124955 do {
124956 ssize_t n = 0;
124957 do {
124958 UA_LOG_DEBUG(logger: cm->eventSource.eventLoop->logger, category: UA_LOGCATEGORY_NETWORK,
124959 msg: "TCP %u\t| Attempting to send", (unsigned)connectionId);
124960 size_t bytes_to_send = buf->length - nWritten;
124961 n = UA_send(fd: (UA_FD)connectionId,
124962 buf: (const char*)buf->data + nWritten,
124963 n: bytes_to_send, flags: flags);
124964 if(n < 0) {
124965 /* An error we cannot recover from? */
124966 if(UA_ERRNO != UA_INTERRUPTED && UA_ERRNO != UA_WOULDBLOCK &&
124967 UA_ERRNO != UA_AGAIN)
124968 goto shutdown;
124969
124970 /* Poll for the socket resources to become available and retry
124971 * (blocking) */
124972 int poll_ret;
124973 do {
124974 poll_ret = UA_poll(fds: &tmp_poll_fd, nfds: 1, timeout: 100);
124975 if(poll_ret < 0 && UA_ERRNO != UA_INTERRUPTED)
124976 goto shutdown;
124977 } while(poll_ret <= 0);
124978 }
124979 } while(n < 0);
124980 nWritten += (size_t)n;
124981 } while(nWritten < buf->length);
124982
124983 /* Free the buffer */
124984 UA_ByteString_clear(p: buf);
124985 return UA_STATUSCODE_GOOD;
124986
124987 shutdown:
124988 UA_LOG_SOCKET_ERRNO_WRAP(
124989 UA_LOG_ERROR(cm->eventSource.eventLoop->logger, UA_LOGCATEGORY_NETWORK,
124990 "TCP %u\t| Send failed with error %s",
124991 (unsigned)connectionId, errno_str));
124992 TCP_shutdownConnection(cm, connectionId);
124993 UA_ByteString_clear(p: buf);
124994 return UA_STATUSCODE_BADCONNECTIONCLOSED;
124995}
124996
124997/* Create a listen-socket that waits for incoming connections */
124998static UA_StatusCode
124999TCP_openPassiveConnection(UA_POSIXConnectionManager *pcm, const UA_KeyValueMap *params,
125000 void *application, void *context,
125001 UA_ConnectionManager_connectionCallback connectionCallback,
125002 UA_Boolean validate) {
125003 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop;
125004 UA_LOCK_ASSERT(&el->elMutex, 1);
125005
125006 /* Get the port parameter */
125007 const UA_UInt16 *port = (const UA_UInt16*)
125008 UA_KeyValueMap_getScalar(map: params, key: TCPConfigParameters[TCP_PARAMINDEX_PORT].name,
125009 type: &UA_TYPES[UA_TYPES_UINT16]);
125010 UA_assert(port); /* existence is checked before */
125011
125012 /* Get the address parameter */
125013 const UA_Variant *addrs =
125014 UA_KeyValueMap_get(map: params, key: TCPConfigParameters[TCP_PARAMINDEX_ADDR].name);
125015 size_t addrsSize = 0;
125016 if(addrs) {
125017 UA_assert(addrs->type == &UA_TYPES[UA_TYPES_STRING]);
125018 if(UA_Variant_isScalar(v: addrs))
125019 addrsSize = 1;
125020 else
125021 addrsSize = addrs->arrayLength;
125022 }
125023
125024 /* Get the reuseaddr parameter */
125025 UA_Boolean reuseaddr = false;
125026 const UA_Boolean *reuseaddrTmp = (const UA_Boolean*)
125027 UA_KeyValueMap_getScalar(map: params, key: TCPConfigParameters[TCP_PARAMINDEX_REUSE].name,
125028 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
125029 if(reuseaddrTmp)
125030 reuseaddr = *reuseaddrTmp;
125031
125032#ifdef UA_ENABLE_ALLOW_REUSEADDR
125033 reuseaddr = true;
125034#endif
125035
125036 /* Undefined or empty addresses array -> listen on all interfaces */
125037 if(addrsSize == 0) {
125038 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
125039 msg: "TCP\t| Listening on all interfaces");
125040 return TCP_registerListenSockets(pcm, NULL, port: *port, application,
125041 context, connectionCallback, validate, reuseaddr);
125042 }
125043
125044 /* Iterate over the configured hostnames */
125045 UA_String *hostStrings = (UA_String*)addrs->data;
125046 UA_StatusCode retval = UA_STATUSCODE_BADINTERNALERROR;
125047 for(size_t i = 0; i < addrsSize; i++) {
125048 char hostname[512];
125049 if(hostStrings[i].length >= sizeof(hostname))
125050 continue;
125051 memcpy(dest: hostname, src: hostStrings[i].data, n: hostStrings->length);
125052 hostname[hostStrings->length] = '\0';
125053 if(TCP_registerListenSockets(pcm, hostname, port: *port, application,
125054 context, connectionCallback, validate, reuseaddr) == UA_STATUSCODE_GOOD)
125055 retval = UA_STATUSCODE_GOOD;
125056 }
125057 return retval;
125058}
125059
125060/* Open a TCP connection to a remote host */
125061static UA_StatusCode
125062TCP_openActiveConnection(UA_POSIXConnectionManager *pcm, const UA_KeyValueMap *params,
125063 void *application, void *context,
125064 UA_ConnectionManager_connectionCallback connectionCallback,
125065 UA_Boolean validate) {
125066 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop;
125067 UA_LOCK_ASSERT(&el->elMutex, 1);
125068
125069 /* Get the connection parameters */
125070 char hostname[UA_MAXHOSTNAME_LENGTH];
125071 char portStr[UA_MAXPORTSTR_LENGTH];
125072
125073 /* Prepare the port parameter as a string */
125074 const UA_UInt16 *port = (const UA_UInt16*)
125075 UA_KeyValueMap_getScalar(map: params, key: TCPConfigParameters[TCP_PARAMINDEX_PORT].name,
125076 type: &UA_TYPES[UA_TYPES_UINT16]);
125077 UA_assert(port); /* existence is checked before */
125078 mp_snprintf(s: portStr, UA_MAXPORTSTR_LENGTH, format: "%d", *port);
125079
125080 /* Prepare the hostname string */
125081 const UA_String *addr = (const UA_String*)
125082 UA_KeyValueMap_getScalar(map: params, key: TCPConfigParameters[TCP_PARAMINDEX_ADDR].name,
125083 type: &UA_TYPES[UA_TYPES_STRING]);
125084 if(!addr) {
125085 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
125086 msg: "TCP\t| Open TCP Connection: No hostname defined, aborting");
125087 return UA_STATUSCODE_BADINTERNALERROR;
125088 }
125089 if(addr->length >= UA_MAXHOSTNAME_LENGTH) {
125090 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
125091 msg: "TCP\t| Open TCP Connection: Hostname too long, aborting");
125092 return UA_STATUSCODE_BADINTERNALERROR;
125093 }
125094 strncpy(dest: hostname, src: (const char*)addr->data, n: addr->length);
125095 hostname[addr->length] = 0;
125096
125097 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
125098 msg: "TCP\t| Open a connection to \"%s\" on port %s", hostname, portStr);
125099
125100 /* Create the socket description from the connectString
125101 * TODO: Make this non-blocking */
125102 struct addrinfo hints, *info;
125103 memset(s: &hints, c: 0, n: sizeof(struct addrinfo));
125104 hints.ai_family = AF_UNSPEC;
125105 hints.ai_socktype = SOCK_STREAM;
125106 int error = getaddrinfo(name: hostname, service: portStr, req: &hints, pai: &info);
125107 if(error != 0) {
125108#ifdef UA_ARCHITECTURE_WIN32
125109 UA_LOG_SOCKET_ERRNO_WRAP(
125110 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
125111 "TCP\t| Lookup of %s failed (%s)",
125112 hostname, errno_str));
125113#else
125114 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
125115 msg: "TCP\t| Lookup of %s failed (%s)",
125116 hostname, gai_strerror(ecode: error));
125117#endif
125118 return UA_STATUSCODE_BADINTERNALERROR;
125119 }
125120
125121 /* Create a socket */
125122 UA_FD newSock = socket(domain: info->ai_family, type: info->ai_socktype, protocol: info->ai_protocol);
125123 if(newSock == UA_INVALID_FD) {
125124 freeaddrinfo(ai: info);
125125 UA_LOG_SOCKET_ERRNO_WRAP(
125126 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
125127 "TCP\t| Could not create socket to connect to %s (%s)",
125128 hostname, errno_str));
125129 return UA_STATUSCODE_BADDISCONNECT;
125130 }
125131
125132 /* Set the socket options */
125133 UA_StatusCode res = UA_STATUSCODE_GOOD;
125134 res |= UA_EventLoopPOSIX_setNonBlocking(sockfd: newSock);
125135 res |= UA_EventLoopPOSIX_setNoSigPipe(sockfd: newSock);
125136 res |= TCP_setNoNagle(sockfd: newSock);
125137 if(res != UA_STATUSCODE_GOOD) {
125138 UA_LOG_SOCKET_ERRNO_WRAP(
125139 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
125140 "TCP\t| Could not set socket options: %s", errno_str));
125141 freeaddrinfo(ai: info);
125142 UA_close(fd: newSock);
125143 return res;
125144 }
125145
125146 /* Only validate, don't actually open the connection */
125147 if(validate) {
125148 freeaddrinfo(ai: info);
125149 UA_close(fd: newSock);
125150 return UA_STATUSCODE_GOOD;
125151 }
125152
125153 /* Non-blocking connect */
125154 error = UA_connect(fd: newSock, addr: info->ai_addr, len: info->ai_addrlen);
125155 freeaddrinfo(ai: info);
125156 if(error != 0 &&
125157 UA_ERRNO != UA_INPROGRESS &&
125158 UA_ERRNO != UA_WOULDBLOCK) {
125159 UA_LOG_SOCKET_ERRNO_WRAP(
125160 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
125161 "TCP\t| Connecting the socket to %s failed (%s)",
125162 hostname, errno_str));
125163 UA_close(fd: newSock);
125164 return UA_STATUSCODE_BADDISCONNECT;
125165 }
125166
125167 /* Allocate the UA_RegisteredFD */
125168 TCP_FD *newConn = (TCP_FD*)UA_calloc(nmemb: 1, size: sizeof(TCP_FD));
125169 if(!newConn) {
125170 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
125171 msg: "TCP %u\t| Error allocating memory for the socket",
125172 (unsigned)newSock);
125173 UA_close(fd: newSock);
125174 return UA_STATUSCODE_BADOUTOFMEMORY;
125175 }
125176
125177 newConn->rfd.fd = newSock;
125178 newConn->rfd.es = &pcm->cm.eventSource;
125179 newConn->rfd.eventSourceCB = (UA_FDCallback)TCP_connectionSocketCallback;
125180 newConn->rfd.listenEvents = UA_FDEVENT_OUT; /* Switched to _IN once the
125181 * connection is open */
125182 newConn->applicationCB = connectionCallback;
125183 newConn->application = application;
125184 newConn->context = context;
125185
125186 /* Register the fd to trigger when output is possible (the connection is open) */
125187 res = UA_EventLoopPOSIX_registerFD(el, rfd: &newConn->rfd);
125188 if(res != UA_STATUSCODE_GOOD) {
125189 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
125190 msg: "TCP\t| Registering the socket to connect to %s failed", hostname);
125191 UA_close(fd: newSock);
125192 UA_free(ptr: newConn);
125193 return res;
125194 }
125195
125196 /* Register internally in the EventSource */
125197 ZIP_INSERT(UA_FDTree, &pcm->fds, &newConn->rfd);
125198 pcm->fdsSize++;
125199
125200 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
125201 msg: "TCP %u\t| Opening a connection to \"%s\" on port %s",
125202 (unsigned)newSock, hostname, portStr);
125203
125204 /* Signal the new connection to the application as asynchonously opening */
125205 connectionCallback(&pcm->cm, (uintptr_t)newSock,
125206 application, &newConn->context,
125207 UA_CONNECTIONSTATE_OPENING, &UA_KEYVALUEMAP_NULL,
125208 UA_BYTESTRING_NULL);
125209
125210 return UA_STATUSCODE_GOOD;
125211}
125212
125213static UA_StatusCode
125214TCP_openConnection(UA_ConnectionManager *cm, const UA_KeyValueMap *params,
125215 void *application, void *context,
125216 UA_ConnectionManager_connectionCallback connectionCallback) {
125217 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
125218 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
125219 UA_LOCK(&el->elMutex);
125220
125221 if(cm->eventSource.state != UA_EVENTSOURCESTATE_STARTED) {
125222 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
125223 msg: "TCP\t| Cannot open a connection for a "
125224 "ConnectionManager that is not started");
125225 UA_UNLOCK(&el->elMutex);
125226 return UA_STATUSCODE_BADINTERNALERROR;
125227 }
125228
125229 /* Check the parameters */
125230 UA_StatusCode res =
125231 UA_KeyValueRestriction_validate(logger: el->eventLoop.logger, logprefix: "TCP",
125232 restrictions: &TCPConfigParameters[1],
125233 TCP_PARAMETERSSIZE-1, map: params);
125234 if(res != UA_STATUSCODE_GOOD) {
125235 UA_UNLOCK(&el->elMutex);
125236 return res;
125237 }
125238
125239 /* Only validate the parameters? */
125240 UA_Boolean validate = false;
125241 const UA_Boolean *validateParam = (const UA_Boolean*)
125242 UA_KeyValueMap_getScalar(map: params,
125243 key: TCPConfigParameters[TCP_PARAMINDEX_VALIDATE].name,
125244 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
125245 if(validateParam)
125246 validate = *validateParam;
125247
125248 /* Listen or active connection? */
125249 UA_Boolean listen = false;
125250 const UA_Boolean *listenParam = (const UA_Boolean*)
125251 UA_KeyValueMap_getScalar(map: params,
125252 key: TCPConfigParameters[TCP_PARAMINDEX_LISTEN].name,
125253 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
125254 if(listenParam)
125255 listen = *listenParam;
125256
125257 if(listen) {
125258 res = TCP_openPassiveConnection(pcm, params, application, context,
125259 connectionCallback, validate);
125260 } else {
125261 res = TCP_openActiveConnection(pcm, params, application, context,
125262 connectionCallback, validate);
125263 }
125264
125265 UA_UNLOCK(&el->elMutex);
125266 return res;
125267}
125268
125269static UA_StatusCode
125270TCP_eventSourceStart(UA_ConnectionManager *cm) {
125271 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
125272 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
125273 if(!el)
125274 return UA_STATUSCODE_BADINTERNALERROR;
125275
125276 UA_LOCK(&el->elMutex);
125277
125278 /* Check the state */
125279 if(cm->eventSource.state != UA_EVENTSOURCESTATE_STOPPED) {
125280 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
125281 msg: "TCP\t| To start the ConnectionManager, it has to be "
125282 "registered in an EventLoop and not started yet");
125283 UA_UNLOCK(&el->elMutex);
125284 return UA_STATUSCODE_BADINTERNALERROR;
125285 }
125286
125287 /* Check the parameters */
125288 UA_StatusCode res =
125289 UA_KeyValueRestriction_validate(logger: el->eventLoop.logger, logprefix: "TCP",
125290 restrictions: TCPConfigParameters, restrictionsSize: 1,
125291 map: &cm->eventSource.params);
125292 if(res != UA_STATUSCODE_GOOD)
125293 goto finish;
125294
125295 /* Allocate the rx buffer */
125296 res = UA_EventLoopPOSIX_allocateRXBuffer(pcm);
125297 if(res != UA_STATUSCODE_GOOD)
125298 goto finish;
125299
125300 /* Set the EventSource to the started state */
125301 cm->eventSource.state = UA_EVENTSOURCESTATE_STARTED;
125302
125303 finish:
125304 UA_UNLOCK(&el->elMutex);
125305 return res;
125306}
125307
125308static void *
125309TCP_shutdownCB(void *application, UA_RegisteredFD *rfd) {
125310 UA_ConnectionManager *cm = (UA_ConnectionManager*)application;
125311 TCP_shutdown(cm, conn: (TCP_FD*)rfd);
125312 return NULL;
125313}
125314
125315static void
125316TCP_eventSourceStop(UA_ConnectionManager *cm) {
125317 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
125318 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
125319 (void)el;
125320
125321 UA_LOCK(&el->elMutex);
125322
125323 UA_LOG_INFO(logger: cm->eventSource.eventLoop->logger, category: UA_LOGCATEGORY_NETWORK,
125324 msg: "TCP\t| Shutting down the ConnectionManager");
125325
125326 /* Prevent new connections to open */
125327 cm->eventSource.state = UA_EVENTSOURCESTATE_STOPPING;
125328
125329 /* Shutdown all existing connection */
125330 ZIP_ITER(UA_FDTree, &pcm->fds, TCP_shutdownCB, cm);
125331
125332 /* All sockets closed? Otherwise iterate some more. */
125333 TCP_checkStopped(pcm);
125334
125335 UA_UNLOCK(&el->elMutex);
125336}
125337
125338static UA_StatusCode
125339TCP_eventSourceDelete(UA_ConnectionManager *cm) {
125340 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
125341 if(cm->eventSource.state >= UA_EVENTSOURCESTATE_STARTING) {
125342 UA_LOG_ERROR(logger: cm->eventSource.eventLoop->logger, category: UA_LOGCATEGORY_EVENTLOOP,
125343 msg: "TCP\t| The EventSource must be stopped before it can be deleted");
125344 return UA_STATUSCODE_BADINTERNALERROR;
125345 }
125346
125347 UA_ByteString_clear(p: &pcm->rxBuffer);
125348 UA_KeyValueMap_clear(map: &cm->eventSource.params);
125349 UA_String_clear(p: &cm->eventSource.name);
125350 UA_free(ptr: cm);
125351
125352 return UA_STATUSCODE_GOOD;
125353}
125354
125355static const char *tcpName = "tcp";
125356
125357UA_ConnectionManager *
125358UA_ConnectionManager_new_POSIX_TCP(const UA_String eventSourceName) {
125359 UA_POSIXConnectionManager *cm = (UA_POSIXConnectionManager*)
125360 UA_calloc(nmemb: 1, size: sizeof(UA_POSIXConnectionManager));
125361 if(!cm)
125362 return NULL;
125363
125364 cm->cm.eventSource.eventSourceType = UA_EVENTSOURCETYPE_CONNECTIONMANAGER;
125365 UA_String_copy(src: &eventSourceName, dst: &cm->cm.eventSource.name);
125366 cm->cm.eventSource.start = (UA_StatusCode (*)(UA_EventSource *))TCP_eventSourceStart;
125367 cm->cm.eventSource.stop = (void (*)(UA_EventSource *))TCP_eventSourceStop;
125368 cm->cm.eventSource.free = (UA_StatusCode (*)(UA_EventSource *))TCP_eventSourceDelete;
125369 cm->cm.protocol = UA_STRING(chars: (char*)(uintptr_t)tcpName);
125370 cm->cm.openConnection = TCP_openConnection;
125371 cm->cm.allocNetworkBuffer = UA_EventLoopPOSIX_allocNetworkBuffer;
125372 cm->cm.freeNetworkBuffer = UA_EventLoopPOSIX_freeNetworkBuffer;
125373 cm->cm.sendWithConnection = TCP_sendWithConnection;
125374 cm->cm.closeConnection = TCP_shutdownConnection;
125375 return &cm->cm;
125376}
125377
125378/**** amalgamated original file "/arch/eventloop_posix_udp.c" ****/
125379
125380/* This Source Code Form is subject to the terms of the Mozilla Public
125381 * License, v. 2.0. If a copy of the MPL was not distributed with this
125382 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
125383 *
125384 * Copyright 2021-2022 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
125385 * Copyright 2021 (c) Fraunhofer IOSB (Author: Jan Hermes)
125386 */
125387
125388
125389#define IPV4_PREFIX_MASK 0xF0
125390#define IPV4_MULTICAST_PREFIX 0xE0
125391#if UA_IPV6
125392# define IPV6_PREFIX_MASK 0xFF
125393# define IPV6_MULTICAST_PREFIX 0xFF
125394#endif
125395
125396/* Configuration parameters */
125397#define UDP_PARAMETERSSIZE 10
125398#define UDP_PARAMINDEX_RECVBUF 0
125399#define UDP_PARAMINDEX_LISTEN 1
125400#define UDP_PARAMINDEX_ADDR 2
125401#define UDP_PARAMINDEX_PORT 3
125402#define UDP_PARAMINDEX_INTERFACE 4
125403#define UDP_PARAMINDEX_TTL 5
125404#define UDP_PARAMINDEX_LOOPBACK 6
125405#define UDP_PARAMINDEX_REUSE 7
125406#define UDP_PARAMINDEX_SOCKPRIO 8
125407#define UDP_PARAMINDEX_VALIDATE 9
125408
125409static UA_KeyValueRestriction UDPConfigParameters[UDP_PARAMETERSSIZE] = {
125410 {{0, UA_STRING_STATIC("recv-bufsize")}, &UA_TYPES[UA_TYPES_UINT32], false, true, false},
125411 {{0, UA_STRING_STATIC("listen")}, &UA_TYPES[UA_TYPES_BOOLEAN], false, true, false},
125412 {{0, UA_STRING_STATIC("address")}, &UA_TYPES[UA_TYPES_STRING], false, true, true},
125413 {{0, UA_STRING_STATIC("port")}, &UA_TYPES[UA_TYPES_UINT16], true, true, false},
125414 {{0, UA_STRING_STATIC("interface")}, &UA_TYPES[UA_TYPES_STRING], false, true, false},
125415 {{0, UA_STRING_STATIC("ttl")}, &UA_TYPES[UA_TYPES_UINT32], false, true, false},
125416 {{0, UA_STRING_STATIC("loopback")}, &UA_TYPES[UA_TYPES_BOOLEAN], false, true, false},
125417 {{0, UA_STRING_STATIC("reuse")}, &UA_TYPES[UA_TYPES_BOOLEAN], false, true, false},
125418 {{0, UA_STRING_STATIC("sockpriority")}, &UA_TYPES[UA_TYPES_UINT32], false, true, false},
125419 {{0, UA_STRING_STATIC("validate")}, &UA_TYPES[UA_TYPES_BOOLEAN], false, true, false}
125420};
125421
125422/* A registered file descriptor with an additional method pointer */
125423typedef struct {
125424 UA_RegisteredFD rfd;
125425
125426 UA_ConnectionManager_connectionCallback applicationCB;
125427 void *application;
125428 void *context;
125429
125430 struct sockaddr_storage sendAddr;
125431#ifdef UA_ARCHITECTURE_WIN32
125432 size_t sendAddrLength;
125433#else
125434 socklen_t sendAddrLength;
125435#endif
125436} UDP_FD;
125437
125438typedef enum {
125439 MULTICASTTYPE_NONE = 0,
125440 MULTICASTTYPE_IPV4,
125441 MULTICASTTYPE_IPV6
125442} MultiCastType;
125443
125444typedef union {
125445#if !defined(ip_mreqn)
125446 struct ip_mreq ipv4;
125447#else
125448 struct ip_mreqn ipv4;
125449#endif
125450#if UA_IPV6
125451 struct ipv6_mreq ipv6;
125452#endif
125453} MulticastRequest;
125454
125455static UA_Boolean
125456isMulticastAddress(const UA_Byte *address, UA_Byte mask, UA_Byte prefix) {
125457 return (address[0] & mask) == prefix;
125458}
125459
125460static MultiCastType
125461multiCastType(struct addrinfo *info) {
125462 const UA_Byte *address;
125463 if(info->ai_family == AF_INET) {
125464 address = (UA_Byte *)&((struct sockaddr_in *)info->ai_addr)->sin_addr;
125465 if(isMulticastAddress(address, IPV4_PREFIX_MASK, IPV4_MULTICAST_PREFIX))
125466 return MULTICASTTYPE_IPV4;
125467#if UA_IPV6
125468 } else if(info->ai_family == AF_INET6) {
125469 address = (UA_Byte *)&((struct sockaddr_in6 *)info->ai_addr)->sin6_addr;
125470 if(isMulticastAddress(address, IPV6_PREFIX_MASK, IPV6_MULTICAST_PREFIX))
125471 return MULTICASTTYPE_IPV6;
125472#endif
125473 }
125474 return MULTICASTTYPE_NONE;
125475}
125476
125477#ifdef UA_ARCHITECTURE_WIN32
125478
125479#define ADDR_BUFFER_SIZE 15000 /* recommended size in the MSVC docs */
125480
125481static UA_StatusCode
125482setMulticastInterface(const char *netif, struct addrinfo *info,
125483 MulticastRequest *req, const UA_Logger *logger) {
125484 ULONG outBufLen = ADDR_BUFFER_SIZE;
125485 UA_STACKARRAY(char, addrBuf, ADDR_BUFFER_SIZE);
125486
125487 /* Get the network interface descriptions */
125488 ULONG flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
125489 GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
125490 PIP_ADAPTER_ADDRESSES ifaddr = (IP_ADAPTER_ADDRESSES *)addrBuf;
125491 DWORD ret = GetAdaptersAddresses(info->ai_family, flags, NULL, ifaddr, &outBufLen);
125492 if(ret != NO_ERROR) {
125493 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER,
125494 "UDP\t| Interface configuration preparation failed");
125495 return UA_STATUSCODE_BADINTERNALERROR;
125496 }
125497
125498 /* Iterate through linked list of network interfaces */
125499 char sourceAddr[64];
125500 unsigned int idx = 0;
125501 for(PIP_ADAPTER_ADDRESSES ifa = ifaddr; ifa != NULL; ifa = ifa->Next) {
125502 idx = (info->ai_family == AF_INET) ? ifa->IfIndex : ifa->Ipv6IfIndex;
125503
125504 /* Check if network interface name matches */
125505 if(strcmp(ifa->AdapterName, netif) == 0)
125506 goto done;
125507
125508 /* Check if ip address matches */
125509 for(PIP_ADAPTER_UNICAST_ADDRESS u = ifa->FirstUnicastAddress; u; u = u->Next) {
125510 LPSOCKADDR addr = u->Address.lpSockaddr;
125511 if(addr->sa_family == AF_INET) {
125512 inet_ntop(AF_INET, &((struct sockaddr_in*)addr)->sin_addr,
125513 sourceAddr, sizeof(sourceAddr));
125514 } else if(addr->sa_family == AF_INET6) {
125515 inet_ntop(AF_INET6, &((struct sockaddr_in6*)addr)->sin6_addr,
125516 sourceAddr, sizeof(sourceAddr));
125517 } else {
125518 continue;
125519 }
125520 if(strcmp(sourceAddr, netif) == 0)
125521 goto done;
125522 }
125523 }
125524
125525 /* Not matching interface found */
125526 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER,
125527 "UDP\t| Interface configuration preparation failed "
125528 "(interface %s not found)", netif);
125529 return UA_STATUSCODE_BADINTERNALERROR;
125530
125531 done:
125532 /* Write the interface index */
125533 if(info->ai_family == AF_INET)
125534 /* MSVC documentation of struct ip_mreq: To use an interface index of 1
125535 * would be the same as an IP address of 0.0.0.1. */
125536 req->ipv4.imr_interface.s_addr = htonl(idx);
125537#if UA_IPV6
125538 else /* if(info->ai_family == AF_INET6) */
125539 req->ipv6.ipv6mr_interface = idx;
125540#endif
125541 return UA_STATUSCODE_GOOD;
125542}
125543
125544#else
125545
125546static UA_StatusCode
125547setMulticastInterface(const char *netif, struct addrinfo *info,
125548 MulticastRequest *req, const UA_Logger *logger) {
125549 struct ifaddrs *ifaddr;
125550 int ret = getifaddrs(ifap: &ifaddr);
125551 if(ret == -1) {
125552 UA_LOG_SOCKET_ERRNO_WRAP(
125553 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER,
125554 "UDP\t| Interface configuration preparation failed "
125555 "(getifaddrs error: %s)", errno_str));
125556 return UA_STATUSCODE_BADINTERNALERROR;
125557 }
125558
125559 /* Iterate over the interfaces */
125560 unsigned int idx = 0;
125561 struct ifaddrs *ifa = NULL;
125562 for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
125563 if(!ifa->ifa_addr)
125564 continue;
125565
125566 /* Does the protocol family match? */
125567 if(ifa->ifa_addr->sa_family != info->ai_family)
125568 continue;
125569
125570 idx = UA_if_nametoindex(ifname: ifa->ifa_name);
125571 if(idx == 0)
125572 continue;
125573
125574 /* Found network interface by name */
125575 if(strcmp(s1: ifa->ifa_name, s2: netif) == 0)
125576 break;
125577
125578 /* Check if the interface name is an IP address that matches */
125579 char host[NI_MAXHOST];
125580 ret = getnameinfo(sa: ifa->ifa_addr,
125581 salen: (info->ai_family == AF_INET) ?
125582 sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6),
125583 host: host, NI_MAXHOST, NULL, servlen: 0, NI_NUMERICHOST);
125584 if(ret != 0) {
125585 UA_LOG_SOCKET_ERRNO_WRAP(
125586 UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER,
125587 "UDP\t| Interface configuration preparation "
125588 "ifailed (getnameinfo error: %s).", errno_str));
125589 freeifaddrs(ifa: ifaddr);
125590 return UA_STATUSCODE_BADINTERNALERROR;
125591 }
125592 if(strcmp(s1: host, s2: netif) == 0)
125593 break;
125594 }
125595
125596 freeifaddrs(ifa: ifaddr);
125597 if(!ifa)
125598 return UA_STATUSCODE_BADINTERNALERROR;
125599
125600 /* Write the interface index */
125601 if(info->ai_family == AF_INET) {
125602#if defined(ip_mreqn)
125603 req->ipv4.imr_ifindex = idx;
125604#endif
125605#if UA_IPV6
125606 } else { /* if(info->ai_family == AF_INET6) */
125607 req->ipv6.ipv6mr_interface = idx;
125608#endif
125609 }
125610 return UA_STATUSCODE_GOOD;
125611}
125612
125613#endif /* UA_ARCHITECTURE_WIN32 */
125614
125615static UA_StatusCode
125616setupMulticastRequest(UA_FD socket, MulticastRequest *req, const UA_KeyValueMap *params,
125617 struct addrinfo *info, const UA_Logger *logger) {
125618 /* Initialize the address information */
125619 if(info->ai_family == AF_INET) {
125620 struct sockaddr_in *sin = (struct sockaddr_in *)info->ai_addr;
125621 req->ipv4.imr_multiaddr = sin->sin_addr;
125622#if !defined(ip_mreqn)
125623 req->ipv4.imr_interface.s_addr = htonl(INADDR_ANY); /* default ANY */
125624#else
125625 req->ipv4.imr_address.s_addr = htonl(INADDR_ANY); /* default ANY */
125626 req->ipv4.imr_ifindex = 0;
125627#endif
125628#if UA_IPV6
125629 } else if(info->ai_family == AF_INET6) {
125630 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)info->ai_addr;
125631 req->ipv6.ipv6mr_multiaddr = sin6->sin6_addr;
125632 req->ipv6.ipv6mr_interface = 0; /* default ANY interface */
125633#endif
125634 } else {
125635 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_SERVER,
125636 msg: "UDP\t| Multicast configuration failed: Unknown protocol family");
125637 return UA_STATUSCODE_BADINTERNALERROR;
125638 }
125639
125640 /* Was an interface (or local IP address) defined? */
125641 const UA_String *netif = (const UA_String*)
125642 UA_KeyValueMap_getScalar(map: params, key: UDPConfigParameters[UDP_PARAMINDEX_INTERFACE].name,
125643 type: &UA_TYPES[UA_TYPES_STRING]);
125644 if(!netif) {
125645 UA_LOG_WARNING(logger, category: UA_LOGCATEGORY_NETWORK,
125646 msg: "UDP %u\t| No network interface defined for multicast. "
125647 "The first suitable network interface is used.",
125648 (unsigned)socket);
125649 return UA_STATUSCODE_GOOD;
125650 }
125651
125652 /* Set the interface index */
125653 UA_STACKARRAY(char, interfaceAsChar, sizeof(char) * netif->length + 1);
125654 memcpy(dest: interfaceAsChar, src: netif->data, n: netif->length);
125655 interfaceAsChar[netif->length] = 0;
125656 return setMulticastInterface(netif: interfaceAsChar, info, req, logger);
125657}
125658
125659/* Retrieves hostname and port from given key value parameters.
125660 *
125661 * @param[in] params the parameter map to retrieve from
125662 * @param[out] hostname the retrieved hostname when present, NULL otherwise
125663 * @param[out] portStr the retrieved port when present, NULL otherwise
125664 * @param[in] logger the logger to log information
125665 * @return -1 upon error, 0 if there was no host or port parameter, 1 if
125666 * host and port are present */
125667static int
125668getHostAndPortFromParams(const UA_KeyValueMap *params, char *hostname,
125669 char *portStr, const UA_Logger *logger) {
125670 /* Prepare the port parameter as a string */
125671 const UA_UInt16 *port = (const UA_UInt16*)
125672 UA_KeyValueMap_getScalar(map: params, key: UDPConfigParameters[UDP_PARAMINDEX_PORT].name,
125673 type: &UA_TYPES[UA_TYPES_UINT16]);
125674 UA_assert(port); /* checked before */
125675 mp_snprintf(s: portStr, UA_MAXPORTSTR_LENGTH, format: "%d", *port);
125676
125677 /* Prepare the hostname string */
125678 const UA_String *host = (const UA_String*)
125679 UA_KeyValueMap_getScalar(map: params, key: UDPConfigParameters[UDP_PARAMINDEX_ADDR].name,
125680 type: &UA_TYPES[UA_TYPES_STRING]);
125681 if(!host) {
125682 UA_LOG_DEBUG(logger, category: UA_LOGCATEGORY_NETWORK,
125683 msg: "UDP\t| No address configured");
125684 return -1;
125685 }
125686 if(host->length >= UA_MAXHOSTNAME_LENGTH) {
125687 UA_LOG_ERROR(logger, category: UA_LOGCATEGORY_EVENTLOOP,
125688 msg: "UDP\t| Open UDP Connection: Hostname too long, aborting");
125689 return -1;
125690 }
125691 strncpy(dest: hostname, src: (const char*)host->data, n: host->length);
125692 hostname[host->length] = 0;
125693 return 1;
125694}
125695
125696static int
125697getConnectionInfoFromParams(const UA_KeyValueMap *params,
125698 char *hostname, char *portStr,
125699 struct addrinfo **info, const UA_Logger *logger) {
125700 int foundParams = getHostAndPortFromParams(params, hostname, portStr, logger);
125701 if(foundParams < 0)
125702 return -1;
125703
125704 /* Create the socket description from the connectString
125705 * TODO: Make this non-blocking */
125706 struct addrinfo hints;
125707 memset(s: &hints, c: 0, n: sizeof(struct addrinfo));
125708 hints.ai_family = AF_UNSPEC;
125709 hints.ai_socktype = SOCK_DGRAM;
125710 int error = getaddrinfo(name: hostname, service: portStr, req: &hints, pai: info);
125711 if(error != 0) {
125712 UA_LOG_SOCKET_ERRNO_GAI_WRAP(
125713 UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
125714 "UDP\t| Lookup of %s failed with error %d - %s",
125715 hostname, error, errno_str));
125716 return -1;
125717 }
125718 return 1;
125719}
125720
125721/* Set loop back data to your host */
125722static UA_StatusCode
125723setLoopBackData(UA_SOCKET sockfd, UA_Boolean enableLoopback,
125724 int ai_family, const UA_Logger *logger) {
125725 /* The Linux Kernel IPv6 socket code checks for optlen to be at least the
125726 * size of an integer. However, channelDataUDPMC->enableLoopback is a
125727 * boolean. In order for the code to work for IPv4 and IPv6 propagate it to
125728 * a temporary integer here. */
125729 UA_Int32 enable = enableLoopback;
125730#if UA_IPV6
125731 if(UA_setsockopt(fd: sockfd,
125732 level: ai_family == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP,
125733 optname: ai_family == AF_INET6 ? IPV6_MULTICAST_LOOP : IP_MULTICAST_LOOP,
125734 optval: (const char *)&enable,
125735 optlen: sizeof (enable)) < 0)
125736#else
125737 if(UA_setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP,
125738 (const char *)&enable,
125739 sizeof (enable)) < 0)
125740#endif
125741 {
125742 UA_LOG_SOCKET_ERRNO_WRAP(
125743 UA_LOG_ERROR(logger, UA_LOGCATEGORY_NETWORK,
125744 "UDP %u\t| Loopback setup failed: "
125745 "Cannot set socket option IP_MULTICAST_LOOP. Error: %s",
125746 (unsigned)sockfd, errno_str));
125747 return UA_STATUSCODE_BADINTERNALERROR;
125748 }
125749 return UA_STATUSCODE_GOOD;
125750}
125751
125752static UA_StatusCode
125753setTimeToLive(UA_SOCKET sockfd, UA_UInt32 messageTTL,
125754 int ai_family, const UA_Logger *logger) {
125755 /* Set Time to live (TTL). Value of 1 prevent forward beyond the local network. */
125756#if UA_IPV6
125757 if(UA_setsockopt(fd: sockfd,
125758 level: ai_family == PF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP,
125759 optname: ai_family == PF_INET6 ? IPV6_MULTICAST_HOPS : IP_MULTICAST_TTL,
125760 optval: (const char *)&messageTTL,
125761 optlen: sizeof(messageTTL)) < 0)
125762#else
125763 if(UA_setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,
125764 (const char *)&messageTTL,
125765 sizeof(messageTTL)) < 0)
125766#endif
125767 {
125768 UA_LOG_SOCKET_ERRNO_WRAP(
125769 UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
125770 "UDP %u\t| Time to live setup failed: "
125771 "Cannot set socket option IP_MULTICAST_TTL. Error: %s",
125772 (unsigned)sockfd, errno_str));
125773 return UA_STATUSCODE_BADINTERNALERROR;
125774 }
125775 return UA_STATUSCODE_GOOD;
125776}
125777
125778static UA_StatusCode
125779setReuseAddress(UA_SOCKET sockfd, UA_Boolean enableReuse, const UA_Logger *logger) {
125780 /* Set reuse address -> enables sharing of the same listening address on
125781 * different sockets */
125782 int enableReuseVal = (enableReuse) ? 1 : 0;
125783 if(UA_setsockopt(fd: sockfd, SOL_SOCKET, SO_REUSEADDR,
125784 optval: (const char*)&enableReuseVal, optlen: sizeof(enableReuseVal)) < 0) {
125785 UA_LOG_SOCKET_ERRNO_WRAP(
125786 UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
125787 "UDP %u\t| Reuse address setup failed: "
125788 "Cannot set socket option SO_REUSEADDR. Error: %s",
125789 (unsigned)sockfd, errno_str));
125790 return UA_STATUSCODE_BADINTERNALERROR;
125791 }
125792 return UA_STATUSCODE_GOOD;
125793}
125794
125795#ifdef __linux__
125796static UA_StatusCode
125797setSocketPriority(UA_SOCKET sockfd, UA_UInt32 socketPriority,
125798 const UA_Logger *logger) {
125799 int prio = (int)socketPriority;
125800 if(UA_setsockopt(fd: sockfd, SOL_SOCKET, SO_PRIORITY, optval: &prio, optlen: sizeof(int)) < 0) {
125801 UA_LOG_SOCKET_ERRNO_WRAP(
125802 UA_LOG_ERROR(logger, UA_LOGCATEGORY_NETWORK,
125803 "UDP %u\t| Socket priority setup failed: "
125804 "Cannot set socket option SO_PRIORITY. Error: %s",
125805 (unsigned)sockfd, errno_str));
125806 return UA_STATUSCODE_BADINTERNALERROR;
125807 }
125808 return UA_STATUSCODE_GOOD;
125809}
125810#endif
125811
125812static UA_StatusCode
125813setConnectionConfig(UA_FD socket, const UA_KeyValueMap *params,
125814 int ai_family, const UA_Logger *logger) {
125815 /* Set socket config that is always set */
125816 UA_StatusCode res = UA_STATUSCODE_GOOD;
125817 res |= UA_EventLoopPOSIX_setNonBlocking(sockfd: socket);
125818 res |= UA_EventLoopPOSIX_setNoSigPipe(sockfd: socket);
125819 if(res != UA_STATUSCODE_GOOD)
125820 return res;
125821
125822 /* Some Linux distributions have net.ipv6.bindv6only not activated. So
125823 * sockets can double-bind to IPv4 and IPv6. This leads to problems. Use
125824 * AF_INET6 sockets only for IPv6. */
125825#if UA_IPV6
125826 int optval = 1;
125827 if(ai_family == AF_INET6 &&
125828 UA_setsockopt(fd: socket, IPPROTO_IPV6, IPV6_V6ONLY,
125829 optval: (const char*)&optval, optlen: sizeof(optval)) == -1) {
125830 UA_LOG_WARNING(logger, category: UA_LOGCATEGORY_NETWORK,
125831 msg: "UDP %u\t| Could not set an IPv6 socket to IPv6 only, closing",
125832 (unsigned)socket);
125833 return UA_STATUSCODE_BADCONNECTIONREJECTED;
125834 }
125835#endif
125836
125837 /* Set socket settings from the parameters */
125838 const UA_UInt32 *messageTTL = (const UA_UInt32*)
125839 UA_KeyValueMap_getScalar(map: params, key: UDPConfigParameters[UDP_PARAMINDEX_TTL].name,
125840 type: &UA_TYPES[UA_TYPES_UINT32]);
125841 if(messageTTL)
125842 res |= setTimeToLive(sockfd: socket, messageTTL: *messageTTL, ai_family, logger);
125843
125844 const UA_Boolean *enableLoopback = (const UA_Boolean*)
125845 UA_KeyValueMap_getScalar(map: params, key: UDPConfigParameters[UDP_PARAMINDEX_LOOPBACK].name,
125846 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
125847 if(enableLoopback)
125848 res |= setLoopBackData(sockfd: socket, enableLoopback: *enableLoopback, ai_family, logger);
125849
125850 const UA_Boolean *enableReuse = (const UA_Boolean*)
125851 UA_KeyValueMap_getScalar(map: params, key: UDPConfigParameters[UDP_PARAMINDEX_REUSE].name,
125852 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
125853 if(enableReuse)
125854 res |= setReuseAddress(sockfd: socket, enableReuse: *enableReuse, logger);
125855
125856#ifdef __linux__
125857 const UA_UInt32 *socketPriority = (const UA_UInt32*)
125858 UA_KeyValueMap_getScalar(map: params, key: UDPConfigParameters[UDP_PARAMINDEX_SOCKPRIO].name,
125859 type: &UA_TYPES[UA_TYPES_UINT32]);
125860 if(socketPriority)
125861 res |= setSocketPriority(sockfd: socket, socketPriority: *socketPriority, logger);
125862#endif
125863
125864 if(res != UA_STATUSCODE_GOOD) {
125865 UA_LOG_SOCKET_ERRNO_WRAP(
125866 UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
125867 "UDP\t| Could not set socket options: %s", errno_str));
125868 }
125869 return res;
125870}
125871
125872static UA_StatusCode
125873setupListenMultiCast(UA_FD fd, struct addrinfo *info, const UA_KeyValueMap *params,
125874 MultiCastType multiCastType, const UA_Logger *logger) {
125875 MulticastRequest req;
125876 UA_StatusCode res = setupMulticastRequest(socket: fd, req: &req, params, info, logger);
125877 if(res != UA_STATUSCODE_GOOD)
125878 return res;
125879
125880 int result = -1;
125881 if(info->ai_family == AF_INET && multiCastType == MULTICASTTYPE_IPV4) {
125882 result = UA_setsockopt(fd: fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
125883 optval: &req.ipv4, optlen: sizeof(req.ipv4));
125884#if UA_IPV6
125885 } else if(info->ai_family == AF_INET6 && multiCastType == MULTICASTTYPE_IPV6) {
125886 result = UA_setsockopt(fd: fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
125887 optval: &req.ipv6, optlen: sizeof(req.ipv6));
125888#endif
125889 }
125890
125891 if(result < 0) {
125892 UA_LOG_SOCKET_ERRNO_WRAP(
125893 UA_LOG_ERROR(logger, UA_LOGCATEGORY_NETWORK,
125894 "UDP %u\t| Cannot set socket for multicast receiving. Error: %s",
125895 (unsigned)fd, errno_str));
125896 return UA_STATUSCODE_BADINTERNALERROR;
125897 }
125898 return UA_STATUSCODE_GOOD;
125899}
125900
125901static UA_StatusCode
125902setupSendMultiCast(UA_FD fd, struct addrinfo *info, const UA_KeyValueMap *params,
125903 MultiCastType multiCastType, const UA_Logger *logger) {
125904 MulticastRequest req;
125905 UA_StatusCode res = setupMulticastRequest(socket: fd, req: &req, params, info, logger);
125906 if(res != UA_STATUSCODE_GOOD)
125907 return res;
125908
125909 int result = -1;
125910 if(info->ai_family == AF_INET && multiCastType == MULTICASTTYPE_IPV4) {
125911 result = setsockopt(fd: fd, IPPROTO_IP, IP_MULTICAST_IF,
125912#ifdef UA_ARCHITECTURE_WIN32
125913 (const char *)&req.ipv4.imr_interface,
125914 sizeof(struct in_addr));
125915#else
125916 optval: &req.ipv4, optlen: sizeof(req.ipv4));
125917#endif
125918#if UA_IPV6
125919 } else if(info->ai_family == AF_INET6 && multiCastType == MULTICASTTYPE_IPV6) {
125920 result = setsockopt(fd: fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
125921#ifdef UA_ARCHITECTURE_WIN32
125922 (const char *)&req.ipv6.ipv6mr_interface,
125923#else
125924 optval: &req.ipv6.ipv6mr_interface,
125925#endif
125926 optlen: sizeof(req.ipv6.ipv6mr_interface));
125927#endif
125928 }
125929
125930 if(result < 0) {
125931 UA_LOG_SOCKET_ERRNO_WRAP(
125932 UA_LOG_ERROR(logger, UA_LOGCATEGORY_NETWORK,
125933 "UDP %u\t| Cannot set socket for multicast sending. Error: %s",
125934 (unsigned)fd, errno_str));
125935 return UA_STATUSCODE_BADINTERNALERROR;
125936 }
125937 return UA_STATUSCODE_GOOD;
125938}
125939
125940/* Test if the ConnectionManager can be stopped */
125941static void
125942UDP_checkStopped(UA_POSIXConnectionManager *pcm) {
125943 UA_LOCK_ASSERT(&((UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop)->elMutex, 1);
125944
125945 if(pcm->fdsSize == 0 &&
125946 pcm->cm.eventSource.state == UA_EVENTSOURCESTATE_STOPPING) {
125947 UA_LOG_DEBUG(logger: pcm->cm.eventSource.eventLoop->logger, category: UA_LOGCATEGORY_NETWORK,
125948 msg: "UDP\t| All sockets closed, the EventLoop has stopped");
125949 pcm->cm.eventSource.state = UA_EVENTSOURCESTATE_STOPPED;
125950 }
125951}
125952
125953/* This method must not be called from the application directly, but from within
125954 * the EventLoop. Otherwise we cannot be sure whether the file descriptor is
125955 * still used after calling close. */
125956static void
125957UDP_close(UA_POSIXConnectionManager *pcm, UDP_FD *conn) {
125958 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop;
125959 UA_LOCK_ASSERT(&el->elMutex, 1);
125960
125961 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
125962 msg: "UDP %u\t| Closing connection",
125963 (unsigned)conn->rfd.fd);
125964
125965 /* Deregister from the EventLoop */
125966 UA_EventLoopPOSIX_deregisterFD(el, rfd: &conn->rfd);
125967
125968 /* Deregister internally */
125969 ZIP_REMOVE(UA_FDTree, &pcm->fds, &conn->rfd);
125970 UA_assert(pcm->fdsSize > 0);
125971 pcm->fdsSize--;
125972
125973 /* Signal closing to the application */
125974 conn->applicationCB(&pcm->cm, (uintptr_t)conn->rfd.fd,
125975 conn->application, &conn->context,
125976 UA_CONNECTIONSTATE_CLOSING,
125977 &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL);
125978
125979 /* Close the socket */
125980 int ret = UA_close(fd: conn->rfd.fd);
125981 if(ret == 0) {
125982 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
125983 msg: "UDP %u\t| Socket closed", (unsigned)conn->rfd.fd);
125984 } else {
125985 UA_LOG_SOCKET_ERRNO_WRAP(
125986 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
125987 "UDP %u\t| Could not close the socket (%s)",
125988 (unsigned)conn->rfd.fd, errno_str));
125989 }
125990
125991 UA_free(ptr: conn);
125992
125993 /* Stop if the ucm is stopping and this was the last open socket */
125994 UDP_checkStopped(pcm);
125995}
125996
125997static void
125998UDP_delayedClose(void *application, void *context) {
125999 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)application;
126000 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop;
126001 UDP_FD *conn = (UDP_FD*)context;
126002 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
126003 msg: "UDP %u\t| Delayed closing of the connection",
126004 (unsigned)conn->rfd.fd);
126005 UA_LOCK(&el->elMutex);
126006 UDP_close(pcm, conn);
126007 UA_UNLOCK(&el->elMutex);
126008}
126009
126010/* Gets called when a socket receives data or closes */
126011static void
126012UDP_connectionSocketCallback(UA_POSIXConnectionManager *pcm, UDP_FD *conn,
126013 short event) {
126014 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop;
126015 UA_LOCK_ASSERT(&el->elMutex, 1);
126016
126017 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126018 msg: "UDP %u\t| Activity on the socket",
126019 (unsigned)conn->rfd.fd);
126020
126021 if(event == UA_FDEVENT_ERR) {
126022 UA_LOG_SOCKET_ERRNO_WRAP(
126023 UA_LOG_DEBUG(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
126024 "UDP %u\t| recv signaled the socket was shutdown (%s)",
126025 (unsigned)conn->rfd.fd, errno_str));
126026 UDP_close(pcm, conn);
126027 return;
126028 }
126029
126030 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126031 msg: "UDP %u\t| Allocate receive buffer", (unsigned)conn->rfd.fd);
126032
126033 /* Use the already allocated receive-buffer */
126034 UA_ByteString response = pcm->rxBuffer;
126035
126036 /* Receive */
126037 struct sockaddr_storage source;
126038#ifndef UA_ARCHITECTURE_WIN32
126039 socklen_t sourceSize = (socklen_t)sizeof(struct sockaddr_storage);
126040 ssize_t ret = recvfrom(fd: conn->rfd.fd, buf: (char*)response.data, n: response.length,
126041 MSG_DONTWAIT, addr: (struct sockaddr*)&source, addr_len: &sourceSize);
126042#else
126043 int sourceSize = (int)sizeof(struct sockaddr_storage);
126044 int ret = recvfrom(conn->rfd.fd, (char*)response.data, (int)response.length,
126045 MSG_DONTWAIT, (struct sockaddr*)&source, &sourceSize);
126046#endif
126047
126048 /* Receive has failed */
126049 if(ret <= 0) {
126050 if(UA_ERRNO == UA_INTERRUPTED)
126051 return;
126052
126053 /* Orderly shutdown of the socket. We can immediately close as no method
126054 * "below" in the call stack will use the socket in this iteration of
126055 * the EventLoop. */
126056 UA_LOG_SOCKET_ERRNO_WRAP(
126057 UA_LOG_DEBUG(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
126058 "UDP %u\t| recv signaled the socket was shutdown (%s)",
126059 (unsigned)conn->rfd.fd, errno_str));
126060 UDP_close(pcm, conn);
126061 return;
126062 }
126063
126064 response.length = (size_t)ret; /* Set the length of the received buffer */
126065
126066 /* Extract message source and port */
126067 char sourceAddr[64];
126068 UA_UInt16 sourcePort;
126069 switch(source.ss_family) {
126070 case AF_INET:
126071 inet_ntop(AF_INET, cp: &((struct sockaddr_in *)&source)->sin_addr,
126072 buf: sourceAddr, len: 64);
126073 sourcePort = htons(hostshort: ((struct sockaddr_in *)&source)->sin_port);
126074 break;
126075 case AF_INET6:
126076 inet_ntop(AF_INET6, cp: &(((struct sockaddr_in6 *)&source)->sin6_addr),
126077 buf: sourceAddr, len: 64);
126078 sourcePort = htons(hostshort: ((struct sockaddr_in6 *)&source)->sin6_port);
126079 break;
126080 default:
126081 sourceAddr[0] = 0;
126082 sourcePort = 0;
126083 }
126084
126085 UA_String sourceAddrStr = UA_STRING(chars: sourceAddr);
126086 UA_KeyValuePair kvp[2];
126087 kvp[0].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "remote-address");
126088 UA_Variant_setScalar(v: &kvp[0].value, p: &sourceAddrStr, type: &UA_TYPES[UA_TYPES_STRING]);
126089 kvp[1].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "remote-port");
126090 UA_Variant_setScalar(v: &kvp[1].value, p: &sourcePort, type: &UA_TYPES[UA_TYPES_UINT16]);
126091 UA_KeyValueMap kvm = {2, kvp};
126092
126093 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126094 msg: "UDP %u\t| Received message of size %u from %s on port %u",
126095 (unsigned)conn->rfd.fd, (unsigned)ret,
126096 sourceAddr, sourcePort);
126097
126098 /* Callback to the application layer */
126099 conn->applicationCB(&pcm->cm, (uintptr_t)conn->rfd.fd,
126100 conn->application, &conn->context,
126101 UA_CONNECTIONSTATE_ESTABLISHED,
126102 &kvm, response);
126103}
126104
126105static UA_StatusCode
126106UDP_registerListenSocket(UA_POSIXConnectionManager *pcm, UA_UInt16 port,
126107 struct addrinfo *info, const UA_KeyValueMap *params,
126108 void *application, void *context,
126109 UA_ConnectionManager_connectionCallback connectionCallback,
126110 UA_Boolean validate) {
126111 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop;
126112 UA_LOCK_ASSERT(&el->elMutex, 1);
126113
126114 /* Get logging information */
126115 char hoststr[UA_MAXHOSTNAME_LENGTH];
126116 int get_res = UA_getnameinfo(info->ai_addr, info->ai_addrlen,
126117 hoststr, sizeof(hoststr),
126118 NULL, 0, NI_NUMERICHOST);
126119 if(get_res != 0) {
126120 hoststr[0] = 0;
126121 UA_LOG_SOCKET_ERRNO_WRAP(
126122 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
126123 "UDP\t| getnameinfo(...) could not resolve the hostname (%s)",
126124 errno_str));
126125 if(validate) {
126126 return UA_STATUSCODE_BADCONNECTIONREJECTED;
126127 }
126128 }
126129
126130 /* Create the listen socket */
126131 UA_FD listenSocket = socket(domain: info->ai_family, type: info->ai_socktype, protocol: info->ai_protocol);
126132 if(listenSocket == UA_INVALID_FD) {
126133 UA_LOG_SOCKET_ERRNO_WRAP(
126134 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
126135 "UDP %u\t| Error opening the listen socket for "
126136 "\"%s\" on port %u (%s)",
126137 (unsigned)listenSocket, hoststr, port, errno_str));
126138 return UA_STATUSCODE_BADCONNECTIONREJECTED;
126139 }
126140
126141 /* Set the socket configuration per the parameters */
126142 UA_StatusCode res =
126143 setConnectionConfig(socket: listenSocket, params,
126144 ai_family: info->ai_family, logger: el->eventLoop.logger);
126145 if(res != UA_STATUSCODE_GOOD) {
126146 UA_close(fd: listenSocket);
126147 return UA_STATUSCODE_BADCONNECTIONREJECTED;
126148 }
126149
126150 /* Are we going to prepare a socket for multicast? */
126151 MultiCastType mc = multiCastType(info);
126152
126153 /* Bind socket to the address */
126154#ifdef UA_ARCHITECTURE_WIN32
126155 /* On windows we need to bind the socket to INADDR_ANY before registering
126156 * for the multicast group */
126157 int ret = -1;
126158 if(mc != MULTICASTTYPE_NONE) {
126159 if(info->ai_family == AF_INET) {
126160 struct sockaddr_in *orig = (struct sockaddr_in *)info->ai_addr;
126161 struct sockaddr_in sin;
126162 memset(&sin, 0, sizeof(sin));
126163 sin.sin_family = AF_INET;
126164 sin.sin_addr.s_addr = htonl(INADDR_ANY);
126165 sin.sin_port = orig->sin_port;
126166 ret = bind(listenSocket, (struct sockaddr*)&sin, sizeof(sin));
126167 } else if(info->ai_family == AF_INET6) {
126168 struct sockaddr_in6 *orig = (struct sockaddr_in6 *)info->ai_addr;
126169 struct sockaddr_in6 sin6;
126170 memset(&sin6, 0, sizeof(sin6));
126171 sin6.sin6_family = AF_INET6;
126172 sin6.sin6_addr = in6addr_any;
126173 sin6.sin6_port = orig->sin6_port;
126174 ret = bind(listenSocket, (struct sockaddr*)&sin6, sizeof(sin6));
126175 }
126176 } else {
126177 ret = bind(listenSocket, info->ai_addr, (socklen_t)info->ai_addrlen);
126178 }
126179#else
126180 int ret = bind(fd: listenSocket, addr: info->ai_addr, len: (socklen_t)info->ai_addrlen);
126181#endif
126182
126183 /* Get the port being used if dynamic porting was used */
126184 if(port == 0) {
126185 struct sockaddr_in sin;
126186 memset(s: &sin, c: 0, n: sizeof(sin));
126187 socklen_t len = sizeof(sin);
126188 getsockname(fd: listenSocket, addr: (struct sockaddr *)&sin, len: &len);
126189 port = ntohs(netshort: sin.sin_port);
126190 }
126191
126192 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126193 msg: "UDP %u\t| New listen socket for \"%s\" on port %u",
126194 (unsigned)listenSocket, hoststr, port);
126195
126196 if(ret < 0) {
126197 UA_LOG_SOCKET_ERRNO_WRAP(
126198 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
126199 "UDP %u\t| Error binding the socket to the address (%s), closing",
126200 (unsigned)listenSocket, errno_str));
126201 UA_close(fd: listenSocket);
126202 return UA_STATUSCODE_BADCONNECTIONREJECTED;
126203 }
126204
126205 /* Enable multicast if this is a multicast address */
126206 if(mc != MULTICASTTYPE_NONE) {
126207 res = setupListenMultiCast(fd: listenSocket, info, params,
126208 multiCastType: mc, logger: el->eventLoop.logger);
126209 if(res != UA_STATUSCODE_GOOD) {
126210 UA_close(fd: listenSocket);
126211 return res;
126212 }
126213 }
126214
126215 /* Validation is complete - close and return */
126216 if(validate) {
126217 UA_close(fd: listenSocket);
126218 return UA_STATUSCODE_GOOD;
126219 }
126220
126221 /* Allocate the UA_RegisteredFD */
126222 UDP_FD *newudpfd = (UDP_FD*)UA_calloc(nmemb: 1, size: sizeof(UDP_FD));
126223 if(!newudpfd) {
126224 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126225 msg: "UDP %u\t| Error allocating memory for the socket, closing",
126226 (unsigned)listenSocket);
126227 UA_close(fd: listenSocket);
126228 return UA_STATUSCODE_BADCONNECTIONREJECTED;
126229 }
126230
126231 newudpfd->rfd.fd = listenSocket;
126232 newudpfd->rfd.es = &pcm->cm.eventSource;
126233 newudpfd->rfd.listenEvents = UA_FDEVENT_IN;
126234 newudpfd->rfd.eventSourceCB = (UA_FDCallback)UDP_connectionSocketCallback;
126235 newudpfd->applicationCB = connectionCallback;
126236 newudpfd->application = application;
126237 newudpfd->context = context;
126238
126239 /* Register in the EventLoop */
126240 res = UA_EventLoopPOSIX_registerFD(el, rfd: &newudpfd->rfd);
126241 if(res != UA_STATUSCODE_GOOD) {
126242 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126243 msg: "UDP %u\t| Error registering the socket, closing",
126244 (unsigned)listenSocket);
126245 UA_free(ptr: newudpfd);
126246 UA_close(fd: listenSocket);
126247 return res;
126248 }
126249
126250 /* Register internally in the EventSource */
126251 ZIP_INSERT(UA_FDTree, &pcm->fds, &newudpfd->rfd);
126252 pcm->fdsSize++;
126253
126254 /* Register the listen socket in the application */
126255 connectionCallback(&pcm->cm, (uintptr_t)newudpfd->rfd.fd,
126256 application, &newudpfd->context,
126257 UA_CONNECTIONSTATE_ESTABLISHED,
126258 &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL);
126259 return UA_STATUSCODE_GOOD;
126260}
126261
126262static UA_StatusCode
126263UDP_registerListenSockets(UA_POSIXConnectionManager *pcm, const char *hostname,
126264 UA_UInt16 port, const UA_KeyValueMap *params,
126265 void *application, void *context,
126266 UA_ConnectionManager_connectionCallback connectionCallback,
126267 UA_Boolean validate) {
126268 UA_LOCK_ASSERT(&((UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop)->elMutex, 1);
126269
126270 /* Get all the interface and IPv4/6 combinations for the configured hostname */
126271 struct addrinfo hints, *res;
126272 memset(s: &hints, c: 0, n: sizeof hints);
126273#if UA_IPV6
126274 hints.ai_family = AF_UNSPEC; /* Allow IPv4 and IPv6 */
126275#else
126276 hints.ai_family = AF_INET; /* IPv4 only */
126277#endif
126278 hints.ai_socktype = SOCK_DGRAM;
126279 hints.ai_protocol = IPPROTO_UDP;
126280 hints.ai_flags = AI_PASSIVE;
126281
126282 /* Set up the port string */
126283 char portstr[6];
126284 mp_snprintf(s: portstr, n: 6, format: "%d", port);
126285
126286 int retcode = getaddrinfo(name: hostname, service: portstr, req: &hints, pai: &res);
126287 if(retcode != 0) {
126288 UA_LOG_SOCKET_ERRNO_GAI_WRAP(
126289 UA_LOG_WARNING(pcm->cm.eventSource.eventLoop->logger,
126290 UA_LOGCATEGORY_NETWORK,
126291 "UDP\t| getaddrinfo lookup for \"%s\" on port %u failed (%s)",
126292 hostname, port, errno_str));
126293 return UA_STATUSCODE_BADCONNECTIONREJECTED;
126294 }
126295
126296 /* Add listen sockets */
126297 struct addrinfo *ai = res;
126298 UA_StatusCode rv = UA_STATUSCODE_GOOD;
126299 while(ai) {
126300 rv = UDP_registerListenSocket(pcm, port, info: ai, params, application,
126301 context, connectionCallback, validate);
126302 if(rv != UA_STATUSCODE_GOOD)
126303 break;
126304 ai = ai->ai_next;
126305 }
126306 freeaddrinfo(ai: res);
126307 return rv;
126308}
126309
126310/* Close the connection via a delayed callback */
126311static void
126312UDP_shutdown(UA_ConnectionManager *cm, UA_RegisteredFD *rfd) {
126313 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX *)cm->eventSource.eventLoop;
126314 UA_LOCK_ASSERT(&el->elMutex, 1);
126315
126316 if(rfd->dc.callback) {
126317 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126318 msg: "UDP %u\t| Cannot close - already closing",
126319 (unsigned)rfd->fd);
126320 return;
126321 }
126322
126323 /* Shutdown the socket to cancel the current select/epoll */
126324 shutdown(fd: rfd->fd, UA_SHUT_RDWR);
126325
126326 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126327 msg: "UDP %u\t| Shutdown called", (unsigned)rfd->fd);
126328
126329 UA_DelayedCallback *dc = &rfd->dc;
126330 dc->callback = UDP_delayedClose;
126331 dc->application = cm;
126332 dc->context = rfd;
126333
126334 /* Don't use the "public" el->addDelayedCallback. It takes a lock. */
126335 dc->next = el->delayedCallbacks;
126336 el->delayedCallbacks = dc;
126337}
126338
126339static UA_StatusCode
126340UDP_shutdownConnection(UA_ConnectionManager *cm, uintptr_t connectionId) {
126341 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
126342 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX *)cm->eventSource.eventLoop;
126343 UA_FD fd = (UA_FD)connectionId;
126344
126345 UA_LOCK(&el->elMutex);
126346 UA_RegisteredFD *rfd = ZIP_FIND(UA_FDTree, &pcm->fds, &fd);
126347 if(!rfd) {
126348 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126349 msg: "UDP\t| Cannot close UDP connection %u - not found",
126350 (unsigned)connectionId);
126351 UA_UNLOCK(&el->elMutex);
126352 return UA_STATUSCODE_BADNOTFOUND;
126353 }
126354 UDP_shutdown(cm, rfd);
126355 UA_UNLOCK(&el->elMutex);
126356 return UA_STATUSCODE_GOOD;
126357}
126358
126359static UA_StatusCode
126360UDP_sendWithConnection(UA_ConnectionManager *cm, uintptr_t connectionId,
126361 const UA_KeyValueMap *params,
126362 UA_ByteString *buf) {
126363 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
126364 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
126365
126366 UA_LOCK(&el->elMutex);
126367
126368 /* Look up the registered UDP socket */
126369 UA_FD fd = (UA_FD)connectionId;
126370 UDP_FD *conn = (UDP_FD*)ZIP_FIND(UA_FDTree, &pcm->fds, &fd);
126371 if(!conn) {
126372 UA_UNLOCK(&el->elMutex);
126373 UA_ByteString_clear(p: buf);
126374 return UA_STATUSCODE_BADINTERNALERROR;
126375 }
126376
126377 /* Send the full buffer. This may require several calls to send */
126378 size_t nWritten = 0;
126379 do {
126380 ssize_t n = 0;
126381 do {
126382 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126383 msg: "UDP %u\t| Attempting to send", (unsigned)connectionId);
126384
126385 /* Prevent OS signals when sending to a closed socket */
126386 int flags = MSG_NOSIGNAL;
126387 size_t bytes_to_send = buf->length - nWritten;
126388 n = UA_sendto(fd: (UA_FD)connectionId, buf: (const char*)buf->data + nWritten,
126389 n: bytes_to_send, flags: flags, addr: (struct sockaddr*)&conn->sendAddr,
126390 addr_len: conn->sendAddrLength);
126391 if(n < 0) {
126392 /* An error we cannot recover from? */
126393 if(UA_ERRNO != UA_INTERRUPTED &&
126394 UA_ERRNO != UA_WOULDBLOCK &&
126395 UA_ERRNO != UA_AGAIN) {
126396 UA_LOG_SOCKET_ERRNO_WRAP(
126397 UA_LOG_ERROR(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
126398 "UDP %u\t| Send failed with error %s",
126399 (unsigned)connectionId, errno_str));
126400 UA_UNLOCK(&el->elMutex);
126401 UDP_shutdownConnection(cm, connectionId);
126402 UA_ByteString_clear(p: buf);
126403 return UA_STATUSCODE_BADCONNECTIONCLOSED;
126404 }
126405
126406 /* Poll for the socket resources to become available and retry
126407 * (blocking) */
126408 int poll_ret;
126409 struct pollfd tmp_poll_fd;
126410 tmp_poll_fd.fd = (UA_FD)connectionId;
126411 tmp_poll_fd.events = UA_POLLOUT;
126412 do {
126413 poll_ret = UA_poll(fds: &tmp_poll_fd, nfds: 1, timeout: 100);
126414 if(poll_ret < 0 && UA_ERRNO != UA_INTERRUPTED) {
126415 UA_LOG_SOCKET_ERRNO_WRAP(
126416 UA_LOG_ERROR(el->eventLoop.logger,
126417 UA_LOGCATEGORY_NETWORK,
126418 "UDP %u\t| Send failed with error %s",
126419 (unsigned)connectionId, errno_str));
126420 UA_UNLOCK(&el->elMutex);
126421 UDP_shutdownConnection(cm, connectionId);
126422 UA_ByteString_clear(p: buf);
126423 return UA_STATUSCODE_BADCONNECTIONCLOSED;
126424 }
126425 } while(poll_ret <= 0);
126426 }
126427 } while(n < 0);
126428 nWritten += (size_t)n;
126429 } while(nWritten < buf->length);
126430
126431 /* Free the buffer */
126432 UA_UNLOCK(&el->elMutex);
126433 UA_ByteString_clear(p: buf);
126434 return UA_STATUSCODE_GOOD;
126435}
126436
126437static UA_StatusCode
126438registerSocketAndDestinationForSend(const UA_KeyValueMap *params,
126439 const char *hostname, struct addrinfo *info,
126440 int error, UDP_FD *ufd, UA_FD *sock,
126441 const UA_Logger *logger) {
126442 UA_FD newSock = socket(domain: info->ai_family, type: info->ai_socktype, protocol: info->ai_protocol);
126443 *sock = newSock;
126444 if(newSock == UA_INVALID_FD) {
126445 UA_LOG_SOCKET_ERRNO_WRAP(
126446 UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK,
126447 "UDP\t| Could not create socket to connect to %s (%s)",
126448 hostname, errno_str));
126449 return UA_STATUSCODE_BADDISCONNECT;
126450 }
126451 UA_StatusCode res = setConnectionConfig(socket: newSock, params, ai_family: info->ai_family, logger);
126452 if(res != UA_STATUSCODE_GOOD) {
126453 UA_close(fd: newSock);
126454 return res;
126455 }
126456
126457 /* Prepare socket for multicast */
126458 MultiCastType mc = multiCastType(info);
126459 if(mc != MULTICASTTYPE_NONE) {
126460 res = setupSendMultiCast(fd: newSock, info, params, multiCastType: mc, logger);
126461 if(res != UA_STATUSCODE_GOOD) {
126462 UA_close(fd: newSock);
126463 return res;
126464 }
126465 }
126466
126467 memcpy(dest: &ufd->sendAddr, src: info->ai_addr, n: info->ai_addrlen);
126468 ufd->sendAddrLength = info->ai_addrlen;
126469 return UA_STATUSCODE_GOOD;
126470}
126471
126472static UA_StatusCode
126473UDP_openSendConnection(UA_POSIXConnectionManager *pcm, const UA_KeyValueMap *params,
126474 void *application, void *context,
126475 UA_ConnectionManager_connectionCallback connectionCallback,
126476 UA_Boolean validate) {
126477 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX *)pcm->cm.eventSource.eventLoop;
126478 UA_LOCK_ASSERT(&el->elMutex, 1);
126479
126480 /* Get the connection parameters */
126481 char hostname[UA_MAXHOSTNAME_LENGTH];
126482 char portStr[UA_MAXPORTSTR_LENGTH];
126483 struct addrinfo *info = NULL;
126484
126485 int error = getConnectionInfoFromParams(params, hostname,
126486 portStr, info: &info, logger: el->eventLoop.logger);
126487 if(error < 0 || info == NULL) {
126488 if(info != NULL) {
126489 freeaddrinfo(ai: info);
126490 }
126491 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126492 msg: "UDP\t| Opening a connection failed");
126493 return UA_STATUSCODE_BADCONNECTIONREJECTED;
126494 }
126495 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126496 msg: "UDP\t| Open a connection to \"%s\" on port %s", hostname, portStr);
126497
126498 /* Allocate the UA_RegisteredFD */
126499 UDP_FD *conn = (UDP_FD*)UA_calloc(nmemb: 1, size: sizeof(UDP_FD));
126500 if(!conn) {
126501 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126502 msg: "UDP\t| Error allocating memory for the socket, closing");
126503 return UA_STATUSCODE_BADOUTOFMEMORY;
126504 }
126505
126506 /* Create a socket and register the destination address from the provided parameters */
126507 UA_FD newSock = UA_INVALID_FD;
126508 UA_StatusCode res =
126509 registerSocketAndDestinationForSend(params, hostname, info,
126510 error, ufd: conn, sock: &newSock,
126511 logger: el->eventLoop.logger);
126512 freeaddrinfo(ai: info);
126513 if(validate && res == UA_STATUSCODE_GOOD) {
126514 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126515 msg: "UDP %u\t| Connection validated to \"%s\" on port %s",
126516 (unsigned)newSock, hostname, portStr);
126517 UA_close(fd: newSock);
126518 UA_free(ptr: conn);
126519 return UA_STATUSCODE_GOOD;
126520 }
126521 if(res != UA_STATUSCODE_GOOD) {
126522 UA_free(ptr: conn);
126523 return res;
126524 }
126525
126526 conn->rfd.fd = newSock;
126527 conn->rfd.listenEvents = 0;
126528 conn->rfd.es = &pcm->cm.eventSource;
126529 conn->rfd.eventSourceCB = (UA_FDCallback)UDP_connectionSocketCallback;
126530 conn->applicationCB = connectionCallback;
126531 conn->application = application;
126532 conn->context = context;
126533
126534 /* Register the fd to trigger when output is possible (the connection is open) */
126535 res = UA_EventLoopPOSIX_registerFD(el, rfd: &conn->rfd);
126536 if(res != UA_STATUSCODE_GOOD) {
126537 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126538 msg: "UDP\t| Registering the socket for %s failed", hostname);
126539 UA_close(fd: newSock);
126540 UA_free(ptr: conn);
126541 return res;
126542 }
126543
126544 /* Register internally in the EventSource */
126545 ZIP_INSERT(UA_FDTree, &pcm->fds, &conn->rfd);
126546 pcm->fdsSize++;
126547
126548 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126549 msg: "UDP %u\t| New connection to \"%s\" on port %s",
126550 (unsigned)newSock, hostname, portStr);
126551
126552 /* Signal the connection as opening. The connection fully opens in the next
126553 * iteration of the EventLoop */
126554 connectionCallback(&pcm->cm, (uintptr_t)newSock, application,
126555 &conn->context, UA_CONNECTIONSTATE_ESTABLISHED,
126556 &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL);
126557
126558 return UA_STATUSCODE_GOOD;
126559}
126560
126561static UA_StatusCode
126562UDP_openReceiveConnection(UA_POSIXConnectionManager *pcm, const UA_KeyValueMap *params,
126563 void *application, void *context,
126564 UA_ConnectionManager_connectionCallback connectionCallback,
126565 UA_Boolean validate) {
126566 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop;
126567 UA_LOCK_ASSERT(&el->elMutex, 1);
126568
126569 /* Get the port */
126570 const UA_UInt16 *port = (const UA_UInt16*)
126571 UA_KeyValueMap_getScalar(map: params, key: UDPConfigParameters[UDP_PARAMINDEX_PORT].name,
126572 type: &UA_TYPES[UA_TYPES_UINT16]);
126573 UA_assert(port); /* checked before */
126574
126575 /* Get the hostname configuration */
126576 const UA_Variant *addrs =
126577 UA_KeyValueMap_get(map: params, key: UDPConfigParameters[UDP_PARAMINDEX_ADDR].name);
126578 size_t addrsSize = 0;
126579 if(addrs) {
126580 UA_assert(addrs->type == &UA_TYPES[UA_TYPES_STRING]);
126581 if(UA_Variant_isScalar(v: addrs))
126582 addrsSize = 1;
126583 else
126584 addrsSize = addrs->arrayLength;
126585 }
126586
126587 /* No hostname configured -> listen on all interfaces */
126588 if(addrsSize == 0) {
126589 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126590 msg: "UDP\t| Listening on all interfaces");
126591 return UDP_registerListenSockets(pcm, NULL, port: *port, params, application,
126592 context, connectionCallback, validate);
126593 }
126594
126595 /* Iterate over the configured hostnames */
126596 UA_String *hostStrings = (UA_String*)addrs->data;
126597 for(size_t i = 0; i < addrsSize; i++) {
126598 char hn[UA_MAXHOSTNAME_LENGTH];
126599 if(hostStrings[i].length >= sizeof(hn))
126600 continue;
126601 memcpy(dest: hn, src: hostStrings[i].data, n: hostStrings->length);
126602 hn[hostStrings->length] = '\0';
126603 UA_StatusCode rv =
126604 UDP_registerListenSockets(pcm, hostname: hn, port: *port, params, application,
126605 context, connectionCallback, validate);
126606 if(rv != UA_STATUSCODE_GOOD)
126607 return rv;
126608 }
126609
126610 return UA_STATUSCODE_GOOD;
126611}
126612
126613static UA_StatusCode
126614UDP_openConnection(UA_ConnectionManager *cm, const UA_KeyValueMap *params,
126615 void *application, void *context,
126616 UA_ConnectionManager_connectionCallback connectionCallback) {
126617 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
126618 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
126619 UA_LOCK(&el->elMutex);
126620
126621 if(cm->eventSource.state != UA_EVENTSOURCESTATE_STARTED) {
126622 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126623 msg: "UDP\t| Cannot open a connection for a "
126624 "ConnectionManager that is not started");
126625 UA_UNLOCK(&el->elMutex);
126626 return UA_STATUSCODE_BADINTERNALERROR;
126627 }
126628
126629 /* Check the parameters */
126630 UA_StatusCode res =
126631 UA_KeyValueRestriction_validate(logger: el->eventLoop.logger, logprefix: "UDP",
126632 restrictions: &UDPConfigParameters[1],
126633 UDP_PARAMETERSSIZE-1, map: params);
126634 if(res != UA_STATUSCODE_GOOD) {
126635 UA_UNLOCK(&el->elMutex);
126636 return res;
126637 }
126638
126639 UA_Boolean validate = false;
126640 const UA_Boolean *validationValue = (const UA_Boolean*)
126641 UA_KeyValueMap_getScalar(map: params, key: UDPConfigParameters[UDP_PARAMINDEX_VALIDATE].name,
126642 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
126643 if(validationValue)
126644 validate = *validationValue;
126645
126646 UA_Boolean listen = false;
126647 const UA_Boolean *listenValue = (const UA_Boolean*)
126648 UA_KeyValueMap_getScalar(map: params, key: UDPConfigParameters[UDP_PARAMINDEX_LISTEN].name,
126649 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
126650 if(listenValue)
126651 listen = *listenValue;
126652
126653 if(listen) {
126654 res = UDP_openReceiveConnection(pcm, params, application, context,
126655 connectionCallback, validate);
126656 } else {
126657 res = UDP_openSendConnection(pcm, params, application, context,
126658 connectionCallback, validate);
126659 }
126660 UA_UNLOCK(&el->elMutex);
126661 return res;
126662}
126663
126664static UA_StatusCode
126665UDP_eventSourceStart(UA_ConnectionManager *cm) {
126666 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
126667 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
126668 if(!el)
126669 return UA_STATUSCODE_BADINTERNALERROR;
126670
126671 UA_LOCK(&el->elMutex);
126672
126673 /* Check the state */
126674 if(cm->eventSource.state != UA_EVENTSOURCESTATE_STOPPED) {
126675 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
126676 msg: "UDP\t| To start the ConnectionManager, "
126677 "it has to be registered in an EventLoop and not started");
126678 UA_UNLOCK(&el->elMutex);
126679 return UA_STATUSCODE_BADINTERNALERROR;
126680 }
126681
126682 /* Check the parameters */
126683 UA_StatusCode res =
126684 UA_KeyValueRestriction_validate(logger: el->eventLoop.logger, logprefix: "UDP",
126685 restrictions: UDPConfigParameters, restrictionsSize: 1,
126686 map: &cm->eventSource.params);
126687 if(res != UA_STATUSCODE_GOOD)
126688 goto finish;
126689
126690 /* Allocate the rx buffer */
126691 res = UA_EventLoopPOSIX_allocateRXBuffer(pcm);
126692 if(res != UA_STATUSCODE_GOOD)
126693 goto finish;
126694
126695 /* Set the EventSource to the started state */
126696 cm->eventSource.state = UA_EVENTSOURCESTATE_STARTED;
126697
126698 finish:
126699 UA_UNLOCK(&el->elMutex);
126700 return res;
126701}
126702
126703static void *
126704UDP_shutdownCB(void *application, UA_RegisteredFD *rfd) {
126705 UA_ConnectionManager *cm = (UA_ConnectionManager*)application;
126706 UDP_shutdown(cm, rfd);
126707 return NULL;
126708}
126709
126710static void
126711UDP_eventSourceStop(UA_ConnectionManager *cm) {
126712 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
126713 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
126714 (void)el;
126715 UA_LOCK(&el->elMutex);
126716
126717 UA_LOG_INFO(logger: cm->eventSource.eventLoop->logger, category: UA_LOGCATEGORY_NETWORK,
126718 msg: "UDP\t| Shutting down the ConnectionManager");
126719
126720 /* Prevent new connections to open */
126721 cm->eventSource.state = UA_EVENTSOURCESTATE_STOPPING;
126722
126723 /* Shutdown all existing connection */
126724 ZIP_ITER(UA_FDTree, &pcm->fds, UDP_shutdownCB, cm);
126725
126726 /* Check if stopped once more (also checking inside UDP_close, but there we
126727 * don't check if there is no rfd at all) */
126728 UDP_checkStopped(pcm);
126729
126730 UA_UNLOCK(&el->elMutex);
126731}
126732
126733static UA_StatusCode
126734UDP_eventSourceDelete(UA_ConnectionManager *cm) {
126735 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
126736 if(cm->eventSource.state >= UA_EVENTSOURCESTATE_STARTING) {
126737 UA_LOG_ERROR(logger: cm->eventSource.eventLoop->logger, category: UA_LOGCATEGORY_EVENTLOOP,
126738 msg: "UDP\t| The EventSource must be stopped before it can be deleted");
126739 return UA_STATUSCODE_BADINTERNALERROR;
126740 }
126741
126742 UA_ByteString_clear(p: &pcm->rxBuffer);
126743 UA_KeyValueMap_clear(map: &cm->eventSource.params);
126744 UA_String_clear(p: &cm->eventSource.name);
126745 UA_free(ptr: cm);
126746
126747 return UA_STATUSCODE_GOOD;
126748}
126749
126750static const char *udpName = "udp";
126751
126752UA_ConnectionManager *
126753UA_ConnectionManager_new_POSIX_UDP(const UA_String eventSourceName) {
126754 UA_POSIXConnectionManager *cm = (UA_POSIXConnectionManager*)
126755 UA_calloc(nmemb: 1, size: sizeof(UA_POSIXConnectionManager));
126756 if(!cm)
126757 return NULL;
126758
126759 cm->cm.eventSource.eventSourceType = UA_EVENTSOURCETYPE_CONNECTIONMANAGER;
126760 UA_String_copy(src: &eventSourceName, dst: &cm->cm.eventSource.name);
126761 cm->cm.eventSource.start = (UA_StatusCode (*)(UA_EventSource *))UDP_eventSourceStart;
126762 cm->cm.eventSource.stop = (void (*)(UA_EventSource *))UDP_eventSourceStop;
126763 cm->cm.eventSource.free = (UA_StatusCode (*)(UA_EventSource *))UDP_eventSourceDelete;
126764 cm->cm.protocol = UA_STRING(chars: (char*)(uintptr_t)udpName);
126765 cm->cm.openConnection = UDP_openConnection;
126766 cm->cm.allocNetworkBuffer = UA_EventLoopPOSIX_allocNetworkBuffer;
126767 cm->cm.freeNetworkBuffer = UA_EventLoopPOSIX_freeNetworkBuffer;
126768 cm->cm.sendWithConnection = UDP_sendWithConnection;
126769 cm->cm.closeConnection = UDP_shutdownConnection;
126770 return &cm->cm;
126771}
126772
126773/**** amalgamated original file "/arch/eventloop_posix_interrupt.c" ****/
126774
126775/* This Source Code Form is subject to the terms of the Mozilla Public
126776 * License, v. 2.0. If a copy of the MPL was not distributed with this
126777 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
126778 *
126779 * Copyright 2021 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
126780 */
126781
126782#include <signal.h>
126783
126784/* Different implementation approaches:
126785 * - Linux: Use signalfd
126786 * - Other: Use the self-pipe trick (http://cr.yp.to/docs/selfpipe.html) */
126787
126788typedef struct UA_RegisteredSignal {
126789#ifdef UA_HAVE_EPOLL
126790 /* With epoll, register each signal with a socket.
126791 * This has to be the first element of the struct to allow casting. */
126792 UA_RegisteredFD rfd;
126793#else
126794 /* Without epoll, we add the rfd to a tailq and self-pipe to trigger the
126795 * traversal of the tailq */
126796 TAILQ_ENTRY(UA_RegisteredSignal) triggeredEntry;
126797#endif
126798
126799 LIST_ENTRY(UA_RegisteredSignal) listPointers;
126800
126801 UA_InterruptCallback signalCallback;
126802 void *context;
126803 int signal; /* POSIX identifier of the interrupt signal */
126804
126805 UA_Boolean active; /* Signals are only active when the EventLoop is started */
126806 UA_Boolean triggered;
126807} UA_RegisteredSignal;
126808
126809typedef struct {
126810 UA_InterruptManager im;
126811
126812 /* Registered signals */
126813 size_t signalsSize;
126814 LIST_HEAD(, UA_RegisteredSignal) signals;
126815
126816#ifndef UA_HAVE_EPOLL
126817 UA_RegisteredFD readFD;
126818 UA_FD writeFD;
126819 TAILQ_HEAD(, UA_RegisteredSignal) triggered;
126820#endif
126821} UA_POSIXInterruptManager;
126822
126823#ifndef UA_HAVE_EPOLL
126824/* On non-linux systems we can have at most one interrupt manager */
126825static UA_POSIXInterruptManager *singletonIM = NULL;
126826#endif
126827
126828/* The following methods have to be implemented for epoll/self-pipe each. */
126829static void activateSignal(UA_RegisteredSignal *rs);
126830static void deactivateSignal(UA_RegisteredSignal *rs);
126831
126832#ifdef UA_HAVE_EPOLL
126833#include <sys/signalfd.h>
126834
126835static void
126836handlePOSIXInterruptEvent(UA_EventSource *es, UA_RegisteredFD *rfd, short event) {
126837 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX *)es->eventLoop;
126838 (void)el;
126839 UA_LOCK_ASSERT(&el->elMutex, 1);
126840
126841 UA_RegisteredSignal *rs = (UA_RegisteredSignal*)rfd;
126842 struct signalfd_siginfo fdsi;
126843 ssize_t s = read(fd: rfd->fd, buf: &fdsi, nbytes: sizeof(fdsi));
126844 if(s < (ssize_t)sizeof(fdsi)) {
126845 /* A problem occured */
126846 deactivateSignal(rs);
126847 return;
126848 }
126849
126850 /* Signal received */
126851 UA_LOG_DEBUG(logger: es->eventLoop->logger, category: UA_LOGCATEGORY_EVENTLOOP,
126852 msg: "Interrupt %u\t| Received a signal %u",
126853 (unsigned)rfd->fd, fdsi.ssi_signo);
126854
126855 UA_UNLOCK(&el->elMutex);
126856 rs->signalCallback((UA_InterruptManager *)es, (uintptr_t)rfd->fd,
126857 rs->context, &UA_KEYVALUEMAP_NULL);
126858 UA_LOCK(&el->elMutex);
126859}
126860
126861static void
126862activateSignal(UA_RegisteredSignal *rs) {
126863 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX *)rs->rfd.es->eventLoop;
126864 UA_LOCK_ASSERT(&el->elMutex, 1);
126865
126866 if(rs->active)
126867 return;
126868
126869 /* Block the normal signal handling */
126870 sigset_t mask;
126871 sigemptyset(set: &mask);
126872 sigaddset(set: &mask, signo: rs->signal);
126873 int res2 = sigprocmask(SIG_BLOCK, set: &mask, NULL);
126874 if(res2 == -1) {
126875 UA_LOG_SOCKET_ERRNO_WRAP(
126876 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_EVENTLOOP,
126877 "Interrupt\t| Could not block the default "
126878 "signal handling with an error: %s",
126879 errno_str));
126880 return;
126881 }
126882
126883 /* Create the fd */
126884 UA_FD newfd = signalfd(fd: -1, mask: &mask, flags: 0);
126885 if(newfd < 0) {
126886 UA_LOG_SOCKET_ERRNO_WRAP(
126887 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_EVENTLOOP,
126888 "Interrupt\t|Could not create a signal file "
126889 "description with error: %s",
126890 errno_str));
126891 sigprocmask(SIG_UNBLOCK, set: &mask, NULL); /* restore signal */
126892 return;
126893 }
126894
126895 rs->rfd.fd = newfd;
126896 rs->rfd.eventSourceCB = handlePOSIXInterruptEvent;
126897 rs->rfd.listenEvents = UA_FDEVENT_IN;
126898
126899 /* Register the fd in the EventLoop */
126900 UA_StatusCode res = UA_EventLoopPOSIX_registerFD(el, rfd: &rs->rfd);
126901 if(res != UA_STATUSCODE_GOOD) {
126902 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
126903 msg: "Interrupt\t|Could not register the a signal file "
126904 "description in the EventLoop");
126905 UA_close(fd: newfd);
126906 sigprocmask(SIG_UNBLOCK, set: &mask, NULL); /* restore signal */
126907 return;
126908 }
126909
126910 rs->active = true;
126911}
126912
126913static void
126914deactivateSignal(UA_RegisteredSignal *rs) {
126915 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX *)rs->rfd.es->eventLoop;
126916 UA_LOCK_ASSERT(&el->elMutex, 1);
126917
126918 /* Only dectivate if active */
126919 if(!rs->active)
126920 return;
126921 rs->active = false;
126922
126923 /* Stop receiving the signal on the FD */
126924 UA_EventLoopPOSIX_deregisterFD(el, rfd: &rs->rfd);
126925
126926 /* Unblock the signal */
126927 sigset_t mask;
126928 sigemptyset(set: &mask);
126929 sigaddset(set: &mask, signo: (int)rs->signal);
126930 sigprocmask(SIG_UNBLOCK, set: &mask, NULL);
126931
126932 /* Clean up locally */
126933 UA_close(fd: rs->rfd.fd);
126934}
126935
126936#else /* !UA_HAVE_EPOLL */
126937
126938static void
126939triggerPOSIXInterruptEvent(int sig) {
126940 UA_assert(singletonIM != NULL);
126941
126942 /* Don't take a lock. All we are doing here can be done from within a
126943 * (reentrant) interrupt. */
126944
126945 /* Get the rs. Only use it if not already triggered. */
126946 UA_RegisteredSignal *rs;
126947 LIST_FOREACH(rs, &singletonIM->signals, listPointers) {
126948 if(rs->signal == sig)
126949 break;
126950 }
126951 if(!rs || rs->triggered || !rs->active)
126952 return;
126953
126954 /* Add to the triggered list */
126955 TAILQ_INSERT_TAIL(&singletonIM->triggered, rs, triggeredEntry);
126956 rs->triggered = true;
126957
126958#ifdef UA_ARCHITECTURE_WIN32
126959 /* On WIN32 we have to re-arm the signal or it will go back to SIG_DFL */
126960 signal(sig, triggerPOSIXInterruptEvent);
126961#endif
126962
126963 /* Trigger the FD in the EventLoop for the self-pipe trick */
126964#ifdef UA_ARCHITECTURE_WIN32
126965 int err = send(singletonIM->writeFD, ".", 1, 0);
126966#else
126967 ssize_t err = write(singletonIM->writeFD, ".", 1);
126968#endif
126969 if(err <= 0) {
126970 UA_LOG_SOCKET_ERRNO_WRAP(
126971 UA_LOG_WARNING(singletonIM->im.eventSource.eventLoop->logger,
126972 UA_LOGCATEGORY_EVENTLOOP,
126973 "Error signaling the interrupt on FD %u to the EventLoop (%s)",
126974 (unsigned)singletonIM->writeFD, errno_str));
126975 }
126976}
126977
126978static void
126979activateSignal(UA_RegisteredSignal *rs) {
126980 UA_assert(singletonIM != NULL);
126981 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)singletonIM->im.eventSource.eventLoop;
126982 UA_LOCK_ASSERT(&el->elMutex, 1);
126983
126984 /* Register the signal on the OS level */
126985 if(rs->active)
126986 return;
126987
126988 void (*prev)(int);
126989 prev = signal(rs->signal, triggerPOSIXInterruptEvent);
126990 if(prev == SIG_ERR) {
126991 UA_LOG_SOCKET_ERRNO_WRAP(
126992 UA_LOG_WARNING(singletonIM->im.eventSource.eventLoop->logger,
126993 UA_LOGCATEGORY_EVENTLOOP,
126994 "Error registering the signal: %s", errno_str));
126995 return;
126996 }
126997
126998 rs->active = true;
126999}
127000
127001static void
127002deactivateSignal(UA_RegisteredSignal *rs) {
127003 UA_assert(singletonIM != NULL);
127004 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)singletonIM->im.eventSource.eventLoop;
127005 UA_LOCK_ASSERT(&el->elMutex, 1);
127006
127007 /* Only dectivate if active */
127008 if(!rs->active)
127009 return;
127010
127011 /* Stop receiving the signal */
127012 signal(rs->signal, SIG_DFL);
127013
127014 /* Clean up locally */
127015 if(rs->triggered) {
127016 TAILQ_REMOVE(&singletonIM->triggered, rs, triggeredEntry);
127017 rs->triggered = false;
127018 }
127019
127020 rs->active = false;
127021}
127022
127023/* Execute all triggered interrupts via the self-pipe trick from within the EventLoop */
127024static void
127025executeTriggeredPOSIXInterrupts(UA_EventSource *es, UA_RegisteredFD *rfd, short event) {
127026 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)es->eventLoop;
127027 UA_LOCK_ASSERT(&el->elMutex, 1);
127028
127029 /* Re-arm the socket for the next signal by reading from it */
127030 char buf[128];
127031#ifdef UA_ARCHITECTURE_WIN32
127032 recv(rfd->fd, buf, 128, 0); /* ignore the result */
127033#else
127034 ssize_t i;
127035 do {
127036 i = read(rfd->fd, buf, 128);
127037 } while(i > 0);
127038#endif
127039
127040 UA_RegisteredSignal *rs, *rs_tmp;
127041 TAILQ_FOREACH_SAFE(rs, &singletonIM->triggered, triggeredEntry, rs_tmp) {
127042 TAILQ_REMOVE(&singletonIM->triggered, rs, triggeredEntry);
127043 rs->triggered = false;
127044 UA_UNLOCK(&el->elMutex);
127045 rs->signalCallback(&singletonIM->im, (uintptr_t)rs->signal,
127046 rs->context, &UA_KEYVALUEMAP_NULL);
127047 UA_LOCK(&el->elMutex);
127048 }
127049}
127050
127051#endif /* !UA_HAVE_EPOLL */
127052
127053static UA_StatusCode
127054registerPOSIXInterrupt(UA_InterruptManager *im, uintptr_t interruptHandle,
127055 const UA_KeyValueMap *params,
127056 UA_InterruptCallback callback, void *interruptContext) {
127057 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX *)im->eventSource.eventLoop;
127058 if(!UA_KeyValueMap_isEmpty(map: params)) {
127059 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
127060 msg: "Interrupt\t| Supplied parameters invalid for the "
127061 "POSIX InterruptManager");
127062 return UA_STATUSCODE_BADINTERNALERROR;
127063 }
127064
127065 UA_LOCK(&el->elMutex);
127066
127067 /* Was the signal already registered? */
127068 int signal = (int)interruptHandle;
127069 UA_POSIXInterruptManager *pim = (UA_POSIXInterruptManager *)im;
127070 UA_RegisteredSignal *rs;
127071 LIST_FOREACH(rs, &pim->signals, listPointers) {
127072 if(rs->signal == signal)
127073 break;
127074 }
127075 if(rs) {
127076 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
127077 msg: "Interrupt\t| Signal %u already registered",
127078 (unsigned)interruptHandle);
127079 UA_UNLOCK(&el->elMutex);
127080 return UA_STATUSCODE_BADINTERNALERROR;
127081 }
127082
127083 /* Create and populate the new context object */
127084 rs = (UA_RegisteredSignal *)UA_calloc(nmemb: 1, size: sizeof(UA_RegisteredSignal));
127085 if(!rs) {
127086 UA_UNLOCK(&el->elMutex);
127087 return UA_STATUSCODE_BADOUTOFMEMORY;
127088 }
127089
127090#ifdef UA_HAVE_EPOLL
127091 rs->rfd.es = &im->eventSource;
127092#endif
127093 rs->signal = (int)interruptHandle;
127094 rs->signalCallback = callback;
127095 rs->context = interruptContext;
127096
127097 /* Add to the InterruptManager */
127098 LIST_INSERT_HEAD(&pim->signals, rs, listPointers);
127099 pim->signalsSize++;
127100
127101 /* Activate if we are already running */
127102 if(pim->im.eventSource.state == UA_EVENTSOURCESTATE_STARTED)
127103 activateSignal(rs);
127104
127105 UA_UNLOCK(&el->elMutex);
127106 return UA_STATUSCODE_GOOD;
127107}
127108
127109static void
127110deregisterPOSIXInterrupt(UA_InterruptManager *im, uintptr_t interruptHandle) {
127111 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX *)im->eventSource.eventLoop;
127112 (void)el;
127113 UA_POSIXInterruptManager *pim = (UA_POSIXInterruptManager *)im;
127114 UA_LOCK(&el->elMutex);
127115
127116 int signal = (int)interruptHandle;
127117 UA_RegisteredSignal *rs;
127118 LIST_FOREACH(rs, &pim->signals, listPointers) {
127119 if(rs->signal == signal)
127120 break;
127121 }
127122 if(rs) {
127123 deactivateSignal(rs);
127124 LIST_REMOVE(rs, listPointers);
127125 UA_free(ptr: rs);
127126 }
127127
127128 UA_UNLOCK(&el->elMutex);
127129}
127130
127131#ifdef UA_ARCHITECTURE_WIN32
127132/* Windows has no pipes. Use a local TCP connection for the self-pipe trick.
127133 * https://stackoverflow.com/a/3333565 */
127134static int
127135pair(SOCKET fds[2]) {
127136 struct sockaddr_in inaddr;
127137 struct sockaddr addr;
127138 SOCKET lst = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
127139 memset(&inaddr, 0, sizeof(inaddr));
127140 memset(&addr, 0, sizeof(addr));
127141 inaddr.sin_family = AF_INET;
127142 inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
127143 inaddr.sin_port = 0;
127144 int yes = 1;
127145 setsockopt(lst, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
127146 bind(lst, (struct sockaddr *)&inaddr, sizeof(inaddr));
127147 listen(lst, 1);
127148 int len = sizeof(inaddr);
127149 getsockname(lst, &addr, &len);
127150 fds[0] = socket(AF_INET, SOCK_STREAM, 0);
127151 int err = connect(fds[0], &addr, len);
127152 fds[1] = accept(lst, 0, 0);
127153 closesocket(lst);
127154 return err;
127155}
127156#endif
127157
127158static UA_StatusCode
127159startPOSIXInterruptManager(UA_EventSource *es) {
127160 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX *)es->eventLoop;
127161 (void)el;
127162 UA_LOCK(&el->elMutex);
127163
127164 /* Check the state */
127165 if(es->state != UA_EVENTSOURCESTATE_STOPPED) {
127166 UA_LOG_ERROR(logger: es->eventLoop->logger, category: UA_LOGCATEGORY_EVENTLOOP,
127167 msg: "Interrupt\t| To start the InterruptManager, "
127168 "it has to be registered in an EventLoop and not started");
127169 UA_UNLOCK(&el->elMutex);
127170 return UA_STATUSCODE_BADINTERNALERROR;
127171 }
127172
127173 UA_POSIXInterruptManager *pim = (UA_POSIXInterruptManager *)es;
127174 UA_LOG_DEBUG(logger: es->eventLoop->logger, category: UA_LOGCATEGORY_EVENTLOOP,
127175 msg: "Interrupt\t| Starting the InterruptManager");
127176
127177#ifndef UA_HAVE_EPOLL
127178 /* Create pipe for self-signaling */
127179 UA_FD pipefd[2];
127180#ifdef UA_ARCHITECTURE_WIN32
127181 int err = pair(pipefd);
127182#else
127183 int err = pipe(pipefd);
127184#endif
127185 if(err != 0) {
127186 UA_LOG_SOCKET_ERRNO_WRAP(
127187 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
127188 "Interrupt\t| Could not open the pipe for "
127189 "self-signaling (%s)", errno_str));
127190 UA_UNLOCK(&el->elMutex);
127191 return UA_STATUSCODE_BADINTERNALERROR;
127192 }
127193
127194 UA_StatusCode res = UA_STATUSCODE_GOOD;
127195#ifndef UA_ARCHITECTURE_WIN32
127196 /* Mark pipes as non-blocking */
127197 for(size_t i = 0; i < (sizeof(pipefd) / sizeof(*pipefd)); ++i) {
127198 res = UA_EventLoopPOSIX_setNonBlocking(pipefd[i]);
127199 if(res != UA_STATUSCODE_GOOD) {
127200 UA_LOG_SOCKET_ERRNO_WRAP(
127201 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
127202 "Interrupt\t| Could mark pipe for "
127203 "self-signaling as non-blocking(%s)",
127204 errno_str));
127205 UA_UNLOCK(&el->elMutex);
127206 return UA_STATUSCODE_BADINTERNALERROR;
127207 }
127208 }
127209#endif
127210
127211 UA_LOG_DEBUG(es->eventLoop->logger, UA_LOGCATEGORY_EVENTLOOP,
127212 "Interrupt\t| Socket pair for the self-pipe: %u,%u",
127213 (unsigned)pipefd[0], (unsigned)pipefd[1]);
127214
127215 pim->writeFD = pipefd[1];
127216 pim->readFD.fd = pipefd[0];
127217 pim->readFD.es = &pim->im.eventSource;
127218 pim->readFD.listenEvents = UA_FDEVENT_IN;
127219 pim->readFD.eventSourceCB = executeTriggeredPOSIXInterrupts;
127220 res = UA_EventLoopPOSIX_registerFD(el, &pim->readFD);
127221 if(res != UA_STATUSCODE_GOOD) {
127222 UA_LOG_ERROR(es->eventLoop->logger, UA_LOGCATEGORY_EVENTLOOP,
127223 "Interrupt\t| Could not register the InterruptManager socket");
127224 UA_close(pipefd[0]);
127225 UA_close(pipefd[1]);
127226 UA_UNLOCK(&el->elMutex);
127227 return UA_STATUSCODE_BADINTERNALERROR;
127228 }
127229#endif
127230
127231 /* Activate the registered signal handlers */
127232 UA_RegisteredSignal*rs;
127233 LIST_FOREACH(rs, &pim->signals, listPointers) {
127234 activateSignal(rs);
127235 }
127236
127237 /* Set the EventSource to the started state */
127238 es->state = UA_EVENTSOURCESTATE_STARTED;
127239
127240 UA_UNLOCK(&el->elMutex);
127241 return UA_STATUSCODE_GOOD;
127242}
127243
127244static void
127245stopPOSIXInterruptManager(UA_EventSource *es) {
127246 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX *)es->eventLoop;
127247 (void)el;
127248 UA_LOCK(&el->elMutex);
127249
127250 if(es->state != UA_EVENTSOURCESTATE_STARTED) {
127251 UA_UNLOCK(&el->elMutex);
127252 return;
127253 }
127254
127255 UA_LOG_DEBUG(logger: es->eventLoop->logger, category: UA_LOGCATEGORY_EVENTLOOP,
127256 msg: "Interrupt\t| Stopping the InterruptManager");
127257
127258 /* Close all registered signals */
127259 UA_POSIXInterruptManager *pim = (UA_POSIXInterruptManager *)es;
127260 UA_RegisteredSignal*rs;
127261 LIST_FOREACH(rs, &pim->signals, listPointers) {
127262 deactivateSignal(rs);
127263 }
127264
127265#ifndef UA_HAVE_EPOLL
127266 /* Close the FD for the self-pipe trick */
127267 UA_EventLoopPOSIX_deregisterFD(el, &pim->readFD);
127268 UA_close(pim->readFD.fd);
127269 UA_close(pim->writeFD);
127270#endif
127271
127272 /* Immediately set to stopped */
127273 es->state = UA_EVENTSOURCESTATE_STOPPED;
127274
127275 UA_UNLOCK(&el->elMutex);
127276}
127277
127278static UA_StatusCode
127279freePOSIXInterruptmanager(UA_EventSource *es) {
127280 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX *)es->eventLoop;
127281 (void)el;
127282 UA_LOCK_ASSERT(&el->elMutex, 1);
127283
127284 if(es->state >= UA_EVENTSOURCESTATE_STARTING) {
127285 UA_LOG_ERROR(logger: es->eventLoop->logger, category: UA_LOGCATEGORY_EVENTLOOP,
127286 msg: "Interrupt\t| The EventSource must be stopped "
127287 "before it can be deleted");
127288 return UA_STATUSCODE_BADINTERNALERROR;
127289 }
127290
127291 /* Deactivate and remove all registered signals */
127292 UA_POSIXInterruptManager *pim = (UA_POSIXInterruptManager *)es;
127293 UA_RegisteredSignal *rs, *rs_tmp;
127294 LIST_FOREACH_SAFE(rs, &pim->signals, listPointers, rs_tmp) {
127295 deactivateSignal(rs);
127296 LIST_REMOVE(rs, listPointers);
127297 UA_free(ptr: rs);
127298 }
127299
127300 UA_String_clear(p: &es->name);
127301 UA_free(ptr: es);
127302
127303#ifndef UA_HAVE_EPOLL
127304 singletonIM = NULL; /* Reset the global singleton pointer */
127305#endif
127306
127307 return UA_STATUSCODE_GOOD;
127308}
127309
127310UA_InterruptManager *
127311UA_InterruptManager_new_POSIX(const UA_String eventSourceName) {
127312#ifndef UA_HAVE_EPOLL
127313 /* There can be only one InterruptManager if epoll is not present */
127314 if(singletonIM)
127315 return NULL;
127316#endif
127317
127318 UA_POSIXInterruptManager *pim = (UA_POSIXInterruptManager *)
127319 UA_calloc(nmemb: 1, size: sizeof(UA_POSIXInterruptManager));
127320 if(!pim)
127321 return NULL;
127322
127323 LIST_INIT(&pim->signals);
127324
127325#ifndef UA_HAVE_EPOLL
127326 TAILQ_INIT(&pim->triggered);
127327 singletonIM = pim; /* Register the singleton singleton pointer */
127328#endif
127329
127330 UA_InterruptManager *im = &pim->im;
127331 im->eventSource.eventSourceType = UA_EVENTSOURCETYPE_INTERRUPTMANAGER;
127332 UA_String_copy(src: &eventSourceName, dst: &im->eventSource.name);
127333 im->eventSource.start = startPOSIXInterruptManager;
127334 im->eventSource.stop = stopPOSIXInterruptManager;
127335 im->eventSource.free = freePOSIXInterruptmanager;
127336 im->registerInterrupt = registerPOSIXInterrupt;
127337 im->deregisterInterrupt = deregisterPOSIXInterrupt;
127338 return im;
127339}
127340
127341/**** amalgamated original file "/arch/eventloop_posix_eth.c" ****/
127342
127343/* This Source Code Form is subject to the terms of the Mozilla Public
127344 * License, v. 2.0. If a copy of the MPL was not distributed with this
127345 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
127346 *
127347 * Copyright 2018 (c) Kontron Europe GmbH (Author: Rudolf Hoyler)
127348 * Copyright 2019-2020 (c) Kalycito Infotech Private Limited
127349 * Copyright 2019-2020 (c) Wind River Systems, Inc.
127350 * Copyright 2022 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
127351 */
127352
127353
127354#if defined(UA_ARCHITECTURE_POSIX) && defined(__linux__)
127355
127356#include <arpa/inet.h> /* htons */
127357#include <net/ethernet.h> /* ETH_P_*/
127358#include <linux/if_packet.h>
127359
127360/* Configuration parameters */
127361#define ETH_PARAMETERSSIZE 9
127362#define ETH_PARAMINDEX_ADDR 0
127363#define ETH_PARAMINDEX_LISTEN 1
127364#define ETH_PARAMINDEX_IFACE 2
127365#define ETH_PARAMINDEX_ETHERTYPE 3
127366#define ETH_PARAMINDEX_VID 4
127367#define ETH_PARAMINDEX_PCP 5
127368#define ETH_PARAMINDEX_DEI 6
127369#define ETH_PARAMINDEX_PROMISCUOUS 7
127370#define ETH_PARAMINDEX_VALIDATE 8
127371
127372static UA_KeyValueRestriction ETHConfigParameters[ETH_PARAMETERSSIZE+1] = {
127373 {{0, UA_STRING_STATIC("address")}, &UA_TYPES[UA_TYPES_STRING], false, true, false},
127374 {{0, UA_STRING_STATIC("listen")}, &UA_TYPES[UA_TYPES_BOOLEAN], false, true, false},
127375 {{0, UA_STRING_STATIC("interface")}, &UA_TYPES[UA_TYPES_STRING], true, true, false},
127376 {{0, UA_STRING_STATIC("ethertype")}, &UA_TYPES[UA_TYPES_UINT16], false, true, false},
127377 {{0, UA_STRING_STATIC("vid")}, &UA_TYPES[UA_TYPES_UINT16], false, true, false},
127378 {{0, UA_STRING_STATIC("pcp")}, &UA_TYPES[UA_TYPES_BYTE], false, true, false},
127379 {{0, UA_STRING_STATIC("dei")}, &UA_TYPES[UA_TYPES_BOOLEAN], false, true, false},
127380 {{0, UA_STRING_STATIC("promiscuous")}, &UA_TYPES[UA_TYPES_BOOLEAN], false, true, false},
127381 {{0, UA_STRING_STATIC("validate")}, &UA_TYPES[UA_TYPES_BOOLEAN], false, true, false},
127382 /* Duplicated address parameter with a scalar value required. For the send-socket case. */
127383 {{0, UA_STRING_STATIC("address")}, &UA_TYPES[UA_TYPES_STRING], true, true, false},
127384};
127385
127386#define UA_ETH_MAXHEADERLENGTH (2*ETHER_ADDR_LEN)+4+2+2
127387
127388typedef struct {
127389 UA_RegisteredFD rfd;
127390
127391 UA_ConnectionManager_connectionCallback applicationCB;
127392 void *application;
127393 void *context;
127394
127395 struct sockaddr_ll sll;
127396 /* The Ethernet header to prepend for sending frames is precomputed and reused.
127397 * The length field (the last 2 byte) is adjusted.
127398 * - 2 * ETHER_ADDR_LEN: destination and source
127399 * - 4 byte: VLAN tagging (optional)
127400 * - 2 byte: EtherType (optional)
127401 * - 2 byte: length */
127402 unsigned char header[UA_ETH_MAXHEADERLENGTH];
127403 unsigned char headerSize;
127404 unsigned char lengthOffset; /* No length field if zero */
127405} ETH_FD;
127406
127407/* The format of a Ethernet address is six groups of hexadecimal digits,
127408 * separated by hyphens (e.g. 01-23-45-67-89-ab). */
127409static UA_StatusCode
127410parseEthAddress(const UA_String *buf, UA_Byte *addr) {
127411 size_t curr = 0, idx = 0;
127412 for(; idx < ETHER_ADDR_LEN; idx++) {
127413 UA_UInt32 value;
127414 size_t progress = UA_readNumberWithBase(buf: &buf->data[curr],
127415 buflen: buf->length - curr, number: &value, base: 16);
127416 if(progress == 0 || value > (long)0xff)
127417 return UA_STATUSCODE_BADINTERNALERROR;
127418
127419 addr[idx] = (UA_Byte) value;
127420
127421 curr += progress;
127422 if(curr == buf->length)
127423 break;
127424
127425 if(buf->data[curr] != '-')
127426 return UA_STATUSCODE_BADINTERNALERROR;
127427
127428 curr++; /* skip '-' */
127429 }
127430
127431 if(idx != (ETH_ALEN-1))
127432 return UA_STATUSCODE_BADINTERNALERROR;
127433
127434 return UA_STATUSCODE_GOOD;
127435}
127436
127437static UA_Boolean
127438isMulticastEthAddress(const UA_Byte *address) {
127439 if((address[0] & 1) == 0)
127440 return false; /* Unicast address */
127441 for(size_t i = 0; i < ETHER_ADDR_LEN; i++) {
127442 if(address[i] != 0xff)
127443 return true; /* Not broadcast address ff-ff-ff-ff-ff-ff */
127444 }
127445 return false;
127446}
127447
127448static void
127449setAddrString(unsigned char addrStr[18], unsigned char addr[ETHER_ADDR_LEN]) {
127450 mp_snprintf(s: (char*)addrStr, n: 18, format: "%02x-%02x-%02x-%02x-%02x-%02x",
127451 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
127452}
127453
127454/* Return zero if parsing failed */
127455static size_t
127456parseETHHeader(const UA_ByteString *buf,
127457 unsigned char destAddr[ETHER_ADDR_LEN],
127458 unsigned char sourceAddr[ETHER_ADDR_LEN],
127459 UA_UInt16 *etherType, UA_UInt16 *vid,
127460 UA_Byte *pcp, UA_Boolean *dei) {
127461 if(buf->length < (2 * ETHER_ADDR_LEN)+2)
127462 return 0;
127463
127464 /* Parse "normal" Ethernet header */
127465 memcpy(dest: destAddr, src: buf->data, ETHER_ADDR_LEN);
127466 memcpy(dest: sourceAddr, src: &buf->data[ETHER_ADDR_LEN], ETHER_ADDR_LEN);
127467 size_t pos = 2 * ETHER_ADDR_LEN;
127468 UA_UInt16 length = ntohs(netshort: *(UA_UInt16*)&buf->data[pos]);
127469 pos += 2;
127470
127471 /* No EtherType and no VLAN */
127472 if(length <= 1500)
127473 return pos;
127474
127475 /* Parse 802.1Q VLAN header */
127476 if(length == 0x8100) {
127477 if(buf->length < (2 * ETHER_ADDR_LEN)+2+4)
127478 return 0;
127479 pos += 2;
127480 UA_UInt16 vlan = ntohs(netshort: *(UA_UInt16*)&buf->data[pos]);
127481 *pcp = 0x07 & vlan;
127482 *dei = 0x01 & (vlan >> 3);
127483 *vid = vlan >> 4;
127484 pos += 2;
127485 length = ntohs(netshort: *(UA_UInt16*)&buf->data[pos]);
127486 }
127487
127488 /* Set the EtherType if it is set */
127489 if(length > 1500)
127490 *etherType = length;
127491
127492 return pos;
127493}
127494
127495static unsigned char
127496setETHHeader(unsigned char *buf,
127497 unsigned char destAddr[ETHER_ADDR_LEN],
127498 unsigned char sourceAddr[ETHER_ADDR_LEN],
127499 UA_UInt16 etherType, UA_UInt16 vid,
127500 UA_Byte pcp, UA_Boolean dei, unsigned char *lengthOffset) {
127501 /* Set dest and source address */
127502 size_t pos = 0;
127503 memcpy(dest: buf, src: destAddr, ETHER_ADDR_LEN);
127504 pos += ETHER_ADDR_LEN;
127505 memcpy(dest: &buf[pos], src: sourceAddr, ETHER_ADDR_LEN);
127506 pos += ETHER_ADDR_LEN;
127507
127508 /* Set the 802.1Q VLAN header */
127509 if(vid > 0 && vid != ETH_P_ALL) {
127510 *(UA_UInt16*)&buf[pos] = htons(hostshort: 0x8100);
127511 pos += 2;
127512 UA_UInt16 vlan = (UA_UInt16)((UA_UInt16)pcp + (((UA_UInt16)dei) << 3) + (vid << 4));
127513 *(UA_UInt16*)&buf[pos] = htons(hostshort: vlan);
127514 pos += 2;
127515 }
127516
127517 /* Set the Ethertype or store the offset for the length field */
127518 if(etherType == 0 || etherType == ETH_P_ALL) {
127519 *lengthOffset = (unsigned char)pos;
127520 } else {
127521 *(UA_UInt16*)&buf[pos] = htons(hostshort: etherType);
127522 }
127523 pos += 2;
127524 return (unsigned char)pos;
127525}
127526
127527static UA_StatusCode
127528ETH_allocNetworkBuffer(UA_ConnectionManager *cm, uintptr_t connectionId,
127529 UA_ByteString *buf, size_t bufSize) {
127530 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
127531
127532 /* Get the ETH_FD */
127533 UA_FD fd = (UA_FD)connectionId;
127534 ETH_FD *erfd = (ETH_FD*)ZIP_FIND(UA_FDTree, &pcm->fds, &fd);
127535 if(!erfd)
127536 return UA_STATUSCODE_BADCONNECTIONREJECTED;
127537
127538 /* Allocate the buffer with the hidden Ethernet header in front */
127539 UA_StatusCode res = UA_ByteString_allocBuffer(bs: buf, length: bufSize+erfd->headerSize);
127540 buf->data += erfd->headerSize;
127541 buf->length -= erfd->headerSize;
127542 return res;
127543}
127544
127545static void
127546ETH_freeNetworkBuffer(UA_ConnectionManager *cm, uintptr_t connectionId,
127547 UA_ByteString *buf) {
127548 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
127549
127550 /* Get the ETH_FD */
127551 UA_FD fd = (UA_FD)connectionId;
127552 ETH_FD *erfd = (ETH_FD*)ZIP_FIND(UA_FDTree, &pcm->fds, &fd);
127553 if(!erfd)
127554 return;
127555
127556 /* Unhide the Ethernet header */
127557 buf->data -= erfd->headerSize;
127558 buf->length += erfd->headerSize;
127559 UA_ByteString_clear(p: buf);
127560}
127561
127562/* Test if the ConnectionManager can be stopped */
127563static void
127564ETH_checkStopped(UA_POSIXConnectionManager *pcm) {
127565 UA_LOCK_ASSERT(&((UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop)->elMutex, 1);
127566
127567 if(pcm->fdsSize == 0 &&
127568 pcm->cm.eventSource.state == UA_EVENTSOURCESTATE_STOPPING) {
127569 UA_LOG_DEBUG(logger: pcm->cm.eventSource.eventLoop->logger, category: UA_LOGCATEGORY_NETWORK,
127570 msg: "ETH\t| All sockets closed, the EventLoop has stopped");
127571 pcm->cm.eventSource.state = UA_EVENTSOURCESTATE_STOPPED;
127572 }
127573}
127574
127575/* This method must not be called from the application directly, but from within
127576 * the EventLoop. Otherwise we cannot be sure whether the file descriptor is
127577 * still used after calling close. */
127578static void
127579ETH_close(UA_POSIXConnectionManager *pcm, ETH_FD *conn) {
127580 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop;
127581 UA_LOCK_ASSERT(&el->elMutex, 1);
127582
127583 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
127584 msg: "ETH %u\t| Closing connection",
127585 (unsigned)conn->rfd.fd);
127586
127587 /* Deregister from the EventLoop */
127588 UA_EventLoopPOSIX_deregisterFD(el, rfd: &conn->rfd);
127589
127590 /* Deregister internally */
127591 ZIP_REMOVE(UA_FDTree, &pcm->fds, &conn->rfd);
127592 UA_assert(pcm->fdsSize > 0);
127593 pcm->fdsSize--;
127594
127595 /* Signal closing to the application */
127596 conn->applicationCB(&pcm->cm, (uintptr_t)conn->rfd.fd,
127597 conn->application, &conn->context,
127598 UA_CONNECTIONSTATE_CLOSING,
127599 &UA_KEYVALUEMAP_NULL, UA_BYTESTRING_NULL);
127600
127601 /* Close the socket */
127602 int ret = UA_close(fd: conn->rfd.fd);
127603 if(ret == 0) {
127604 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
127605 msg: "ETH %u\t| Socket closed", (unsigned)conn->rfd.fd);
127606 } else {
127607 UA_LOG_SOCKET_ERRNO_WRAP(
127608 UA_LOG_WARNING(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
127609 "ETH %u\t| Could not close the socket (%s)",
127610 (unsigned)conn->rfd.fd, errno_str));
127611 }
127612
127613 /* Don't call free here. This might be done automatically via the delayed
127614 * callback that calls ETH_close. */
127615 /* UA_free(rfd); */
127616
127617 /* Stop if the ucm is stopping and this was the last open socket */
127618 ETH_checkStopped(pcm);
127619}
127620
127621static void
127622ETH_delayedClose(void *application, void *context) {
127623 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)application;
127624 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop;
127625 ETH_FD *conn = (ETH_FD*)context;
127626 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_EVENTLOOP,
127627 msg: "ETH %u\t| Delayed closing of the connection",
127628 (unsigned)conn->rfd.fd);
127629 UA_LOCK(&el->elMutex);
127630 ETH_close(pcm, conn);
127631 UA_UNLOCK(&el->elMutex);
127632 UA_free(ptr: conn);
127633}
127634
127635/* Gets called when a socket receives data or closes */
127636static void
127637ETH_connectionSocketCallback(UA_ConnectionManager *cm, UA_RegisteredFD *rfd,
127638 short event) {
127639 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
127640 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
127641 UA_LOCK_ASSERT(&el->elMutex, 1);
127642
127643 ETH_FD *conn = (ETH_FD*)rfd;
127644 if(event == UA_FDEVENT_ERR) {
127645 UA_LOG_SOCKET_ERRNO_WRAP(
127646 UA_LOG_DEBUG(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
127647 "ETH %u\t| recv signaled the socket was shutdown (%s)",
127648 (unsigned)rfd->fd, errno_str));
127649 ETH_close(pcm, conn);
127650 UA_free(ptr: rfd);
127651 return;
127652 }
127653
127654 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
127655 msg: "ETH %u\t| Allocate receive buffer", (unsigned)rfd->fd);
127656
127657 /* Get the number of available bytes */
127658 int bytes_available = 0;
127659 ioctl(fd: rfd->fd, FIONREAD, &bytes_available);
127660 if(bytes_available <= 0)
127661 return;
127662
127663 UA_ByteString response;
127664 UA_StatusCode res = UA_ByteString_allocBuffer(bs: &response, length: (size_t)bytes_available);
127665 if(res != UA_STATUSCODE_GOOD)
127666 return;
127667
127668 /* Receive */
127669#ifndef UA_ARCHITECTURE_WIN32
127670 ssize_t ret = UA_recv(fd: rfd->fd, buf: (char*)response.data,
127671 n: response.length, MSG_DONTWAIT);
127672#else
127673 int ret = UA_recv(rfd->fd, (char*)response.data,
127674 response.length, MSG_DONTWAIT);
127675#endif
127676
127677 /* Receive has failed */
127678 if(ret <= 0) {
127679 if(UA_ERRNO == UA_INTERRUPTED) {
127680 UA_ByteString_clear(p: &response);
127681 return;
127682 }
127683
127684 /* Orderly shutdown of the socket. We can immediately close as no method
127685 * "below" in the call stack will use the socket in this iteration of
127686 * the EventLoop. */
127687 UA_LOG_SOCKET_ERRNO_WRAP(
127688 UA_LOG_DEBUG(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
127689 "ETH %u\t| recv signaled the socket was shutdown (%s)",
127690 (unsigned)rfd->fd, errno_str));
127691 ETH_close(pcm, conn);
127692 UA_free(ptr: rfd);
127693 UA_ByteString_clear(p: &response);
127694 return;
127695 }
127696
127697 /* Set the length of the received buffer */
127698 response.length = (size_t)ret;
127699
127700 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
127701 msg: "ETH %u\t| Received message of size %u",
127702 (unsigned)rfd->fd, (unsigned)ret);
127703
127704 /* Parse the Ethernet header */
127705 unsigned char destAddr[ETHER_ADDR_LEN];
127706 unsigned char sourceAddr[ETHER_ADDR_LEN];
127707 UA_UInt16 etherType = 0;
127708 UA_UInt16 vid = 0;
127709 UA_Byte pcp = 0;
127710 UA_Boolean dei = 0;
127711 size_t headerSize = parseETHHeader(buf: &response, destAddr, sourceAddr,
127712 etherType: &etherType, vid: &vid, pcp: &pcp, dei: &dei);
127713 if(headerSize == 0) {
127714 UA_ByteString_clear(p: &response);
127715 return;
127716 }
127717
127718 /* Set up the parameter arguments */
127719 unsigned char destAddrBytes[18];
127720 unsigned char sourceAddrBytes[18];
127721 setAddrString(addrStr: destAddrBytes, addr: destAddr);
127722 setAddrString(addrStr: sourceAddrBytes, addr: sourceAddr);
127723 UA_String destAddrStr = {17, destAddrBytes};
127724 UA_String sourceAddrStr = {17, sourceAddrBytes};
127725
127726 size_t paramsSize = 2;
127727 UA_KeyValuePair params[6];
127728 params[0].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "destination-address");
127729 UA_Variant_setScalar(v: &params[0].value, p: &destAddrStr, type: &UA_TYPES[UA_TYPES_STRING]);
127730 params[1].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "source-address");
127731 UA_Variant_setScalar(v: &params[1].value, p: &sourceAddrStr, type: &UA_TYPES[UA_TYPES_STRING]);
127732 if(etherType > 0) {
127733 params[2].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "ethertype");
127734 UA_Variant_setScalar(v: &params[1].value, p: &etherType, type: &UA_TYPES[UA_TYPES_UINT16]);
127735 paramsSize++;
127736 }
127737 if(vid > 0) {
127738 params[paramsSize].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "vid");
127739 UA_Variant_setScalar(v: &params[paramsSize].value, p: &vid, type: &UA_TYPES[UA_TYPES_UINT16]);
127740 params[paramsSize+1].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "pcp");
127741 UA_Variant_setScalar(v: &params[paramsSize+1].value, p: &pcp, type: &UA_TYPES[UA_TYPES_BYTE]);
127742 params[paramsSize+2].key = UA_QUALIFIEDNAME(nsIndex: 0, chars: "dei");
127743 UA_Variant_setScalar(v: &params[paramsSize+2].value, p: &dei, type: &UA_TYPES[UA_TYPES_BOOLEAN]);
127744 paramsSize += 3;
127745 }
127746
127747 UA_KeyValueMap map = {paramsSize, params};
127748
127749 /* Callback to the application layer with the Ethernet header hidden */
127750 response.data += headerSize;
127751 response.length -= headerSize;
127752 conn->applicationCB(cm, (uintptr_t)rfd->fd, conn->application, &conn->context,
127753 UA_CONNECTIONSTATE_ESTABLISHED, &map, response);
127754 response.data -= headerSize;
127755 response.length += headerSize;
127756 UA_ByteString_clear(p: &response);
127757}
127758
127759static UA_StatusCode
127760ETH_openListenConnection(UA_EventLoopPOSIX *el, ETH_FD *conn,
127761 const UA_KeyValueMap *params,
127762 int ifindex, UA_UInt16 etherType,
127763 UA_Boolean validate) {
127764 UA_LOCK_ASSERT(&el->elMutex, 1);
127765
127766 /* Bind the socket to interface and EtherType. Don't receive anything else. */
127767 struct sockaddr_ll sll;
127768 memset(s: &sll, c: 0, n: sizeof(struct sockaddr_ll));
127769 sll.sll_family = AF_PACKET;
127770 sll.sll_protocol = htons(hostshort: etherType);
127771 sll.sll_ifindex = ifindex;
127772 if(!validate && bind(fd: conn->rfd.fd, addr: (struct sockaddr*)&sll, len: sizeof(sll)) < 0)
127773 return UA_STATUSCODE_BADINTERNALERROR;
127774
127775 /* Immediately register for listen events. Don't have to wait for a
127776 * connection to open. */
127777 conn->rfd.listenEvents = UA_FDEVENT_IN;
127778
127779 /* Set receiving to promiscuous (all target host addresses) */
127780 const UA_Boolean *promiscuous = (const UA_Boolean*)
127781 UA_KeyValueMap_getScalar(map: params, key: ETHConfigParameters[ETH_PARAMINDEX_PROMISCUOUS].name,
127782 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
127783 if(promiscuous && *promiscuous) {
127784 struct packet_mreq mreq;
127785 memset(s: &mreq, c: 0, n: sizeof(struct packet_mreq));
127786 mreq.mr_ifindex = ifindex;
127787 mreq.mr_type = PACKET_MR_PROMISC;
127788 int ret = setsockopt(fd: conn->rfd.fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
127789 optval: &mreq, optlen: sizeof(mreq));
127790 if(ret < 0) {
127791 UA_LOG_SOCKET_ERRNO_WRAP(
127792 UA_LOG_ERROR(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
127793 "ETH %u\t| Could not set raw socket to promiscuous mode %s",
127794 (unsigned)conn->rfd.fd, errno_str));
127795 return UA_STATUSCODE_BADINTERNALERROR;
127796 } else {
127797 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
127798 msg: "ETH %u\t| The socket was set to promiscuous mode",
127799 (unsigned)conn->rfd.fd);
127800 }
127801 }
127802
127803 /* Register for multicast if an address is defined */
127804 const UA_String *address = (const UA_String*)
127805 UA_KeyValueMap_getScalar(map: params, key: ETHConfigParameters[ETH_PARAMINDEX_ADDR].name,
127806 type: &UA_TYPES[UA_TYPES_STRING]);
127807 if(address) {
127808 UA_Byte addr[ETHER_ADDR_LEN];
127809 UA_StatusCode res = parseEthAddress(buf: address, addr);
127810 if(res != UA_STATUSCODE_GOOD) {
127811 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
127812 msg: "ETH\t| Address for listening cannot be parsed");
127813 return res;
127814 }
127815
127816 if(!isMulticastEthAddress(address: addr)) {
127817 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
127818 msg: "ETH\t| Address for listening is not a multicast address. Ignoring.");
127819 return UA_STATUSCODE_GOOD;
127820 }
127821
127822 struct packet_mreq mreq;
127823 memset(s: &mreq, c: 0, n: sizeof(struct packet_mreq));
127824 mreq.mr_ifindex = ifindex;
127825 mreq.mr_type = PACKET_MR_MULTICAST;
127826 mreq.mr_alen = ETH_ALEN;
127827 memcpy(dest: mreq.mr_address, src: addr, ETHER_ADDR_LEN);
127828 if(!validate && UA_setsockopt(fd: conn->rfd.fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
127829 optval: (char *)&mreq, optlen: sizeof(mreq)) < 0) {
127830 UA_LOG_SOCKET_ERRNO_WRAP(
127831 UA_LOG_ERROR(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
127832 "ETH\t| Registering for multicast failed with error %s",
127833 errno_str));
127834 return UA_STATUSCODE_BADINTERNALERROR;
127835 }
127836 }
127837
127838 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
127839 msg: "ETH %u\t| Opened an Ethernet listen socket",
127840 (unsigned)conn->rfd.fd);
127841
127842 return UA_STATUSCODE_GOOD;
127843}
127844
127845static UA_StatusCode
127846ETH_openSendConnection(UA_EventLoopPOSIX *el, ETH_FD *conn, const UA_KeyValueMap *params,
127847 UA_Byte source[ETHER_ADDR_LEN], int ifindex, UA_UInt16 etherType) {
127848 UA_LOCK_ASSERT(&el->elMutex, 1);
127849
127850 /* Parse the target address (has to exist) */
127851 const UA_String *address = (const UA_String*)
127852 UA_KeyValueMap_getScalar(map: params, key: ETHConfigParameters[ETH_PARAMINDEX_ADDR].name,
127853 type: &UA_TYPES[UA_TYPES_STRING]);
127854 UA_Byte dest[ETHER_ADDR_LEN];
127855 UA_StatusCode res = parseEthAddress(buf: address, addr: dest);
127856 if(res != UA_STATUSCODE_GOOD) {
127857 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
127858 msg: "ETH\t| Could not parse the Ethernet address \"%.*s\"",
127859 (int)address->length, (char*)address->data);
127860 return res;
127861 }
127862
127863 /* Get the VLAN config */
127864 UA_UInt16 vid = 0;
127865 UA_Byte pcp = 0;
127866 UA_Boolean eid = false;
127867
127868 const UA_UInt16 *vidp = (const UA_UInt16*)
127869 UA_KeyValueMap_getScalar(map: params, key: ETHConfigParameters[ETH_PARAMINDEX_VID].name,
127870 type: &UA_TYPES[UA_TYPES_UINT16]);
127871 if(vidp)
127872 vid = *vidp;
127873
127874 const UA_Byte *pcpp = (const UA_Byte*)
127875 UA_KeyValueMap_getScalar(map: params, key: ETHConfigParameters[ETH_PARAMINDEX_PCP].name,
127876 type: &UA_TYPES[UA_TYPES_BYTE]);
127877 if(pcpp)
127878 pcp = *pcpp;
127879
127880 const UA_Boolean *eidp = (const UA_Boolean*)
127881 UA_KeyValueMap_getScalar(map: params, key: ETHConfigParameters[ETH_PARAMINDEX_DEI].name,
127882 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
127883 if(eidp)
127884 eid = *eidp;
127885
127886 /* Store the structure for sendto */
127887 conn->sll.sll_ifindex = ifindex;
127888 conn->sll.sll_halen = ETH_ALEN;
127889 memcpy(dest: conn->sll.sll_addr, src: dest, ETHER_ADDR_LEN);
127890
127891 /* Generate the Ethernet header */
127892 conn->headerSize = setETHHeader(buf: conn->header, destAddr: dest, sourceAddr: source, etherType,
127893 vid, pcp, dei: eid, lengthOffset: &conn->lengthOffset);
127894
127895
127896 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
127897 msg: "ETH %u\t| Opened an Ethernet send socket",
127898 (unsigned)conn->rfd.fd);
127899
127900 return UA_STATUSCODE_GOOD;
127901}
127902
127903static UA_StatusCode
127904ETH_openConnection(UA_ConnectionManager *cm, const UA_KeyValueMap *params,
127905 void *application, void *context,
127906 UA_ConnectionManager_connectionCallback connectionCallback) {
127907 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
127908 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX *)cm->eventSource.eventLoop;
127909
127910 UA_LOCK(&el->elMutex);
127911
127912 /* Listen or send connection? */
127913 const UA_Boolean *listen = (const UA_Boolean*)
127914 UA_KeyValueMap_getScalar(map: params, key: ETHConfigParameters[ETH_PARAMINDEX_LISTEN].name,
127915 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
127916 size_t ethParams = ETH_PARAMETERSSIZE;
127917 if(!listen || !*listen)
127918 ethParams++; /* Require the address parameter to exist */
127919
127920 /* Validate the parameters */
127921 UA_StatusCode res =
127922 UA_KeyValueRestriction_validate(logger: el->eventLoop.logger, logprefix: "ETH", restrictions: ETHConfigParameters,
127923 restrictionsSize: ethParams, map: params);
127924 if(res != UA_STATUSCODE_GOOD) {
127925 UA_UNLOCK(&el->elMutex);
127926 return res;
127927 }
127928
127929 /* Only validate the parameters? */
127930 UA_Boolean validate = false;
127931 const UA_Boolean *validateParam = (const UA_Boolean*)
127932 UA_KeyValueMap_getScalar(map: params,
127933 key: ETHConfigParameters[ETH_PARAMINDEX_VALIDATE].name,
127934 type: &UA_TYPES[UA_TYPES_BOOLEAN]);
127935 if(validateParam)
127936 validate = *validateParam;
127937
127938 /* Get the EtherType parameter */
127939 UA_UInt16 etherType = ETH_P_ALL;
127940 const UA_UInt16 *etParam = (const UA_UInt16*)
127941 UA_KeyValueMap_getScalar(map: params, key: ETHConfigParameters[ETH_PARAMINDEX_ETHERTYPE].name,
127942 type: &UA_TYPES[UA_TYPES_UINT16]);
127943 if(etParam)
127944 etherType = *etParam;
127945
127946 /* Get the interface index */
127947 const UA_String *interface = (const UA_String*)
127948 UA_KeyValueMap_getScalar(map: params, key: ETHConfigParameters[ETH_PARAMINDEX_IFACE].name,
127949 type: &UA_TYPES[UA_TYPES_STRING]);
127950 if(interface->length >= 128) {
127951 UA_UNLOCK(&el->elMutex);
127952 return UA_STATUSCODE_BADINTERNALERROR;
127953 }
127954 char ifname[128];
127955 memcpy(dest: ifname, src: interface->data, n: interface->length);
127956 ifname[interface->length] = 0;
127957 int ifindex = (int)if_nametoindex(ifname: ifname);
127958 if(ifindex == 0) {
127959 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
127960 msg: "ETH\t| Could not find the interface %s", ifname);
127961 UA_UNLOCK(&el->elMutex);
127962 return UA_STATUSCODE_BADINTERNALERROR;
127963 }
127964
127965 /* Create the socket and add the basic configuration */
127966 ETH_FD *conn = NULL;
127967 UA_FD sockfd;
127968 if(listen && *listen)
127969 sockfd = socket(PF_PACKET, SOCK_RAW, protocol: htons(hostshort: etherType));
127970 else
127971 sockfd = socket(PF_PACKET, SOCK_RAW, protocol: 0); /* Don't receive */
127972 if(sockfd == -1) {
127973 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
127974 msg: "ETH\t| Could not create a raw Ethernet socket (are you root?)");
127975 UA_UNLOCK(&el->elMutex);
127976 return UA_STATUSCODE_BADINTERNALERROR;
127977 }
127978
127979 /* SO_REUSEADDR is unnecessary (and unsupported on some Linux systems):
127980 * res |= UA_EventLoopPOSIX_setReusable(sockfd); */
127981 res |= UA_EventLoopPOSIX_setNonBlocking(sockfd);
127982 res |= UA_EventLoopPOSIX_setNoSigPipe(sockfd);
127983 if(res != UA_STATUSCODE_GOOD)
127984 goto cleanup;
127985
127986 /* Create the FD object */
127987 conn = (ETH_FD*)UA_calloc(nmemb: 1, size: sizeof(ETH_FD));
127988 if(!conn) {
127989 res = UA_STATUSCODE_BADOUTOFMEMORY;
127990 goto cleanup;
127991 }
127992
127993 conn->rfd.fd = sockfd;
127994 conn->rfd.es = &pcm->cm.eventSource;
127995 conn->rfd.eventSourceCB = (UA_FDCallback)ETH_connectionSocketCallback;
127996 conn->context = context;
127997 conn->application = application;
127998 conn->applicationCB = connectionCallback;
127999
128000 /* Configure a listen or a send connection */
128001 if(!listen || !*listen) {
128002 /* Get the source address for the interface */
128003 struct ifreq ifr;
128004 memcpy(dest: ifr.ifr_name, src: ifname, n: interface->length);
128005 ifr.ifr_name[interface->length] = 0;
128006 int result = ioctl(fd: conn->rfd.fd, SIOCGIFHWADDR, &ifr);
128007 if(result == -1) {
128008 UA_LOG_SOCKET_ERRNO_WRAP(
128009 UA_LOG_ERROR(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
128010 "ETH %u\t| Cannot get the source address, %s",
128011 (unsigned)conn->rfd.fd, errno_str));
128012 res = UA_STATUSCODE_BADCONNECTIONREJECTED;
128013 goto cleanup;
128014 }
128015 res = ETH_openSendConnection(el, conn, params,
128016 source: (unsigned char*)ifr.ifr_hwaddr.sa_data,
128017 ifindex, etherType);
128018 } else {
128019 res = ETH_openListenConnection(el, conn, params, ifindex, etherType, validate);
128020 }
128021
128022 /* Don't actually open or shut down */
128023 if(validate || res != UA_STATUSCODE_GOOD)
128024 goto cleanup;
128025
128026 /* Register in the EventLoop */
128027 res = UA_EventLoopPOSIX_registerFD(el, rfd: &conn->rfd);
128028 if(res != UA_STATUSCODE_GOOD)
128029 goto cleanup;
128030
128031 /* Register locally */
128032 ZIP_INSERT(UA_FDTree, &pcm->fds, &conn->rfd);
128033 pcm->fdsSize++;
128034
128035 /* Register the listen socket in the application */
128036 connectionCallback(cm, (uintptr_t)sockfd, application, &conn->context,
128037 UA_CONNECTIONSTATE_ESTABLISHED, &UA_KEYVALUEMAP_NULL,
128038 UA_BYTESTRING_NULL);
128039 UA_UNLOCK(&el->elMutex);
128040 return UA_STATUSCODE_GOOD;
128041
128042 cleanup:
128043 UA_close(fd: sockfd);
128044 UA_free(ptr: conn);
128045 UA_UNLOCK(&el->elMutex);
128046 return res;
128047}
128048
128049static void
128050ETH_shutdown(UA_POSIXConnectionManager *pcm, ETH_FD *conn) {
128051 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop;
128052 UA_LOCK_ASSERT(&((UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop)->elMutex, 1);
128053
128054 UA_DelayedCallback *dc = &conn->rfd.dc;
128055 if(dc->callback) {
128056 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
128057 msg: "ETH %u\t| Cannot close - already closing",
128058 (unsigned)conn->rfd.fd);
128059 return;
128060 }
128061
128062 /* Shutdown the socket to cancel the current select/epoll */
128063 shutdown(fd: conn->rfd.fd, UA_SHUT_RDWR);
128064
128065 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
128066 msg: "ETH %u\t| Shutdown called", (unsigned)conn->rfd.fd);
128067
128068 dc->callback = ETH_delayedClose;
128069 dc->application = pcm;
128070 dc->context = conn;
128071
128072 /* Don't use the "public" el->addDelayedCallback. It takes a lock. */
128073 dc->next = el->delayedCallbacks;
128074 el->delayedCallbacks = dc;
128075}
128076
128077static UA_StatusCode
128078ETH_shutdownConnection(UA_ConnectionManager *cm, uintptr_t connectionId) {
128079 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
128080 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
128081 UA_LOCK(&el->elMutex);
128082
128083 /* Get the ETH_FD */
128084 UA_FD fd = (UA_FD)connectionId;
128085 UA_RegisteredFD *rfd = ZIP_FIND(UA_FDTree, &pcm->fds, &fd);
128086 if(!rfd) {
128087 UA_LOG_WARNING(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
128088 msg: "ETH\t| Cannot close Ethernet connection %u - not found",
128089 (unsigned)connectionId);
128090 UA_UNLOCK(&el->elMutex);
128091 return UA_STATUSCODE_BADNOTFOUND;
128092 }
128093
128094 ETH_shutdown(pcm, conn: (ETH_FD*)rfd);
128095 UA_UNLOCK(&el->elMutex);
128096 return UA_STATUSCODE_GOOD;
128097}
128098
128099static UA_StatusCode
128100ETH_sendWithConnection(UA_ConnectionManager *cm, uintptr_t connectionId,
128101 const UA_KeyValueMap *params, UA_ByteString *buf) {
128102 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
128103 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
128104
128105 UA_LOCK(&el->elMutex);
128106
128107 /* Get the ETH_FD */
128108 UA_FD fd = (UA_FD)connectionId;
128109 ETH_FD *conn = (ETH_FD*)ZIP_FIND(UA_FDTree, &pcm->fds, &fd);
128110 if(!conn) {
128111 UA_UNLOCK(&el->elMutex);
128112 return UA_STATUSCODE_BADCONNECTIONREJECTED;
128113 }
128114
128115 /* Uncover and set the Ethernet header */
128116 buf->data -= conn->headerSize;
128117 buf->length += conn->headerSize;
128118 memcpy(dest: buf->data, src: conn->header, n: conn->headerSize);
128119 if(conn->lengthOffset) {
128120 UA_UInt16 *ethLength = (UA_UInt16*)&buf->data[conn->lengthOffset];
128121 *ethLength = htons(hostshort: (UA_UInt16)(buf->length - conn->headerSize));
128122 }
128123
128124 /* Prevent OS signals when sending to a closed socket */
128125 int flags = MSG_NOSIGNAL;
128126
128127 struct pollfd tmp_poll_fd;
128128 tmp_poll_fd.fd = (UA_FD)connectionId;
128129 tmp_poll_fd.events = UA_POLLOUT;
128130
128131 /* Send the full buffer. This may require several calls to send */
128132 size_t nWritten = 0;
128133 do {
128134 ssize_t n = 0;
128135 do {
128136 UA_LOG_DEBUG(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
128137 msg: "ETH %u\t| Attempting to send", (unsigned)connectionId);
128138 size_t bytes_to_send = buf->length - nWritten;
128139 n = UA_sendto(fd: conn->rfd.fd, buf: (const char*)buf->data + nWritten, n: bytes_to_send,
128140 flags: flags, addr: (struct sockaddr*)&conn->sll, addr_len: sizeof(conn->sll));
128141 if(n < 0) {
128142 /* An error we cannot recover from? */
128143 if(UA_ERRNO != UA_INTERRUPTED &&
128144 UA_ERRNO != UA_WOULDBLOCK &&
128145 UA_ERRNO != UA_AGAIN) {
128146 UA_LOG_SOCKET_ERRNO_WRAP(
128147 UA_LOG_ERROR(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
128148 "ETH %u\t| Send failed with error %s",
128149 (unsigned)connectionId, errno_str));
128150 ETH_shutdown(pcm, conn);
128151 UA_UNLOCK(&el->elMutex);
128152 UA_ByteString_clear(p: buf);
128153 return UA_STATUSCODE_BADCONNECTIONCLOSED;
128154 }
128155
128156 /* Poll for the socket resources to become available and retry
128157 * (blocking) */
128158 int poll_ret;
128159 do {
128160 poll_ret = UA_poll(fds: &tmp_poll_fd, nfds: 1, timeout: 100);
128161 if(poll_ret < 0 && UA_ERRNO != UA_INTERRUPTED) {
128162 UA_LOG_SOCKET_ERRNO_WRAP(
128163 UA_LOG_ERROR(el->eventLoop.logger, UA_LOGCATEGORY_NETWORK,
128164 "ETH %u\t| Send failed with error %s",
128165 (unsigned)connectionId, errno_str));
128166 ETH_shutdown(pcm, conn);
128167 UA_UNLOCK(&el->elMutex);
128168 UA_ByteString_clear(p: buf);
128169 return UA_STATUSCODE_BADCONNECTIONCLOSED;
128170 }
128171 } while(poll_ret <= 0);
128172 }
128173 } while(n < 0);
128174 nWritten += (size_t)n;
128175 } while(nWritten < buf->length);
128176
128177 /* Free the buffer */
128178 UA_UNLOCK(&el->elMutex);
128179 UA_ByteString_clear(p: buf);
128180 return UA_STATUSCODE_GOOD;
128181}
128182
128183static UA_StatusCode
128184ETH_eventSourceStart(UA_ConnectionManager *cm) {
128185 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)cm->eventSource.eventLoop;
128186 UA_LOCK(&el->elMutex);
128187
128188 /* Check the state */
128189 if(cm->eventSource.state != UA_EVENTSOURCESTATE_STOPPED) {
128190 UA_LOG_ERROR(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
128191 msg: "To start the Ethernet ConnectionManager, "
128192 "it has to be registered in an EventLoop and not started");
128193 UA_UNLOCK(&el->elMutex);
128194 return UA_STATUSCODE_BADINTERNALERROR;
128195 }
128196
128197 /* Set the EventSource to the started state */
128198 cm->eventSource.state = UA_EVENTSOURCESTATE_STARTED;
128199
128200 UA_UNLOCK(&el->elMutex);
128201 return UA_STATUSCODE_GOOD;
128202}
128203
128204static void *
128205ETH_shutdownCB(void *application, UA_RegisteredFD *rfd) {
128206 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)application;
128207 ETH_shutdown(pcm, conn: (ETH_FD*)rfd);
128208 return NULL;
128209}
128210
128211static void
128212ETH_eventSourceStop(UA_ConnectionManager *cm) {
128213 UA_POSIXConnectionManager *pcm = (UA_POSIXConnectionManager*)cm;
128214 UA_EventLoopPOSIX *el = (UA_EventLoopPOSIX*)pcm->cm.eventSource.eventLoop;
128215 UA_LOCK(&el->elMutex);
128216
128217 UA_LOG_INFO(logger: el->eventLoop.logger, category: UA_LOGCATEGORY_NETWORK,
128218 msg: "ETH\t| Shutting down the ConnectionManager");
128219
128220 /* Prevent new connections to open */
128221 cm->eventSource.state = UA_EVENTSOURCESTATE_STOPPING;
128222
128223 /* Shutdown all existing connection */
128224 ZIP_ITER(UA_FDTree, &pcm->fds, ETH_shutdownCB, cm);
128225
128226 /* Check if stopped once more (also checking inside ETH_close, but there we
128227 * don't check if there is no rfd at all) */
128228 ETH_checkStopped(pcm);
128229
128230 UA_UNLOCK(&el->elMutex);
128231}
128232
128233static UA_StatusCode
128234ETH_eventSourceDelete(UA_ConnectionManager *cm) {
128235 if(cm->eventSource.state >= UA_EVENTSOURCESTATE_STARTING) {
128236 UA_LOG_ERROR(logger: cm->eventSource.eventLoop->logger, category: UA_LOGCATEGORY_EVENTLOOP,
128237 msg: "ETH\t| The EventSource must be stopped before it can be deleted");
128238 return UA_STATUSCODE_BADINTERNALERROR;
128239 }
128240
128241 /* Delete the parameters */
128242 UA_KeyValueMap_clear(map: &cm->eventSource.params);
128243 UA_String_clear(p: &cm->eventSource.name);
128244 UA_free(ptr: cm);
128245 return UA_STATUSCODE_GOOD;
128246}
128247
128248static const char *ethName = "eth";
128249
128250UA_ConnectionManager *
128251UA_ConnectionManager_new_POSIX_Ethernet(const UA_String eventSourceName) {
128252 UA_POSIXConnectionManager *cm = (UA_POSIXConnectionManager*)
128253 UA_calloc(nmemb: 1, size: sizeof(UA_POSIXConnectionManager));
128254 if(!cm)
128255 return NULL;
128256
128257 cm->cm.eventSource.eventSourceType = UA_EVENTSOURCETYPE_CONNECTIONMANAGER;
128258 UA_String_copy(src: &eventSourceName, dst: &cm->cm.eventSource.name);
128259 cm->cm.eventSource.start = (UA_StatusCode (*)(UA_EventSource *))ETH_eventSourceStart;
128260 cm->cm.eventSource.stop = (void (*)(UA_EventSource *))ETH_eventSourceStop;
128261 cm->cm.eventSource.free = (UA_StatusCode (*)(UA_EventSource *))ETH_eventSourceDelete;
128262 cm->cm.protocol = UA_STRING(chars: (char*)(uintptr_t)ethName);
128263 cm->cm.openConnection = ETH_openConnection;
128264 cm->cm.allocNetworkBuffer = ETH_allocNetworkBuffer;
128265 cm->cm.freeNetworkBuffer = ETH_freeNetworkBuffer;
128266 cm->cm.sendWithConnection = ETH_sendWithConnection;
128267 cm->cm.closeConnection = ETH_shutdownConnection;
128268 return &cm->cm;
128269}
128270
128271#endif /* defined(UA_ARCHITECTURE_POSIX) && defined(__linux__) */
128272
128273

source code of qtopcua/src/3rdparty/open62541/open62541.c